概念
web–> SQS --> worker 是EB用来做均衡负载和自动扩容的办法
原理
如果一个操作需要很长时间才会完成,而网页要求500ms之内完成响应,那么单单有主机器来完成这个操作就显得非常困难。
解决这个困难的方法有几种。
- 一种是可以使用异步处理机制,让其他计算机协同处理。但是在高负载的情况下,协同处理的进程也会被任务占满。如果提前起好多几个计算器,在负载小的时候会浪费资源
- 另一种就是使用SQS+worker的方案。在这种方案里,worker只会在自己有能力处理消息的时候,才会从sqs里面获取消息,所以不会出现过载。再配合自动扩容,就会把浪费资源和无法处理过载的情况给解决了。就是用这种方式完成的自动扩容和均衡负载
实现架构
最简单版本的SQS+worker架构会是
- 一个SQS队列
- 一个worker + 一个守护进程 + 一个router
执行过程
1,你把一条消息送到SQS队列里面
2,worker 的守护进程从SQS队列里面取出消息,然后通过MIME送到本地的80端口
3,守护进程配置好router,80接收端的程序准备分别为router写好接收代码
另外,也可以配置定时任务,定时向SQS里面发送消息
worker的守护进程
1,守护进程首先先收到消息,把SQS队列里面的消息设置为占用,但是并不会删除SQS队列里面的消息
2,当worker处理完了消息,返回的是200,那么守护进程会发送一个 删除消息 的指令给亚马逊SQS队列,让队列删掉那条消息。
3,当worker处理完了消息,返回的不是200。那么在一个 ErrorVisibilityTimeout 和一个InactivityTimeout 时间之后,会把消息重新放到SQS队列里面,让其他worker能够重新处理该消息。
SQS队列
- SQS队列会自动删除时间超过RetentionPeriod的消息
死信队列 dead letter queues
私信队列会接收那些没有成功处理的消息,建立私信队列的好处是方便定位问题
你可以使用默认的dead letter queues,也可以配置一个SQS队列来做这个事情。另外是不能取消掉私信队列的。
定时任务
使用yaml文件来启动定时任务。yml的例子:
version: 1
cron:
- name: "backup-job"
url: "/backup"
schedule: "0 */12 * * *"
- name: "audit"
url: "/audit"
schedule: "0 23 * * *"
1,定时任务启动的时候,守护进程发一条消息给SQS队列
2,EB使用了leader环境来跑定时任务,leader的状态在Amazon DymamoDB上维护
自动扩容
亚马逊EC2的自动扩容会自动监控CPU的利用率,然后你需要自己配置CPU的利用率阈值,和最多ec2阈值。
所有的EC2实例会把自己的利用率发给云监控中心,自动扩容系统会从云监控中心,取到CPU利用率的平均值,然后你可以设置cpu利用率的上限和下限以及与之对应的多少个实例。
另外,你也可以设置云监控中心告警