云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

美国服务器_网站建设好处_超低折扣

小七 141 0

Dogfooding Cloudflare工人

在WWW团队中,我们负责Cloudflare的REST API、帐户管理服务和仪表板体验。我们认真对待安全性和PCI合规性,这意味着我们将迅速跟上法规和相关法律。最近的一个法规遵从性项目要求在边缘检测某些最终用户请求数据,并在API响应中以及在仪表板中对其作出响应。我们意识到这对狗粮Cloudflare的工人来说是一个极好的机会。将工人部署到网站以及api.cloudflare.com网站在这篇博文中,我们将对我们使用一个worker解决的问题进行分解,并共享我们的worker的带注释的源代码,并分享我们在这个过程中发现的一些最佳实践、技巧和技巧。自从部署以来,我们的工作人员已经为超过4亿个请求提供了api.cloudflare.com网站以及网站仪表板。任务首先,我们需要检测客户端何时使用过时的TLS协议连接到我们的服务。接下来,我们希望将这些信息传递到我们的应用程序堆栈中更深层次,这样我们就可以对它采取行动,并有条件地用通知来装饰我们的响应,提供有关即将发生的更改的提示。我们的Edge团队很快就创建了一个补丁来为每个传入的请求捕获TLS连接信息,但是我们如何将它传播到应用层,以便对其进行操作呢?解决方案Workers团队对核心平台进行了修改,以接收从边缘发送的TLS协议版本数据,使其作为可用于worker Javascript上下文的cf对象的属性在Workers环境中可用(现在可以在自己的worker中使用此属性)。由于我们的工作人员能够检查请求的TLS协议版本,我们只需要在将这些信息转发到应用程序层之前附加一个包含此信息的定制HTTP报头。我们的api使用这些数据向响应添加弃用警告,UI使用它显示解释即将发生的更改的横幅。现在让我们看一下工人的源代码。一个失败开放工人的解剖/***Cloudflare workers实现服务工人规范*参见:https://developers.cloudflare.com/workers/about/介绍一下**将事件处理程序绑定到fetch事件允许您的辅助进程拦截对您的区域的请求*/addEventListener('fetch',事件=>{/***如果发生未捕获的异常,则将fail open视为worker不存在*如果您不确定自己在做什么,建议您包括此呼叫*作为您的工人在其获取事件侦听器中所做的第一件事**如果不包括此调用,但工作线程遇到未捕获的异常*在处理您的请求时,您的用户将看到一个边缘级错误页*而不是从你的网站,应用程序或API的响应**请继续阅读下面的内容,以了解决定是否*在你的工人中失败打开或关闭*/event.passThroughOnException事件()//这允许您从工作线程返回自己的响应对象事件响应(requestWithTLSHeader(事件))})/***调用我们的哨兵帐户以创建异常事件**请注意,要使其与事件.等待直到()呼叫*异常块在requestWithTLSHeader中,此函数必须返回一个promise**@returns{Promise}*/函数promisifiedSentryLog(ex){//如果要使用此脚本,请将这些常量更改为您自己的哨兵值const sentryProjectId=''const sentryAPIKey=''const sentrySecretKey=''//手动配置呼叫哨兵设b={项目:sentryProjectId,logger:"javascript",平台:"javascript",例外情况:{价值观:[{类型:"错误",值:((ex)&&(ex.message公司)) ? ex.message公司:"未知"}]}}让sentryUrl=`https://sentry.io/api/${sentryProjectId}/store/?sentry_version=7&sentry_client=raven js%2F3.24.2&sentry_key=${sentryAPIKey}&sentry_secret=${sentrySecretKey}`/***向Sentry的API发出POST请求,其中包括我们的项目*和凭据信息,以及任意日志记录数据**在这种情况下,我们传递异常消息,*但是你可以用这个模式来记录任何你想要的东西**记住,fetch会返回一个承诺,*这就是这个函数兼容的原因事件.等待直到*/return fetch(sentryUrl,{body:JSON.stringify(b) ,方法:"POST"})}/***为后端创建一个新请求,以镜像传入的请求,*添加了一个新的头,指定使用了哪个TLS版本*在与边缘的连接处**这是包含此worker的核心逻辑的主函数**它通过检查是否存在正在转发的属性"tlsVersion"来工作*从边缘进入workers平台,以便worker脚本可以访问它**worker以默认的TLS头开始。如果tlsVersion属性,*它表示客户端连接的TLS协议的版本,*如果存在,则工作进程将其本地tlsVersion变量设置为此属性的值**然后,它将传入的请求头封装在一个新的headers对象中,*这使我们能够附加我们自己的定制X-Client-SSL-Protocol头**然后,工作人员转发原始请求*(用新的headers对象覆盖headers)到源**现在,我们的应用程序层可以处理这些信息*显示情态动词并根据需要包含弃用警告**@returns{Promise}*/异步函数requestWithTLSHeader(事件){//强烈建议您将核心工作逻辑包装在try/catch块中试试看{让tlsVersion="无"//创建包含原始请求标头的新Headers对象let reqHeaders=新标题(请求.headers)if(事件和事件请求&& event.request.cf&& event.request.cf.tls版本和类型event.request.cf.tlsVersion==="字符串"&event.request.cf.tls版本!== "") {TLS版本=event.request.cf.tls版本}//添加新标题请求标题.append('X-Client-SSL-Protocol',TLS版本)//用我们自己的头扩展原始请求的头,否则获取原始请求返回等待获取(事件请求,{headers:reqHeaders})}接球(ex){/***向运行时发出信号,指示它应该等到promise解决为止**这避免了运行库在之前停止执行的竞争条件*我们的异步哨兵任务完成了**如果不这样做,passthrough子请求将争用*你的等待中的不同步的哨兵请求,你会的*错过许多事件/未能正确捕捉*/事件.等待直到(promisifiedSentryLog(ex))/***故意抛出异常以触发传递*行为定义者event.passThroughOnException事件()**这意味着我们的工人将失败打开-而不是阻止请求*由于意外的异常,我们的后端服务*/抛出前}}上述工人脚本于2018年5月17日更新,以纠正哨兵的API是如何工作的。通过Sentry进行异步、日志记录和警报我们决定使用Sentry来捕获我们从我们的工作人员发送的事件,但是您可以在任何类似的服务中遵循相同的模式。实现这一点的关键是要理解,您必须向Cloudflare worker运行时发出信号,让它等待异步日志记录子请求(而不是取消它)。您可以通过:确保日志记录函数返回一个promise(promise解析为什么并不重要)在中包装对日志函数的调用事件.等待直到正如我们上面所做的此模式修复了一个常见的竞争条件:如果您不利用事件.等待直到,运行时将争用passthrough子请求和日志记录子请求。如果passthrough子请求的完成速度明显快于日志记录子请求,则可以取消日志记录请求。在实践中,您会注意到这个问题表现为被丢弃的日志消息—给定的异常是否被正确地记录将成为每个请求的掷骰子。要了解更多信息,请查看我们的官方指南来调试Cloudflare workers。无法打开以确保服务连续性设计员工时的一个关键考虑因素是失败行为。根据您的特定工作人员正在完成的任务,您要么希望它以失败方式打开,要么失败地关闭。失败的打开意味着如果发生严重错误,原始请求将被传递,就像您的工作线程不存在一样;而失败关闭意味着在您的工作线程中引发异常的请求将不会被进一步处理。如果您正在编辑元数据、收集度量或添加新的非关键HTTP报头(举几个例子),您可能不希望工作线程中出现未处理的异常来阻止请求得到服务。在这种情况下,您可以利用event.passThroughOnException事件如上所述,建议您在fetch事件处理程序的第一行调用此方法。这将设置一个标志,Cloudflare worker请求处理程序可以在发生异常时检查该标志,以确定所需的传递行为。另一方面,如果您以安全为中心的角色雇用您的工作人员,让它阻止来自邪恶机器人程序的恶意请求,或者在未提供有效的安全凭据时阻止对敏感端点的访问,则您可能希望您的工作人员失败关闭。这是默认行为,它将阻止在工作线程中引发异常的请求被进一步处理