需求背景
PHP RabbitMQ扩展不支持连接池
连接池的作用主要是节省连接的时间。连接池机制预先打开N个连接,把它们缓存起来,当需要使用连接的时候就直接使用这些已经打开的连接,从而节省了时间。但PHP的RabbitMQ扩展为了兼容PHP-FPM模式,因为在PHP-FPM模式下是不能做连接池的,脚本在解释执行完毕后会释放所有的内存资源,没法进行内存常驻。
RabbitMQ配置信息与业务强耦合
RabbitMQ配置信息散落在各个业务上,任意配置的改动,都需要各个业务组进行配合修改,并且要在切换的过程中保证线上的服务运行正常,且没法做到统一管理,给维护上带来一定的难度与成本。
PHP-FPM缺乏异步消息投递机制
PHP-FPM为同步编程模型,并不支持异步的编程方式,所有代码都是逐行顺序执行的。非常符合程序员的习惯,不管是编码还是调试。但在IO密集型的场景下,就会逐渐显得有点乏力,因为该场景下的CPU利用率将会大大降低,发挥不出该有的性能。
性能低
PHP-FPM模型下的PHP,将会有着非常多的初始化。比如配置、连接、文件等等。这一系列的操作,对性能的影响将是毫秒级的。
技术要求
吞吐量
吞吐量(Throughput)指在单位时间内成功传输的数据量。作为消息队列中间件,必须有着非常高的吞吐量,不能因此成为业务的瓶颈。
可用性
可用性(Availability)指在一段连续时间考察内,系统正常运行的概率。在保证吞吐量的基础上,还必须保证系统能够7*24小时正常运转。作为消息中转平台,如果发生故障,将会导致业务不同情况受损。
可维护性
可维护性(Maintainability)是衡量一个系统的可修复(恢复)性和可改进性的难易程度。除了编码上的可维护性,还需对故障的检测、诊断、修复提供快速的响应能力。
跨平台
跨平台(Cross Platform)指不应受到硬件或者环境影响而导致程序的不可运行。在设计中,必须考虑到多种编程语言(JAVA、PHP、PYTHON等等)的接入场景,要基于通用的协议进行开发。
业务透明
业务透明(Service Transparency)指对所有环境提供固定的接入方式。消息队列的配置不对业务开放,实现统一管理。无论是阶段性的服务迁移或者是参数调整,对业务来说都是无感知的,简化维护流程。
技术选型简介
PHP简介
PHP(外文名称:PHP:Hypertext Preprocessor,中文名称:超文本预处理器)是一种通用的开源脚本语言。该语法吸收了C语言、Java和Perl的特点,有利于学习和广泛使用,主要适用于Web开发领域。PHP的独特语法是C、Java、Perl和PHP自己的语法的混合。它可以比CGI或Perl更快地执行动态web页面。与其他编程语言相比,PHP将程序嵌入到HTML(一种标准通用标记语言的应用程序)文档中执行。执行效率比完全生成HTML标记的CGI要高得多。PHP还可以执行编译后的代码,这将对代码进行加密和优化,以使其运行得更快。
Swoole简介
Swoole允许PHP开发人员编写高性能、高并发的服务,如TCP、UDP、Unix套接字、HTTP和WebSocket,使PHP超越Web。Swoole4的成熟将PHP带到了一个前所未有的阶段,为性能改进提供了独一无二的可能性。Swoole可广泛应用于互联网、移动通信、云计算、在线游戏、物联网、汽车联网、智能家居等领域。使用PHP+Swoole可以使企业IT研发团队更有效率,更专注于开发创新产品。
RabbitMQ简介
RabbitMQ,全名为Rabbit Message Queue,是一种应用程序到应用程序的通信方法。应用程序通过从队列(应用程序的数据)读写消息进行通信,而不需要专用连接来链接它们。消息传递指的是程序之间通过发送消息中的数据进行通信,而不是通过相互直接调用进行通信,后者通常用于远程过程调用等技术。排队意味着应用程序通过队列进行通信。使用队列消除了同时接收和发送应用程序的需要。
生产者服务设计
架构设计图
待补充
进程关系简介
Reactor线程
- Reactor线程是在Master进程中创建的线程
- 负责维护客户端TCP连接、处理网络IO、处理协议、收发数据
- 不执行任何PHP代码
- 将TCP客户端发来的数据缓冲、拼接、拆分成完整的一个请求数据包
Worker进程
- 接受由Reactor线程投递的请求数据包,并执行PHP回调函数处理数据
- 生成响应数据并发给Reactor线程,由Reactor线程发送给TCP客户端
- 可以是异步非阻塞模式,也可以是同步阻塞模式
- Worker以多进程的方式运行
TaskWorker进程
- 接受由Worker进程投递的任务
- 处理任务,并将结果数据返回给Task Worker进程
- 完全是同步阻塞模式
- Task Worker以多进程的方式运行
Manager进程
- 负责创建/回收Worker/Task进程
入口设计
基于HTTP协议
HTTP(超文本传输协议)是Internet上使用最广泛的网络传输协议之一。所有的WWW文件必须遵守这个标准,并且可以作为所有编程语言的通用协议使用。
Swoole的http服务启动
$http = new Swoole\Http\Server('0.0.0.0', 9501);
$http->on('request', function ($request, $response) {
...调用入口
});
$http->start();
URL路由设计TaskWorker进程工作原理
HTTP服务与TaskWorker进程关系
HTTP接收到请求,完成基本的解析与校验之后,通过TaskWorker进程,进行消息投递并结束HTTP请求。然后由TaskWorker进程进行异步的RabbitMQ消息投递,能够满足高吞吐量的场景。
消息体构建
public static function buildMessage(string $content): array
{
$content = json_decode($content, true);
$queue = [];
foreach($content as $item) {
$obj = new self();
foreach([
'exchange',
'queue',
'route',
'payload'
] as $k) {
$obj->{$k} = $item[$k];
}
$queue[