消息队列的思考

什么是消息队列

维基百科的定义:在计算机科学中,消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它。

这定义太复杂了。简单的来讲就是排队系统嘛。这好比,每天到了中午吃饭的点,去麦当劳或者肯德基,都是要排队的嘛,毕竟,员工的数量有限,中午想吃饭的人会很多。大家都会先下单,然后拿着号码去排队取餐。这就是队列啊。

消息队列应用场景

消息队列的应用场景是,当前业务处理量遇到瓶颈,无法及时处理业务,将部分耗时业务分离到消息队列异步处理,避免业务处理失败。
这好比有人在麦当劳点了1个经典套餐,另外一个人点了7个儿童套餐过生日,门店的员工会根据下单情况进行处理,做好经典套餐直接让第一个人来取,肯定不会说,先做完7个儿童套餐再处理第一个任务。

消息队列,可以解耦复杂业务的逻辑,但不可避免,降低了用户的体验。如果每次去麦当劳都需要排对下单,取餐,我想你以后也不大想去他们家吃饭了吧。

优势

队列的好处:
1. 增大的系统的吞吐量,可以处理更多的”请求”。
2. 不管是耗时任务还是即时任务,都可以得到较好的处理。

劣势

队列的劣势:
1. 由于消息队列的存在,任务变成了异步处理,处理完成的时间不可预知。
2. 既然有异步的处理,必然会有数据不一致的情况。

常用的消息队列

RabbitMQ

消息模式

支持消息模式 备注
简单队列 支持单一的消费者
工作队列 支持多个消费者
发布订阅 通过exchange获取队列,消费队列的消息
路由队列 exchange_type='direct' 必须exchange和routing_key匹配才可以消费消费。
主题队列 exchange_type='topic' 可实现队列模糊匹配
RPC 支持RPC调用消费

性能

  1. 根据性能测试第二部分 第一部分 大约在4w个消息每秒,开启ack+持久化后,几乎下降了10倍。该测试在2012年发布的,仅供参考。

实现原理

  1. RabbitMQ是基于AMQP(Advanced Message Queuing Protocol,高级消息队列协议)实现的消息中间件。实现的语言是erlang。
  2. 常用较多的是路由模式。可以实现精确的消息匹配,只需要获取自定义的消息。

PHP支持

  1. 安装Composer包 php-amqplib/php-amqplib
  2. PHP扩展

Kafka

消费模式

暂时只支持一种topics。支持多个消费者,支持分组,可以平均分布消息到不同的分区。

性能

  1. 官方在2014年也做了性能测试。单机达到了80k消息每秒。官方性能测试 文章地址
  2. 可以说是为了性能而存在的消息队列。
  3. Kafka并不保证消息顺序,也不支持数据持久化,部署依赖zookeeper组件实现分布式。

实现原理

Kafka底层是Java实现的。

PHP支持

  1. 优先推荐PHP扩展 rdkafka 主要就基于librdkafka开发的PHP客户端。
  2. 也有相关的Composer包,该包不支持snappy压缩方式的消息。

参考链接

  1. 消息队列及常见消息队列介绍
  2. 消息队列
  3. RabbitMQ和Kafka

发表评论

电子邮件地址不会被公开。 必填项已用*标注