1.为什么要使用消息队列
- 异步处理
可以更快的返回结果;
减少等待的时间,提升系统总体的性能。
说明:假设有两个系统A和B,系统A处理业务需要20ms,系统B处理业务需要花费60ms。在没有消息中间件的时候,用户发送请求到系统A,A处理完自己的业务后处理B的业务,最后返回结果总耗时应该在80ms(20ms+60ms)以上,在引入消息中间件后,A处理完业务后发送消息到消息中间件上(花费2ms),然后直接返回结果,总耗时在22ms左右。大大提升了系统的性能。 - 流量控制
通过使用消息队列来隔离网关和后台服务,来控制流量与保护后台服务。
说明:假设A商城举办大促活动,系统面临10 000的QPS,而后台的处理能力在5000左右的并发量,这时,如果流量全部进来则系统很大概率是要宕机的。再引入消息中间件后,可以将并发量放入到消息中间件中,然后系统再慢慢的进行处理。以此来实现大流量肖峰。 - 服务解耦
下游服务通过订阅主题(topic)来实现与上游服务的解耦。
说明:假设系统A跟系统B之间有消息中间件,那么如果B突然宕机了,则A并不会受到影响,A继续往消息中间件中发消息,等B系统恢复后再继续处理消息中间件的数据。
2.常用的消息队列
RabbitMQ
开发语言:Erlang
- 优点
轻量级、开箱即用;支持非常灵活的路由配置(Exchange模块);
能保证消息不丢失;
能保证高可用;
支持很多高级功能,如消息重试、死信队列等。
- 缺点
大量的消息堆积会使得性能非常差每秒能处理几万到十几万条消息,基本能满足大多数应用场景,但相比于RocketMQ和Kafka性能是最低的。不足以胜任类似“秒杀”的业务;
由于是用Erlang语言开发的,所以后期进行扩展或者二次开发有一定难度。
总结:老牌的消息队列,俗称兔子MQ。适合用于对性能、功能要求不高的场景,开箱即用。
RocketMQ
开发语言:Java
- 优点
吞吐量高,普通机器能达到十万QPS以上;
能保证高可用,高性能;
保证数据不丢失;
支持大规模的集群部署;
- 缺点
文档等资料不是很详细。
总结:阿里巴巴的开源消息队列产品,作为优秀的国产消息队列,近年来使用的越来越广。适用于在线业务。
Kafka
开发语言:Java与Scala
- 优点
异步收发的性能超高;
支持集群部署;
支持高吞吐量
- 缺点
可能会丢失数据。因为它收到消息之后不是马上写入磁盘,而是先写入内存中。
功能比较单一。主要功能就是接收/发消息。
总结:适用于大数据、流计算等海量的消息处理,以及日志收集系统ELK中。