阅读更多

0顶
0踩

Web前端

原创新闻 如何用Go语言每分钟处理100万个请求

2017-09-13 16:37 by 副主编 jihong10102006 评论(0) 有11435人浏览
go
引用
原文:Handling 1 Million Requests per Minute with Golang
作者:Marcio Castilho
翻译:无阻我飞扬

摘要:作者结合自身工作经历,以一个项目为案例,通过多个Go语言程序实例的尝试,阐述了Go语言是如何每分钟可以处理100万个请求的,以下是译文。

我在几个不同的公司从事反垃圾邮件,反病毒和反恶意软件工作超过15年,现在我知道这些系统的复杂性可能是由于我们每天处理的大量数据造成的。

目前,我是smsjunk.com的CEO和KnowBe4的首席架构师,两个活跃在网络安全行业的公司。

有趣的是,在过去10年左右的时间里,作为一名软件工程师,我所参与的所有web后端开发大部分都是以Ruby on Rails(Rails是使用Ruby语言编写的网页程序开发框架,目的是为开发者提供常用组件)开发的。不要误会我,我热爱Ruby on Rails,我相信它是一个令人着迷的开发环境,但一段时间后,你开始以Ruby的方式思考和设计系统,忘了如何高效和原本可以利用多线程、并行、快速执行和小的内存消耗来简化软件架构。多年来,我是一个C / C++、Delphi和C #开发人员,我刚刚意识到,用合适的工具来完成工作可能会降低事情的复杂度。

我不太热衷于开发语言和框架的战争,网站之间总是为此争吵。我相信效率、生产率和代码的可维护性主要取决于如何简单地构建解决方案。

问题

当我们在一个匿名的遥测和分析系统上工作时,我们的目标是能够处理来自数百万终端的大量的POST请求。Web处理程序将接收一个JSON文档,其中可能包含需要写入Amazon S3的许多有效负载的集合,这是为了使map-reduce系统稍后操作这个数据。

传统上,我们将研究创造一个一阶作业者架构,利用诸如:
  • Sidekiq
  • Resque
  • DelayedJob
  • Elasticbeanstalk Worker Tier
  • RabbitMQ
  • 等等…
设置2个不同的集群,一个用于web前端,另一个用于作业者,这样会扩大可以处理的后台工作的数量。

但从一开始,我们的团队就知道应该这样做,因为在讨论阶段,我们预见这可能是一个非常大的流量系统。我使用Go语言大约2年左右的时间,我们开发了一些在用的系统,但是没有一个系统能得到这么多的负载。

首先通过创建一些structure,定义通过POST调用来接收到的web请求负载,还有一个上传请求负载到S3 bucket的函数。

Go语言程序的单纯方法

最初我们采取了一个非常单纯的POST处理方式,仅仅试图将任务并行化处理放到一个简单的goroutine:

对于中等负载来说,这可能对大多数人是有效的,但这很快证明在大型负载时,效果不太好。我们预期有很多的请求,但当我们部署第一个版本到产品中时,并没有看到这个数量级的请求。我们完全低估了流量。

上面的方法在几个方面都不好,没有办法控制我们正在大量生产的Go程序要产生多少个例程。由于我们每分钟收到100万个POST请求,理所当然的,这段代码很快就崩溃了。

再次尝试

我们需要寻找一个不同的方式。从一开始,我们就讨论如何保持请求处理程序的生命周期非常短,并在后台生成处理进程。当然,这是必须在Ruby on Rails领域要做的,否则这将限制所有可用的web处理器,无论你使用的是puma, unicorn, passenger中的哪一个(请不要参加JRuby讨论)。那么我们就需要利用通用的解决方案去做这个,例如Resque, Sidekiq, SQS,等等。清单还可以继续列下去,因为有很多方法可以做到这一点。

所以第二个版本是创建一个缓存通道,在这里我们可以对一些作业进行排队并上传到S3,由于我们可以控制队列中的最大项目数,在内存中我们有足够多的RAM对任务进行排队,我们认为只在通道队列中缓存作业是可以的。

然后实际上的作业出列和处理,我们使用的是类似的函数:

说实话,我不知道我们在想什么。这一定是一个充满红牛的深夜。这种方法没有给我们带来任何好处,我们用缓冲队列来交换有缺陷的并发,也只是推迟了问题的产生时间而已。我们的同步处理器一次只上传一个有效负载到S3,而且由于传入请求的速率比单处理器上传到S3的能力大得多,所以缓冲通道很快就达到了极限,限制了请求处理程序来排队更多项目的能力。

我们只是简单地回避这个问题,最终导致系统的死亡。在我们部署了这个有缺陷的版本之后,我们的延迟率以不变的速率持续增长。

更好的解决方案

当使用Go语言通道时,我们决定利用通用模式以便创造一个2阶的通道系统,一个用于作业排队,另外一个控制多少作业者同时在JobQueue上操作。

这个想法是以某种可持续的速度并行上传到S3,它既不会削弱机器性能,也不会从S3开始生成连接错误。所以我们选择了创建一个作业/作业者模式。对那些熟悉java,C#等语言的人来说,可以考虑采用Go语言实现通道方式而不是作业者线程池的方式。



我们修改了Web请求处理程序,创建一个带负载的jobstruct实例,发送到JobQueue通道,便于作业者去拾取。

在网站服务器初始化过程中,我们创建一个Dispatcher,调用Run()去创建一个作业者池,开始侦听出现在JobQueue的作业。
dispatcher := NewDispatcher(MaxWorker)
dispatcher.Run()

下面是用于dispatcher执行的代码:


注意,我们会提供被实例化和被添加到作业者池的最大的作业者量。 因为我们这个带有dockerized Go环境的项目使用了亚马逊Elasticbeanstalk,我们总是设法遵循12要素方法论来配置生产中的系统,从环境变量中读取这些数值。这样就可以控制有多少作业者和作业队列的最大值,因此,我们可以快速地调整这些值,而不需要重新部署集群。

var (

MaxWorker = os.Getenv(“MAX_WORKERS”)

MaxQueue = os.Getenv(“MAX_QUEUE”)

)

在部署完它之后,我们立刻发现所有的延迟率都降到了无关紧要的数字,系统处理请求的能力急剧上升。

弹性负载均衡完全预热几分钟后,我们看到ElasticBeanstalk应用服务每分钟逼近100万个请求。通常在早晨的几个小时里,流量高峰会超过每分钟100万个请求。

一旦我们部署了新的代码,服务器的数量从100台减少到大约20台。

在恰当地配置了集群和自动缩放设置以后,我们能够把它降低到仅有4x EC2 c4。如果CPU连续5分钟超过90%,大型实例和弹性自动缩放设置就生成一个新实例。

结论

简单总是在我的字典里获胜。我们可以设计一个复杂系统,它具有多队列,后台作业者,复杂部署的特点。但是相反我们决定利用Elasticbeanstalk的自动缩放和高效简单的方式去并发,Go语言很好的提供了这些功能。

并不是每天你仅有四台机器的集群,去处理每分钟写入到亚马逊S3 bucket的100万个POST请求,这可能比我最新的MacBook Pro功能强大的多。

总有合适的工具适合这项工作。有时,当您的Ruby on Rails系统需要一个非常强大的web处理程序时,可以稍微考虑一下Ruby生态系统之外的更简单、更强大的替代解决方案。
  • 大小: 43 KB
  • 大小: 32.3 KB
  • 大小: 17.9 KB
  • 大小: 10.5 KB
  • 大小: 126.1 KB
  • 大小: 18.8 KB
  • 大小: 25.3 KB
  • 大小: 14.6 KB
  • 大小: 32.9 KB
  • 大小: 20.8 KB
  • 大小: 19.5 KB
  • 大小: 106.8 KB
  • 大小: 54.7 KB
  • 大小: 136 KB
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 如何用Go语言每分钟处理100万个请求.pdf

    如何用Go语言每分钟处理100万个请求.pdf

  • 如何用Golang处理每分钟100万个请求

    如何用Golang处理每分钟100万个请求

  • 使用Go每分钟处理百万个请求

    前两天马斯克,Bengio等千位AI科技人士签署暂停巨型 AI 实验公开信,在这封信里马斯克等人呼吁所有人工智能实验室立即暂停训练比 GPT-4 更强大的人工智能系统(包括目前正在训练的 GPT-5)至少 6 个月,同时利用这段...

  • 如何用GO处理高峰期每分钟100万条数据请求

    最近看了一篇文章,用go处理每分钟达百万条的数据请求 原文地址:http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/ 翻译地址:https://www.jianshu.com/p/21de03ac682c 这里作者...

  • 使用Go语言每分钟处理1百万请求

    在Go中要实现高并发,可以使用 go routine 每个请求 都开启 一个 go routine 去处理,但这样的方式 当 流量大了 就不太可行了,另一种方法 是开启 一个 channel 缓存请求队列 然后 再 for select 循环去 取 任务 ,但是...

  • 用Golang处理每分钟100万份请求

    我在几家不同的公司从事反垃圾邮件,防病毒和反恶意软件行业工作超过15年,现在我知道这些系统最终会因为我们每天处理的大量数据而变得复杂。目前,我是smsjunk.com的CEO和KnowBe4的首席架构师,他们都是网络安全...

  • post json后台处理数据_【翻译】使用 Golang 处理每分钟 100 万次的请求

    使用 Golang 处理每分钟 100 万次的请求Marcio Castilho2017 年 8 月 31 日・大概 7 分钟阅读时间我在反垃圾邮件、反病毒和反恶意软件行业工作了 15 年,由于我们每天处理的数据量巨大,这些系统最终可能会变得非常...

  • 我们如何用Go来处理每分钟100万复杂请求的场景

    在Malwarebytes 我们经历了显著的增长,自从我一年前加入了硅谷的公司,一个主要的职责成了设计架构和开发一些系统来支持一个快速增长的信息安全公司和所有需要的设施来支持一个每天百万用户使用的产品。...

  • [译]使用golang每分钟处理百万请求

    [译]使用golang每分钟处理百万请求 在Malwarebytes,我们正在经历惊人的增长,自从我在1年前加入硅谷的这家公司以来,我的主要职责是为多个系统做架构和开发,为这家安全公司的快速发展以及百万日活产品所必需的基础...

  • 使用golang每分钟处理百万请求

    问题 从原生方法到Go协程 再试一次 更好的解决方案 实时结果 结论 正文 [译]使用golang每分钟处理百万请求 在Malwarebytes,我们正在经历惊人的增长,自从我在1年前加入硅谷的这家公司以来,我...

  • 不同语言运行 100 万个并发任务需要多少内存?

    在前几天的《Python潮流周刊#5:并发一百万个任务要用多少内存?》中,我分享了一篇同题文章,在发布后,我才发现有人已翻译了它,特此分享这篇译文。值得注意的是,译者在文末还翻译了几则评论内容,以及指出了原文...

  • python如何并发上千个get_Python每秒处理一百万个并发请求?当真有这么猛吗?

    https://github.com/squeakypl/japronto/pull/12 和 ...虽然其包含了固有的阻塞设计,但是它的速度依旧远超前四个框架,这四个框架都是 Python 异步解决方案。所以,不要相信所谓的异...

  • 基于Matlab/Simulink的风电调频与风储联合频域模型仿真及应用

    内容概要:本文介绍了利用Matlab/Simulink进行风电调频与风储联合仿真的方法。针对传统时域仿真耗时的问题,提出了一种基于频域模型的方法,实现了快速高效的仿真。文中详细描述了虚拟惯性控制和储能下垂控制的具体实现方式及其对系统频率稳定性的影响。通过频域模型,将复杂的微分方程转化为简单的矩阵运算,显著提高了仿真速度。同时,加入了SOC(荷电状态)管理和滑动平均滤波,确保了储能系统的安全可靠运行。实验结果显示,在相同的硬件条件下,频域模型的仿真速度比传统时域模型快了近十倍,且频率偏差明显减小。 适合人群:从事电力系统仿真、风电调频研究的专业人士和技术爱好者。 使用场景及目标:适用于需要快速验证风电调频控制策略的研究人员和工程师。主要目标是在保证仿真精度的同时大幅提高仿真速度,为风电并网提供技术支持。 其他说明:本文提供的模型专注于调频性能分析,不涉及风机内部动态细节。对于更详细的风机模型,作者提供了进一步的参考资料。

  • 含碳交易与绿证的智能楼宇微网优化调度模型及其MATLAB实现

    内容概要:本文介绍了一种针对电热综合能源系统的优化调度模型,该模型在传统微网(风、光、储、火)的基础上加入了电动汽车(EVs)和智能楼宇单元,并引入了碳排放和绿色证书交易机制。模型通过MATLAB和YALMIP工具进行求解,主要关注于优化能源分配方案,降低整体成本并控制碳排放。文中详细讨论了模型的目标函数设计、约束条件设定、电动汽车充放电策略、智能楼宇温控负荷预测、绿证交易价格机制等方面的内容。实验结果显示,在考虑碳交易和绿证交易的情况下,系统的灵活性和经济性均有所提高。 适合人群:从事电力系统优化、智能楼宇设计、电动汽车调度等领域研究的专业人士和技术爱好者。 使用场景及目标:适用于希望深入了解电热综合能源系统优化调度方法的研究人员,尤其是那些对碳市场和绿证交易感兴趣的从业者。目标是提供一种能够有效整合多种能源形式并兼顾环境效益的解决方案。 其他说明:文中提供的代码片段展示了具体的实现细节,对于想要进一步探索相关领域的读者具有很高的参考价值。此外,作者还分享了一些调参经验和遇到的问题解决办法,有助于初学者更好地理解和应用这一复杂的优化模型。

  • texlive-cweb-7:20180414-12.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统texlive-cweb-7:20180414-12.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf texlive-cweb-7:20180414-12.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

  • Matlab中地表水源热泵系统建模与粒子群算法优化制冷制热量

    内容概要:本文详细介绍了如何使用Matlab对地表水源热泵系统进行建模,并采用粒子群算法来优化每小时的制冷量和制热量。首先,文章解释了地表水源热泵的工作原理及其重要性,随后展示了如何设定基本参数并构建热泵机组的基础模型。接着,文章深入探讨了粒子群算法的具体实现步骤,包括参数设置、粒子初始化、适应度评估以及粒子位置和速度的更新规则。为了确保优化的有效性和实用性,文中还讨论了如何处理实际应用中的约束条件,如设备的最大能力和制冷/制热模式之间的互斥关系。此外,作者分享了一些实用技巧,例如引入混合优化方法以加快收敛速度,以及在目标函数中加入额外的惩罚项来减少不必要的模式切换。最终,通过对优化结果的可视化分析,验证了所提出的方法能够显著降低能耗并提高系统的运行效率。 适用人群:从事暖通空调系统设计、优化及相关领域的工程师和技术人员,尤其是那些希望深入了解地表水源热泵系统特性和优化方法的专业人士。 使用场景及目标:适用于需要对地表水源热泵系统进行精确建模和优化的情景,旨在找到既满足建筑负荷需求又能使机组运行在最高效率点的制冷/制热量组合。主要目标是在保证室内舒适度的前提下,最大限度地节约能源并延长设备使用寿命。 其他说明:文中提供的Matlab代码片段可以帮助读者更好地理解和复现整个建模和优化过程。同时,作者强调了在实际工程项目中灵活调整相关参数的重要性,以便获得更好的优化效果。

  • 流体力学中EMD经验模态分解的MATLAB实现与应用技巧

    内容概要:本文详细介绍了经验模态分解(EMD)在流体力学领域的应用,特别是通过MATLAB进行流场数据分析的方法。首先,文章解释了EMD的基本概念及其在处理非平稳信号方面的优势,如湍流和涡旋数据。接着,提供了具体的MATLAB代码示例,展示了如何将原始流场数据分解为多个本征模态函数(IMF),并通过可视化手段展示分解结果。此外,文中还讨论了一些常见的EMD应用技巧,如边界效应处理、筛分停止准则设置以及针对特定应用场景(如二维速度场、三维加速度信号)的优化方法。最后,强调了EMD在流场信号解剖中的重要性和实用性,并分享了多个实战案例,包括圆柱绕流、翼型失速、船舶波浪载荷等。 适合人群:从事流体力学研究的专业人士,尤其是需要处理非平稳流场数据的研究人员和技术人员。 使用场景及目标:适用于需要对复杂流场数据进行精细分析的情景,如风洞实验、CFD模拟结果后处理等。主要目标是帮助用户更好地理解和解析流场中的多尺度动态行为,提高数据分析的准确性和效率。 其他说明:文章不仅提供了详细的理论讲解,还包括丰富的代码示例和实用技巧,有助于读者快速掌握EMD的应用方法。同时,附带的实例数据和视频教程进一步增强了学习效果。

  • 滑模变结构控制MATLAB仿真:理论解析与实践应用

    内容概要:本文详细介绍了滑模变结构控制的基本理论及其在MATLAB环境下的仿真实现。首先解释了滑模变结构控制的概念,即系统结构随状态变化而切换,以达到理想的动态性能。文中通过具体的二阶系统实例展示了如何构建状态空间模型、设计滑模面和控制律,并利用MATLAB进行了详细的仿真验证。此外,还探讨了滑模控制中的关键问题,如抖振现象的处理、参数选择的原则以及面对不确定性和扰动时的鲁棒性表现。 适合人群:自动化专业学生、控制系统工程师、从事控制理论研究的研究人员。 使用场景及目标:适用于需要深入了解滑模变结构控制原理并在实践中加以应用的人群。具体应用场景包括但不限于机器人控制、航空航天、工业自动化等领域,旨在提高系统的稳定性和抗干扰能力。 其他说明:文章提供了丰富的MATLAB代码片段,帮助读者更好地理解和掌握滑模变结构控制的实际操作步骤。同时强调了在实际应用中需要注意的技术细节,如计算步长的选择、参数优化等。

  • 基于Zynq的高效以太网传输框架:FPGA数据DMA传输与千兆网通信解决方案

    内容概要:本文详细介绍了基于Zynq平台的以太网传输框架,涵盖从FPGA数据采集、DMA传输到DDR存储,再到通过千兆网传输给电脑的全过程。框架通过高效的DMA技术和合理的软硬件协同设计,实现了快速、可靠的数据传输。文中不仅提供了具体的VHDL、Verilog和C代码示例,还分享了实际应用中的经验教训和技术细节,如内存对齐、中断处理和网络带宽控制等。 适合人群:适用于嵌入式系统开发人员、FPGA工程师、模拟半导体芯片测试工程师以及相关专业的师生。 使用场景及目标:主要用于需要高效数据传输的应用场景,如模拟数字转换器(ADC)、数字模拟转换器(DAC)的数据采集与传输,摄像头数据回传,声呐采集等。目标是提高开发效率,减少开发周期,使开发者能够集中精力在特定功能的实现上。 其他说明:文章强调了框架的实际应用效果,如降低内存拷贝耗时、提高网络吞吐量、减少CPU占用率等,并提供了一些实用的调试和优化技巧。配套的工程文件和详细的文档支持进一步增强了其实用性和易用性。

Global site tag (gtag.js) - Google Analytics