1 为什么用MQ
在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如大量的insert,update之类的请求同时到达mysql,可能会直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误。通过使用消息队列,我们可以异步处理请求,从而缓解系统的压力。
2 候选框架
消息中间件是一种由消息传送机制或消息队列模式组成的中间件技术,利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。目前业界有很多的MQ产品,像RabbitMQ、ActiveMQ、ZeroMQ等都是极好的消息中间件。本次选型就从这三个3个备选框架中,多维度考察,结合咱们的系统,选取合适的框架。
3 框架简介
3.1 RabbitMQ
是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正是如此,使得它变得非常重量级,更适合于企业级的开发。
3.2 ApacheActiveMQ
ActiveMQ被誉为Java世界的中坚力量。它有很长的历史,而且被广泛地使用。它还是跨平台的,给那些非微软平台的产品提供了一个天然的集成接入点。类似于RabbitMQ,ActiveMQ易于实现高级场景,而且只需付出低消耗。它被誉为消息中间件的”瑞士军刀”。
3.3 ZeroMQ
ZeroMQ号称最快的消息队列系统,尤其针对大吞吐量的需求场景。是一个非常轻量级的消息系统,专门为高吞吐量/低延迟的场景开发。与RabbitMQ相比,ZeroMQ支持许多高级消息场景,但是你必须实现ZeroMQ框架中的各个块(比如Socket或Device等)。
4 详细参数比较
| RabbitMQ | ActiveMQ | ZeroMQ |
开发语言 | ErLang | Java | C |
支持协议 | AMQP, MQTT, STOMP | AMQP, MQTT, STOMP | TCP, UDP |
客户端语言 | Java, .Net, Python, Php, Perl | Java, .Net, Python, Php, Perl | Java, .Net, Python, Php等 |
事务 | 支持 | 支持 | 不支持 |
持久化 | 内存,文件 | 内存,文件,数据库 | 消息发送端保持 |
集群 | 支持 | 支持 | 不支持 |
负载均衡 | 支持 | 支持 | 不支持 |
管理界面 | 好 | 一般 | 无 |
优点 | 由于用到Erlang, mq性能较好.管理界面丰富,在互联网公司有较大规模应用.工业标准. | 产品成熟,运用广泛,文档较多. | 号称最快,大吞吐量 |
缺点 | ErLang语言难度较大 | 队列消息上千时有丢消息现象;下一个版本6.0在实现上有很大改动,而5.x维护较少. | 不提供消息持久化、无法方便存储及监控中间过程,需要自己实现审计和数据恢复 |
5 性能测试结果
5.1 场景1
场景说明:将分别包含1024字节的消息入队20000次,然后出队.查看入出队的时间.
结果:ZeroMQ所需时间最短, RabbitMQ(AMQP)次之.
5.2 场景2
场景说明:将分别包含32字节的200000个消息同时做入出队.查看入出队的时间.
结果:与场景一结果相同, ZeroMQ所需时间最短, RabbitMQ(AMQP)次之.
6 结合系统分析,做出选型
通过5.1与5.2的测试结果, 我们能得出:不论是大消息(1024字节), 还是小消息(32字节), ZeroMQ的性能都特别的好.然后使用AMQP协议的RabbitMQ也比较快. 另外还发现使用AMQP协议要比STOMP协议快.
综合此次需要异步消息的功能, [用户访问记录、预约、挂号、支付业务],消息都不会很大,应该在1KB以下, ZeroMQ和RabbitMQ(AMQP)都是很不错的选择.但考虑到ZeroMQ不支持事务,不支持持久化, 最后选择使用RabbitMQ.