消息队列的思考
目录
什么是消息队列
维基百科的定义:在计算机科学中,消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它。
这定义太复杂了。简单的来讲就是排队系统嘛。这好比,每天到了中午吃饭的点,去麦当劳或者肯德基,都是要排队的嘛,毕竟,员工的数量有限,中午想吃饭的人会很多。大家都会先下单,然后拿着号码去排队取餐。这就是队列啊。
消息队列应用场景
消息队列的应用场景是,当前业务处理量遇到瓶颈,无法及时处理业务,将部分耗时业务分离到消息队列异步处理,避免业务处理失败。 这好比有人在麦当劳点了1个经典套餐,另外一个人点了7个儿童套餐过生日,门店的员工会根据下单情况进行处理,做好经典套餐直接让第一个人来取,肯定不会说,先做完7个儿童套餐再处理第一个任务。
消息队列,可以解耦复杂业务的逻辑,但不可避免,降低了用户的体验。如果每次去麦当劳都需要排对下单,取餐,我想你以后也不大想去他们家吃饭了吧。
优势
队列的好处:
- 增大的系统的吞吐量,可以处理更多的”请求”。
- 不管是耗时任务还是即时任务,都可以得到较好的处理。
劣势
队列的劣势:
- 由于消息队列的存在,任务变成了异步处理,处理完成的时间不可预知。
- 既然有异步的处理,必然会有数据不一致的情况。
常用的消息队列
RabbitMQ
消息模式
支持消息模式 | 备注 |
---|---|
简单队列 | 支持单一的消费者 |
工作队列 | 支持多个消费者 |
发布订阅 | 通过exchange获取队列,消费队列的消息 |
路由队列 | exchange_type='direct' 必须exchange和routing_key匹配才可以消费消费。 |
主题队列 | exchange_type='topic' 可实现队列模糊匹配 |
RPC | 支持RPC调用消费 |
性能
实现原理
- RabbitMQ是基于AMQP(Advanced Message Queuing Protocol,高级消息队列协议)实现的消息中间件。实现的语言是erlang。
- 常用较多的是路由模式。可以实现精确的消息匹配,只需要获取自定义的消息。
PHP支持
- 安装Composer包
php-amqplib/php-amqplib
- PHP扩展
Kafka
消费模式
暂时只支持一种topics。支持多个消费者,支持分组,可以平均分布消息到不同的分区。
性能
- 官方在2014年也做了性能测试。单机达到了80k消息每秒。官方性能测试 文章地址
- 可以说是为了性能而存在的消息队列。
- Kafka并不保证消息顺序,也不支持数据持久化,部署依赖zookeeper组件实现分布式。
实现原理
Kafka底层是Java实现的。
PHP支持
- 优先推荐PHP扩展 rdkafka 主要就基于librdkafka开发的PHP客户端。
- 也有相关的Composer包,该包不支持snappy压缩方式的消息。