1. 消息队列概念
消息队列其实就是队列结构的中间件
(1). 队列结构的中间件
(2). 消息放入后,不需要立即处理
(3). 由订阅者/消费者按顺序处理
当遇到并发特别大,或者耗时非常长的环节,同时不需要立即获得环节的返回结果,就可以使用消息队列

应用场景
冗余: 比如订单系统,需要严格的数据转换和记录,消息队列可以把这些数据持久化的存储在队列中,然后由订单后续程序进行获取,后续处理完成之后再把这条记录删除,来保证每一条记录都能处理完成
解耦:消息队列分为两套系统,解决了两套系统之间深度耦合的问题,使用消息队列之后,入队的系统和出队的系统没有直接的关系,入队系统和出队系统,其中一套系统崩溃的时候都不会影响到另外一套系统的正常运转,比如订单系统崩溃了,是不会影响到后端的财务系统,配货系统的运转的
流量削峰:最经典的场景就是秒杀和抢购,这种场景会出现明显的流量剧增,大量需求集中在短短几秒之内,对服务器的瞬间压力非常大。配合缓存和消息队列,能非常有效的顶住瞬间访问量,防止服务器崩溃
异步通信:消息本身就可以使入队的系统直接返回,实现了程序的异步操作
扩展性:比如订单入队之后,后续会有财务系统进行处理,后期如果想增加一个配货系统,只需要让配货系统订阅消息队列就可以了,非常容易对系统进行扩展
排序保证:某些场景下,数据的处理顺序是非常重要的,这种情况适合用队列处理,因为队列本身可以做成单线程,单进单出的系统,有效保证数据按顺序处理
常见队列实现优缺点
队列介质:
(1). MySQL:可靠性高,易实现,速度慢
(2). Redis:速度块,单条大消息包时效率低
(3). 消息系统:专业性强,可靠,学习成本高
消息处理触发机制
(1). 死循环方式读取 (使程序不断的读取数据):易实现,故障时无法及时处理(比较适合秒杀)
(2). 定时任务(每隔几秒后几分处理一次):压力均分,由处理量上线(物流系统,订单系统)(比较流行)
(3). 守护进程(监听进程): 类似于PHP-FPM和PHP-CG,需要shell基础
解耦案例:队列处理订单系统和配送系统


流量削峰案例:Redis的List类型实现秒杀
为什么要用Redis,而不是Mysql
1. Redis是基于内存,速度要快很多, Mysql需要写入硬盘。 其他业务也会使用Mysql,秒杀系统如果耗光Mysql的资源,会影响其他系统。
2. Redis对数据库有很好的补充作用。Redis是可持久化的,会周期性的把数据写到硬盘里,不用担心断电的问题。
3. Redis提供了五种数据类型,字符串,双向链表,哈希表,集合,有序集合。其中双向链表List类型可以支持反向查找和遍历,最多可以支持四十亿个元素。
Redis数据类型中的list类型
1. LPUSH / LPUSHX : 将值插入到(/存在的,不存在忽略)列表头部
2. RPUSH / RPUSHX :将值插入到(/存在的,不存在忽略)列表尾部
3. LPOP:移出并获取列表的第一个元素
4. RPOP:移出并获取列表的最后一个元素
5. LTRIM:保留指定区间内的元素
6. LLEN:获取列表长度
7. LSET:通过索引设置列表元素的值
8. LINDEX:通过索引获取列表中的元素
9. LRANGE:获取列表指定范围内的元素
代码级设置
1. 秒杀程序把请求写入Redis (Uid, time_stamp微秒)
2. 检查Redis已存放数据的长度,超出上限直接丢弃
3. 死循环处理存入Redis的数据并入库
将秒杀的程序写进redis中,通过入库程序,慢慢写入数据库,这样可以实现流量均衡,使后端不会有特别大的压力
RabbitMQ
专业的消息队列系统
RabbitMQ安装(rabbitmq-server, php-amqplib)
生产者向消息通道发送消息
消费者处理消息
待学。。。
网友评论