onWorkerStart
原型
function onWorkerStart(swoole_server $server, int $worker_id)
参数:int $worker_id
-
$worker_id
是一个从[0 -$worker_num
) 区间内的数字,表示这个Worker工作进程的编号。 -
$worker_id
和进程PID没有任何关系,可使用posix_getpid
函数获取当前进程的PID。
使用
onWorkerStart
事件会在Worker
进程、Task
进程启动时发生,事件回调中创建的对象可以在进程生命周期内使用。onWorkerStart
事件与onStart
事件是并发执行的,并没有固定的先后顺序。可通过
$server->taskworker
属性判断当前是Worker工作进程还是Task任务进程当服务器对象设置了
worker_num
和task_worker_num
选项超过1时,每个进程都会触发一次onWorkerStart
事件,可通过判断$worker_id
来区分不同的工作进程。由
Worker
进程向Task
进程发送任务,Task进程处理完所有任务之后会通过onFinish
回调函数通知Worker进程。
例如:在后台操作向10W个用户群发通知邮件,操作完成后操作的状态显示为发送中,此时可以继续其它操作,等邮件群发完毕后,操作的状态自动会修改为已发送。
当发生致命错误或代码中主动调用
exit
时,Worker工作进程或Task任务进程会退出,Manager管理进程会重新创建新的工作进程,这可以导致死循环,也就是不停地在创建和销毁进程。如果想使用
Reload
重载机制实现代码重新加载,必须在onWorkerStart
中require
业务文件,而不是在文件头部引入。在onWorkerStart
调用之前已经包含的文件不会重新载入代码。可以将公用的、不易变得PHP文件放置到
onWorkerStart
之前,这样虽然不能重载代码,但对所有Worker工作进程来说是共享得,也就不需要额外得内存来保存这些数据。onWorkerStart
之后的代码,每隔进程都需要在内存中保存一份。Swoole2.1.0版本中
onWorkerStart
回调函数中创建了协程,在onWorkerStart
中可以调用协程的API。
当onWorkerStart
事件被回调后,Worker进程的任务分配模式是怎么样的呢?
首先Worker进程数据包分配模式取决于服务器运行时配置参数dispatch_mode
的值
-
dispatch_mode = 1
表示平均分配 -
dispatch_mode = 2
表示文件描述符取模固定分配,默认方式。 -
dispatch_mode = 3
表示抢占式分配
所谓抢占式分配,指的是每次都是空闲的Worker工作进程获得数据,此方式很适合SOA/RPC类的内部服务框架。当服务器运行时参数配置了抢占式分配模式后,Worker工作进程内发生的onConnect
、onReceive
、onClose
、onTimer
事件会将Worker进程标记为繁忙状态而不再去接收新的请求。Reactor线程会将新请求投递给其它状态空闲的Worker工作进程上。如果希望每个连接的数据分配都给固定的Worker工作进程,需设置为按文件描述符取模固定分配的方式。
onWorkerStop
原型
function onWorkerStop(Swoole\Server $server, int $worker_id);
onWorkerStop
事件在Worker工作进程终止时发生,在此函数中可以回收Worker进程申请的各类资源。
参数
$worker_id
是一个从[0 - $worker_num
)之间的整型数字,用于表示当前Worker工作进程的编号。另外$worker_id
和PID是没有任何关系的。
注意
- 当进程移除结束,比如被强制
kill
、致命错误、core dump
时是无法执行onWorkerStop
回调函数的。 - 不要再
onWorkerStop
中调用任何异步或协程相关的API,触发onWorkerStop
时底层已经销毁了所有事件循环设施。
onWorkerExit
原型
function onWorkerExit(swoole_server $server, int $worker_id);
onWorkerExit
仅在服务器开启了reload_async
异步重启特性后才生效,异步重启特性会先创建新的Worker工作进程用来处理新的请求,旧的Worker工作进程会自行退出。旧的Worker工作进程在退出时先会执行一次onWorkerStop
事件回调,然后会在事件循环的每个周期结束时调用onWorkerExit
通知Worker进程退出。
如果Worker进程没有退出,onWorkerExit
会持续触发。onWorkerExit
仅仅在Worker工作进程内触发,Task任务进程是不会执行onWorkerExit
事件的。
在onWorkerExit
中应尽可能地移除或关闭异步的Socket连接,最终底层检测到Reactor线程中事件监听的句柄数量为0时会退出进程。
onWorkerError
原型
void onWorkerError(swoole_server $server, int $worker_id, int $worker_pid, int $exit_code, int $signal);
onWorkerError
事件主要用于报警和监控,一旦发现Worker工作进程异常退出,那很有可能是遇到了致命错误或进程CoreDump
,通过记录日志或发送警报的信息来提示开发者进行相应的处理。
当Worker工作进程或Task任务进程发生异常后,会在Manager管理进程内触发onWorkerError
事件回调。
参数
-
int $worker_id
异常进程的编号 -
int $worker_pid
异常进程的PID -
int $exit_code
退出的状态码,范围时0到255。 -
int $signal
进程退出的信号
进程退出状态码
-
exit_code = 255
表示Worker工作进程发生了Fatal Error
致命错误,需检查PHP的错误日志,找到存在问题的代码并进行解决。
进程退出信号
-
signal = 11
说明Worker工作进程发生了segment_fault
段错误,可能触发了底层的Bug,需要收集core dump
信息和valgrind
内存检测日志,向官方反馈。 -
signal = 9
说明Worker工作进程被系统强行kill
杀死,需检查是否有认为的kill -9
操作,并检查dmesg
信息中是否存在OOM
(Out of Memory)内存溢出。如果存在内存溢出,则是分配了过大的内存。此时需检测服务器对象的setting
属性配置中,是否创建了非常大的Swoole\Table
、Swoole\Buffer
等内存模块。