PHP 消息队列 详解
前言:之前做过的一些项目中有时候会接触到消息队列,但是对消息队列并没有一个很清楚的认知,本篇文章将会详细分析和归纳一些笔记,以供后续学习。
一、消息对列概念
从本质上说消息对列就是一个队列结构的中间件,也就是说消息放入这个中间件之后就可以直接返回,并不需要系统立即处理,而另外会有一个程序读取这些数据,并按顺序进行逐次处理。
二、结构

由一个业务系统进行入队,把消息逐次插入到消息队列中,插入成功之后直接返回成功的结果,后续会有一个消息处理系统,这个系统会把消息系统中的记录逐次进行取出并进行处理,完成一个出队的流程。
三、应用场景
1、数据冗余:比如订单系统,后续需要严格的进行数据转换和记录,消息队列可以把这些数据持久化的存储在队列中,然后有订单,后续处理程序进行获取,后续处理完之后在把这条记录进行删除来保证每一条记录都能够处理完成。 2、系统解耦:使用消息系统之后,入队系统和出队系统是分开的,也就说其中一个崩溃之后不会影响另外一个的正常运行。 3、异步通信:消息本身使用入队之后可以直接返回。 4、扩展性:例如订单队列,不仅可以处理订单,还可以给其他业务使用。 5、排序保证:有些场景需要按照产品的顺序进行处理比如单进单出从而保证数据按照一定的顺序处理,使用消息队列是可以的。 6、流量削峰:就是秒杀和抢购的时候,会出现明显的流量剧增,对服务器的压力非常大。 7、消息通讯:消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。
四、队列介质
1、数据库,例如mysql(可靠性高,易实现,速度慢)
2、缓存, 例如redis(速度快,单个消息报包过大时效率低)
3、消息系统,专业性强,可靠,学习成本高(例如rabbitMq是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。)
4、Beanstalkd (一个高性能、轻量级的分布式内存队列系统)
五、消息处理触发机制
1、死循环方式读取:易实现,故障时无法及时恢复;(比较适合做秒杀,比较集中,运维集中维护) 2、定时任务:压力均分,有处理上限;目前比较流行的处理触发机制。(唯一的缺点是间隔和数据需要注意,不要等上一个任务没有完成下一个任务又开始了) 3、守护进程:类似于php-fpm 和php-cg,需要shell基础 4、采用发布订阅的方式
六、案例一:应用解耦
应用解耦:在订单系统出现故障时,不会影响到物流系统
一、说明:电商系统中订单系统、物流系统、财务系统以及操作日志记录系统之间的关系。 二、注意点:需要考虑中间数据的容灾能力,当故障发生并恢复时,保证业务流程可以恢复。保证每条数据都可以正确地完成处理。 三、传统模式:订单系统调用库存系统的接口。
缺点:1)假如物流系统无法访问,则订单无法调用物流接口,从而导致订单失败;
2) 订单系统与库存系统耦合 四、架构设计(以订单系统、物流系统为例,mysql为队列介质)
1、首先订单系统会接收用户的订单,然后进行订单的处理。
2、然后会把这些订单信息写到队列表中,这个队列表是沟通这两个系统的关键。
3、由配送系统定时执行的一个程序来读取队列表进行处理。
4、配送系统处理之后,会把已处理的记录进行标记。
架构图

程序流程图

发布订阅方式

七、案例二:流量削峰
说明:一般情况下,做秒杀案例,抢购,瞬间高并发,需要排队 的案例中 redis是一个很好的选择。 解释:小明制作蛋糕的时间比较长,订单来到后先登记成一个清单,然后逐次按顺序制作,订单量过大时,会暂时挂出『已售完』的牌子。 注意点:对于消峰需求,可以高峰期挂出『暂时无法购买,请稍等』等提示,防止流量对后续业务的冲击。对于秒杀等抢完即停的需求,需要考虑超发问题,可以添加一个名额计数器,或者在秒杀名额已满员时,发放一个秒杀完成标记,后续处理程序检测到完成标记后,再进行后续处理。 redis数据类型中的 list 类型常用命令:
* redis 的list 是一个双向链表,可以从头部或者尾部追加数据。 1、LPUSH/LPUSHX :将值插入到(/存在的)列表头部
2、RPUSH/RPUSHX: 将值插入到(/存在的)列表尾部
3、LPOP : 移除并获取列表的第一个元素
4、RPOP: 移除并获取列表的最后一个元素
5、LTRIM: 保留指定区间内的元素
6、LLEN: 获取列表长度
7、LSET: 通过索引设置列表元素的值
8、LINDEX: 通过索引获取列表中的元素
9、LRANGE: 获取列表指定范围内的元素
架构图

八、案例三:送达保证
场景说明:内容需要逐条严格执行,并保证执行成功,执行不成功或者中断时,可以恢复 解释:小明制作的蛋糕需要客户验货签收后,才可以继续制作下一个蛋糕。 实现:入队系统将业务需求写入消息队列后,即进行下一次业务处理。后续处理程序对队列内容进行逐条处理,处理完成后发放『完成许可』。消息队列中的内容,只有取得『完成许可』后,才可以从消息队列中删除。 注意点:重点考虑容灾相关问题,如业务恢复问题、重复处理问题。
架构图

九、案例四:排序保证
说明:消息队列中的内容有严格的顺序。 案例:抢号排队等系统 解释:小明制作蛋糕的顺序需要严格按下单顺序来制作。 实现:入队系统将内容逐条写入消息队列,并按单线排列,按先进先出的顺序来提出数据并进行后续处理。 注意点:需要使用单线程,保证只有一条生产线。
架构图

十、案例五:扩展性
场景:采用发布-订阅模式时,添加新的订阅者 案例:注册用户后,发送成功短信的模型中,追加一个发送email的功能 实现: 由多个消费者订阅一个消息的中间层,然后发布者将信息发布到中间层中。 订阅了这个中间层的消费者均可以收到这个消息,并进行后续处理。在这个结构中。如果想添加一个消息的后续处理组件 ,只需要将这个组件订阅到中间层即可 注意点:保证业务之间没有深度耦合,防止扩展时造成干扰。
架构图

十一、案例六:异步处理
场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种 (1)串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。 (2)并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。
串行示意图

并行示意图

我们可以发现:假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。 问题:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢? 解决:引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构如下:
引入消息队列示意图

解释说明:按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,
因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍。
十二、案例七:消息通讯
场景说明:消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。 点对点通讯:客户端A和客户端B使用同一队列,进行消息通讯。 聊天室通讯:客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现类似聊天室效果。 以上实际是消息队列的两种消息模式,点对点或发布订阅模式。
点对点示意图

聊天室示意图

以上就是我关于消息队列整理的一些信息,整篇文章主要是对消息队列的认识和能用来干什么的描述,看完后也能对消息队列有个清晰的认知。
参考链接:https://cloud.tencent.com/developer/article/1031602
http://www.cnblogs.com/dump/p/8243868.html
PHP 消息队列 详解的更多相关文章
- kafka以及消息队列详解
Kafka 是LinkedIn 开发的一个高性能.分布式的消息系统. 用途:广泛用于日志收集.流式数据处理.在线和离线消息分发等场景. 1. Kafka 将消息流按Topic 组织,保存消息的服务器称 ...
- 【转】windows消息和消息队列详解
转载出处:http://blog.csdn.net/bichenggui/article/details/4677494 windows消息和消息队列 与基于MS - DOS的应用程序不同,Wind ...
- IPC之消息队列详解与使用
一. 概念 消息队列就是一个消息的链表.对消息队列有写权限的进程可以向其中按照一定的规则添加新消息:对消息队列有读权限的进程可以从消息队列中读出消息.消息队列是随内核持续的.下面介绍三个概念: ...
- Windows 消息以及消息处理算法--线程和消息队列详解
Windows以消息驱动的方式,使得线程能够通过处理消息来响应外界. Windows 为每个需要接受消息和处理消息的线程建立消息队列(包括发送消息队列,登记消息队列,输入消息队列,响应消息队列),其中 ...
- 数据结构图文解析之:队列详解与C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- Android开发——Android的消息机制详解
)子线程默认是没有Looper的,Handler创建前,必须手动创建,否则会报错.通过Looper.prepare()即可为当前线程创建一个Looper,并通过Looper.loop()来开启消息循环 ...
- Windows 消息机制详解
总的来说: MSG包括: 窗口句柄,指示MSG发送的目的窗口 消息标识 lPARAM.wParam 发送时间 发送时的鼠标位置 关于消息队列: Windows系统有一个系统消息队列 每个线程都有一 ...
- HTTP消息头详解
HTTP是一个属于应用层面的面向对象的协议,由于其便捷.快速的方式.适用于分布式超媒体信息系统.于1990年提出 HTTP 协议主要特点概括如下 1.支持客户/服务器模式. 2.简单快速 请求方法常用 ...
- Java自带线程池和队列详解
Java线程池使用说明 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后 ...
随机推荐
- Bootstrap实现注册界面
样式一 例图 代码 <head> <meta charset="UTF-8"> <title>用户注册</title> <li ...
- 硬杠后端(后端坑系列)——Django前期工作
Django是一个开放源代码的Web应用框架,由Python写成,采用了MVC的框架模式. MVC MVC是一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个部件 ...
- Android项目实战(四十五):Zxing二维码切换横屏扫描
Demo链接 默认是竖屏扫描,但是当我们在清单文件中配置横屏显示的时候: <activity android:name=".CaptureActivity" android: ...
- vue input输入框长度限制
今天在开发登录页时,需要设置登录输入框的长度,输入类型为number <input type="number" maxlength="11" placeh ...
- socket字符流循环截取
场景:socket 客户端将一个单向链表序列化后发送给服务端,服务端将之解析,重新构建单向链表. Client.cpp //遍历链表,填充到缓冲区 ]) { ListNode* tmp = p; // ...
- Scala之eq,equals,==的区别
一.简介 根据官方API的定义: final def ==(arg0: Any): Boolean The expression x == that is equivalent to if (x eq ...
- Java设计模式视频讲解
设计模式(JAVA) 视频网址: http://www.qghkt.com/ 设计模式(JAVA)视频地址: https://ke.qq.com/course/318643?tuin=a508ea62 ...
- ILRuntime入门笔记
基础知识 官方地址:https://github.com/Ourpalm/ILRuntime 官方文档:https://ourpalm.github.io/ILRuntime/ 文档Markdown源 ...
- java 开发工具记录
jenkins 持续构建项目 lombok 优雅代码插件 sonarqube 代码检测插件
- 一键发布部署vs插件[AntDeploy]开源了
deploy to remote server by one button click 功能 支持docker一键部署(支持netcore) 支持iis一键部署(支持netcore和framework ...