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

摘要:作者结合自身工作经历,以一个项目为案例,通过多个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的作业。


  1. dispatcher := NewDispatcher(MaxWorker)  
  2. dispatcher.Run() 

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

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


  1. var (  
  2. MaxWorker = os.Getenv(“MAX_WORKERS”)  
  3. 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生态系统之外的更简单、更强大的替代解决方案。

本文作者:佚名

来源:51CTO

时间: 2025-01-20 04:29:38

如何用Go语言每分钟处理100万个请求的相关文章

我是菜鸟如何用c语言在.txt文本中读出以下数据

问题描述 我是菜鸟如何用c语言在.txt文本中读出以下数据 如何用c语言在.txt文本中读出以下数据 19650114103100 26.00 98.402.50999 0 19650114172400 25.60 100.003.00999 0 19650115162400 26.80 102.802.90999 0 19650116073100 25.40 99.902.40999 0 19650117024700 29.00 103.303.40999 0 19650118024100 2

Erebus以Linux勒索软件的方式重出江湖,勒索韩国公司100万美元

本文讲的是Erebus以Linux勒索软件的方式重出江湖,勒索韩国公司100万美元, 6月10日,韩国网络托管公司NAYANA被Erebus 勒索软件(由趋势科技公司检测为RANSOM_ELFEREBUS.A)攻击,导致旗下 153 台 Linux 服务器与 3400 个商业网站感染 Erebus 勒索软件. 安全专家表示,勒索软件 Erebus 滥用 Event Viewer 提权,允许实现用户账户控制( UAC )绕过,即用户不会收到以较高权限运行程序运行的通知.此外, Erebus 还可将

Badoo 告诉你切换到 PHP7 节省了 100 万美元

介绍 我们成功的把我们的应用迁移到了php7上面(数百台机器的集群),而且运行的很好,据说我们是第二个把如此规模的应用切换到php7的企业,在切 换的过程我们发现了一些php7字节码缓存的bug,庆幸的是这些bug现在已经被修复了,现在我们把这个激动人心的消息分享给所有的php社 区:php7现在已经可以稳定的运行在商用环境上,而且比以前更加节省内存,性能也有的很大的提高. 下面我会详细的介绍下我们是如何把应用前移动php7的,我们在这中间遇到的问题及处理情况,还有最终的结果.但首先让我们回头看

百度DuerOS硅谷公布普罗米修斯计划,100万美金基金吸引AI才俊

美国西部时间11月9日,百度DuerOS在硅谷GSVlabs正式宣布启动普罗米修斯计划.据介绍,普罗米修斯计划包含开放超大规模对话式AI数据集.跨学科合作等多种计划,以及一个100万美元的基金用以鼓励和培养对话式AI领域的优秀项目和人才.百度度秘事业部首席技术官朱凯华.百度主任架构师陈果果.亚马逊机器学习高级主管Björn Hoffmeister博士.约翰•霍普金斯大学人类语言技术中心主任Sanjeev Khudanpur博士等全球对话式AI领域的专家.学者莅临发布会现场. 发布会上,朱凯华表示

工作五年“攒”够100万,程序猿们,我可没开玩笑!8条建议抱走不谢

对于身处北上广深杭等大多数一线城市来说,100万人民币并不算什么太大数字,甚至还不够给房子交首付,但是对于一个刚刚工作几年的程序员来说,拥有100万人民币存款却是一个看似难以实现的目标,然而只要作为程序员合的你们做好合理的规划,这个目标是不难实现的,而且当五年过去之后,你可能发现你不止拥有了这100万存款,还提升了自己的"财商".程序员如何实现工作五年"攒"够100万,本文就给你细细道来. 那么,作为一个程序员,工作五年就能如何才能够攒到100万呢? 其实,资金的积

TeamViewer当“帮凶”,小龙女网银被盗100万技术分析

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 TeamViewer是全球知名的远程控制软件,一般用于在线远程协助.然而在近期曝出的"小龙女"李若彤被骗子盗窃网银资金100万的案例中,总部位于德国的TeamViewer却千里迢迢来到中国充当了骗子的帮凶. 原来,TeamViewer提供了名为"定制版"的服务,骗子把TeamViewer改头换面,将界面

“维c银翘片”服用需谨慎,余额宝用户大涨突破100万

[余额宝用户大涨,人数突破100万]余额宝的第100万位用户终于在昨天晚上(2013年6月18日21时30分10秒)诞生啦,而这距离余额宝服务上线还不到6天的时间.我们非常感谢所有亲们的支持!还是那句老话,余额宝想做的其实很简单,那就是希望让大家享受到用零花钱理财的快乐. [腾讯将要投资美国创意闪购网站 Fab.com,投资额近 1.5 亿美元]创意产品闪购网站--Fab.com已经获得了D轮1.5 亿美元的投资,腾讯和日本 Itochu最新加入到了对 Fab 的投资,而且腾讯将加入 Fab.c

大咖们,请问如何用C语言实现检测到鼠标左键按下时,等效于按下printscreen键

问题描述 大咖们,最近公司要截很多图,按printscreen键按到手软求教如何用c语言实现,按下鼠标左键的时候,同步实现按下printscreen,多谢.我知道以下代码可实现鼠标左键按下的检测,#include<stdio.h>#include<windows.h>#include<conio.h>#include<stdlib.h>intmain(intargc,char*argv[]){SetConsoleTitle("1111111111&

Glamping Hubs宣布获得100万美元A轮融资

摘要: 为旅行者提供预定豪华帐篷的在线平台Glamping Hubs宣布获得100万美元A轮融资,西班牙风投机构Axon Partners领投.Axon的总裁认为,随着旅行日益成为大众消费的热点,人们也在寻找不同的旅 为旅行者提供预定"豪华帐篷"的在线平台Glamping Hubs宣布获得100万美元A轮融资,西班牙风投机构Axon Partners领投.Axon的总裁认为,随着旅行日益成为大众消费的热点,人们也在寻找不同的旅行体验,这也正是Glamping Hubs的市场所在(其实除