Swoole学习笔记(一):架构概述
更新:HHH   时间:2023-1-7


swoole虽然是标准的PHP扩展,实际上与普通的扩展不同。普通的扩展只是提供一个库函数。而swoole扩展在运行后会接管PHP的控制权,进入事件循环。
在swoole中,有一个master进程(父进程)和多个worker进程(子进程),这个和nginx,fpm属于同一种模型。

1.进程和子进程
关于进程的概念不多赘述,进程中最重要的两个部分,一是内存:包括堆栈,各种变量等等;二是上下文切换,如操作系统资源、信号量和自身状态等等;
子进程由父进程创建,但是子进程拥有独立的内存和上下文环境:
1)子进程会复制父进程的内存空间和上下文环境。注意,这里是复制,并不是共享内存,这和线程是不同的。
2)修改某个子进程的内存空间,不会修改父进程或其他子进程中的内存空间;
3)子进程会复制父进程的IO句柄(fd描述符);

2.进程间的通讯方式
进程之间常见的通讯方式如下:
1)管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2)命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
3)消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
4)共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
5)信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
6)套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
7)信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
在swoole中,子进程间的通讯是通过共享内存实现的:

共享内存具有如下的特点:
共享内存不属于任何一个进程;
共享内存中分配的内存可以被任何进程访问,只要有这块共享内存的key值就好;
即使进程退出,共享内存仍然可以技术保留;

3.swoole的整体架构
swoole的整体架构如下:

swoole中进程间的通信是通过管道实现的。
1) master用来处理swoole核心的事件驱动
Main Reactor:总线程,负责线程任何调度
Reactor:线程,每一个子线程包含一个epoll实例的实现
2) manager
负责管理,不会运行任何用户层的业务逻辑,只负责进程的管理和分配
3) worker
主逻辑进程,处理来自客户端的请求
当woker进程被关闭,manager会重新拉起一个进程,保证woker的总数量
4) task
异步工作进程,处理耗时较长的任务

4.task与woker
task与woker之间是通过unix Sock管道进行通讯的,也可以通过消息队列进行实现

1.Task传递数据大小
数据小于8K,直接通过管道传递,数据大于8K,写入临时文件传递
2.Task传递对象
可以通过序列化传递一个对象的拷贝;
Task中对对象的改变不会反映到Worker进程中;
数据库连接,网络连接对象不可以传递。
3.Task的onFinish回调
Task的onFinish回调会发回调用task方法的Worker进程(投递者)

5.timer定时器
timer定时器用来替代crontab,来实现一个精度更高(毫秒级别)的定时器;
在1.7.x之前,timer是一个线程,这个线程会在一定的间隔唤醒,来检查各个定时器是否能够使用
这种方式有以下两个问题:
1)创建的定时器的数量有限,本轮还没循环完,下轮就又开始了;
2)容错性小,线程挂掉,整个定时器任务失效;

新版swoole采用注册一个epoll函数,如果超过timeout,这个函数会返回,去回调指定函数,检查内存中是否有可用的定时器
使用最小堆,存放timer

返回web开发教程...