Swoole从入门到入土(4)——TCP服务器[正确重启]
在上一篇中,我们提到了一个配置项max_wait_time。这个配置项决定了在服务端在进程经束的时候,在max_wait_time时间内onWorkerStop事件会完成扫尾工作。
那什么时候worker进程会结束呢?那当然是手动关闭(管理进程收到重启、关闭信号后)或者自动关闭(达到 max_request 时)啦。
这里我们就会遇到一个问题:当更新了服务端的代码后,为了让新代码生效,如何优雅地终止 / 重启swoole服务端才能保证正在执行的业务不丢失?
因为一台繁忙的后端服务器随时都在处理请求,如果运维人员通过 kill 进程方式来终止 / 重启服务器程序,有可能导致刚好代码执行到一半终止,没法保证整个业务逻辑的完整性。
幸好,Swoole 提供了柔性终止 / 重启的机制,管理员只需要向 Server 发送特定的信号或者调用 reload 方法,worker进程就可以保证做好善后工作并结束进程,之后再重新拉起。
管理员发送信号 :
# 重启所有worker进程
kill -USR1 主进程PID # 仅重启task进程
kill -USR2 主进程PID
#SIGTERM: 向主进程 / 管理进程发送此信号服务器将安全终止
kill -15 主进程PID
reload()方法:安全地重启所有 Worker/Task 进程。
Swoole\Server->reload(bool $only_reload_taskworkrer = false): bool
参数$only_reload_taskworkrer:是否仅重启 Task 进程,默认值:false
注意事项:
-reload 有保护机制,当一次 reload 正在进行时,收到新的重启信号会丢弃
- 如果设置了 user/group,Worker 进程可能没有权限向 master 进程发送信息,这种情况下必须使用 root 账户,在 shell 中执行 kill 指令进行重启
-reload 指令对 addProcess 添加的用户进程无效
-在 Base 模式下,客户端连接直接维持在 Worker 进程中,因此 reload 时会切断所有连接。
shutdown() 方法: 关闭服务
Swoole\Server->shutdown(): void
此函数可以用在 Worker 进程内
到了这里,大家了解了如何优雅关闭 / 重启swoole服务器了。当然,还没完,我们需要注意以下两点:
1) 要注意新修改的代码必须要在 OnWorkerStart 事件中重新载入才会生效,比如某个类在 OnWorkerStart 之前就通过 composer 的 autoload 载入了就是不可以的。
2) reload 还要配合这两个参数 max_wait_time 和 reload_async,设置了这两个参数之后就能实现异步安全重启。如果没有reload_async,Worker 进程收到重启信号或达到 max_request 时,会立即停止服务,这时 Worker 进程内可能仍然有事件监听,这些异步任务将会被丢弃。设置reload_async后会先创建新的 Worker,旧的 Worker 在完成所有事件之后自行退出。
如果旧的 Worker 一直不退出,底层还增加了一个定时器,在max_wait_time 秒内旧的 Worker 没有退出,底层会强行终止,并会产生一个 WARNING 报错。
本文新配置:
reload_async:设置异步重启开关。【默认值:true】
如何设置配置?请查看上一篇,基本配置项,点这里传送。
本文新事件:
onWorkerStart:此事件在 Worker 进程 / Task 进程启动时发生,这里创建的对象可以在进程生命周期内使用。
function onWorkerStart(Swoole\Server $server, int $workerId);
$server:Swoole\Server 对象
$workerId:Worker 进程 id(非进程的 PID)
注意:
- onWorkerStart/onStart 是并发执行的,没有先后顺序。
- 可以通过 $server->taskworker 属性来判断当前是 Worker 进程还是 Task 进程。
- 设置了 worker_num 和 task_worker_num 超过 1 时,每个进程都会触发一次 onWorkerStart 事件,可通过判断 $worker_id 区分不同的工作进程。
- 由 worker 进程向 task 进程发送任务,task 进程处理完全部任务之后通过 onFinish 回调函数通知 worker 进程。
- 如果想使用 Reload 机制实现代码重载入,必须在 onWorkerStart 中 require 你的业务文件,而不是在文件头部。在 onWorkerStart 调用之前已包含的文件,不会重新载入代码。
- 可以将公用的、不易变的 php 文件放置到 onWorkerStart 之前。这样虽然不能重载入代码,但所有 Worker 是共享的,不需要额外的内存来保存这些数据。 onWorkerStart 之后的代码每个进程都需要在内存中保存一份。
- 发生致命错误或者代码中主动调用 exit 时,Worker/Task 进程会退出,管理进程会重新创建新的进程。这可能导致死循环,不停地创建销毁进程。
onWorkerStop:此事件在 Worker 进程终止时发生。在此函数中可以回收 Worker 进程申请的各类资源。
function onWorkerStop(Swoole\Server $server, int $workerId);
$server:Swoole\Server 对象
$workerId:Worker 进程 id(非进程的 PID)
注意:
- 程异常结束,如被强制 kill、致命错误、core dump 时无法执行 onWorkerStop 回调函数。
- 一定不要在 onWorkerStop 中调用任何异步或协程相关 API,触发 onWorkerStop 时底层已销毁了所有事件循环设施。
onWorkerExit:仅在开启 reload_async 特性后有效。(笔者注:这个事件笔者在试验的代码中触发不了,不知道是不是哪个姿势不对)
function onWorkerExit(Swoole\Server $server, int $workerId);
$server:Swoole\Server 对象
$workerId:Worker 进程 id(非进程的 PID)
注意:
- Worker 进程未退出,onWorkerExit 会持续触发。
- onWorkerExit 仅在 Worker 进程内触发, Task 进程不执行 onWorkerExit。
- 在 onWorkerExit 中尽可能地移除 / 关闭异步的 Socket 连接,最终底层检测到事件循环中事件监听的句柄数量为 0 时退出进程。
- 等待 Worker 进程退出后才会执行 onWorkerStop 事件回调。
----------高级分割线----------
Linux信号普及:



--------------------------- 我是可爱的分割线 ----------------------------
最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同学点击链接,联系我吧。
Swoole从入门到入土(4)——TCP服务器[正确重启]的更多相关文章
- 【Swoole】简单安装与创建TCP服务器
pecl install swoole PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了php语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据 ...
- php的异步非阻塞swoole模块使用(一)实现简易tcp服务器--服务端
绑定tcp服务器的地址 $swserver = new swoole_server("127.0.0.1",9501); 设置tcp服务器装机容量(太危言耸听了-其实就是设置属性) ...
- HTTP从入门到入土(3)——TCP三次握手
TCP三次握手 客户端与服务器之间互相发送HTTP请求响应之前需要先进行TCP连接,因为HTTP是一个无连接.无状态协议,不存在连接的概念,只有请求和响应的概念.而请求和响应实际上只是数据包,他们需要 ...
- php的异步非阻塞swoole模块使用(一)实现简易tcp服务器--客户端
//实例化一个swoole客户端 $swclient = new swoole_client(SWOOLE_SOCK_TCP); //建立连接---如果连接无效则退出 )){ echo "连 ...
- Swoole学习(七)Swoole之异步TCP服务器的创建
环境:Centos6.4,PHP环境:PHP7 <?php //创建TCP服务器 /** * $host 是swoole需要监听的ip,如果要监听本地,不对外服务,那么就是127.0.0.1;如 ...
- Swoole学习(二)Swoole之TCP服务器的创建
环境:Centos6.4,PHP环境:PHP7 <?php //创建TCP服务器 /** * $host 是swoole需要监听的ip,如果要监听本地,不对外服务,那么就是127.0.0.1;如 ...
- swoole 创建tcp服务器
server.php <?php /** * 创建tcp服务器 * Date: 2019/1/15 */ $serv = new swoole_server('127.0.0.1', 9501) ...
- Swoole系列(三):建立TCP服务器并发送数据测试
<?php // 建立tcp服务器下 $host = '0.0.0.0'; $port = 9501; $serv = new swoole_server($host,$port); $serv ...
- 18-ESP8266 SDK开发基础入门篇--TCP 服务器 RTOS版,串口透传,TCP客户端控制LED
https://www.cnblogs.com/yangfengwu/p/11112015.html 先规定一下协议 aa 55 02 01 F1 4C 控制LED点亮 F1 4C为CRC高位和低位 ...
- 17-ESP8266 SDK开发基础入门篇--TCP服务器 RTOS版,小试牛刀
https://www.cnblogs.com/yangfengwu/p/11105466.html 现在开始写... lwip即可以用socket 的API 也可以用 netconn 的API实 ...
随机推荐
- Mygin 实现简单Http
本篇是完全参考gin的功能,自己手动实现一个类似的功能,帮助自己理解和学习gin框架 目的 简单介绍net/http库以及http.Handler接口 实现简单的功能 标准库启动Web服务 impor ...
- [转帖]TiDB 热点问题处理
TiDB 热点问题处理 本文介绍如何定位和解决读写热点问题. TiDB 作为分布式数据库,内建负载均衡机制,尽可能将业务负载均匀地分布到不同计算或存储节点上,更好地利用上整体系统资源.然而,机制不是万 ...
- [转帖]一、Kafka Tool使用
一.Kafka Tool使用 1.添加cluster 2.开启SASL_PLAINTEXT 如果kafka 开启SASL_PLAINTEXT认证(用户名和密码认证) 3.高级设置 如果设置的是SASL ...
- [转帖]linux系统下grub.cfg详解和实例操作
linux系统下grub.cfg详解和实例操作 简介 grub是引导操作系统的程序,它会根据自己的配置文件,去引导内核,当内核被加载到内存以后,内核会根据grub配置文件中的配置,找到根分区所使用的文 ...
- [转帖]VMWare ESXi中,不同的虚拟网卡性能竟然能相差三倍!
https://zhuanlan.zhihu.com/p/525656364 正文共:1024 字 11 图,预估阅读时间:1 分钟 在上个实验中(VPP使用DPDK纳管主机网卡),我们已经初步实现了 ...
- 【转帖】磁盘IOPS的计算
计算磁盘IOPS的三个因素: 1.RAID类型的读写比 不同RAID类型的IOPS计算公式: RAID类型 公式 RAID5.RAID3 Drive IOPS=Read IOPS + 4*Write ...
- 【转帖】JVM 元数据区的内存泄漏之谜
https://www.infoq.cn/article/Z111FLot92PD1ZP3sbrS 一.问题描述 某天,SRE 部门观察到一个非常重要的应用里面有一台服务器的业务处理时间(Transa ...
- 【转帖】Linux创建软连接出现的错误及解决方法
问题: 创建软连接以后,使用cd 软连接路径显示没有那个文件或目录. 创建过程及切换结果,如图: 原因: 路径一定要写成绝对路径!!! 解决办法: 了解创建软连接的命令: ln -s 源文件 目标文件 ...
- [转帖]台积电3nm工艺细节曝光
https://weibo.com/ttarticle/p/show?id=2309404853901739557561&sudaref=www.baidu.com 2023年1月3日消息 ...
- [转帖]01-rsync备份方式
https://developer.aliyun.com/article/885783?spm=a2c6h.24874632.expert-profile.284.7c46cfe9h5DxWK 简介: ...