swoole(5)信号监听、热重启
一:信号监听
信号:由用户、系统或者进程发给目标进程的信息,以通知目标进程某个状态的改变或系统异常
信号查看:kill -l
SIGHUP 终止进程 终端线路挂断
SIGINT 终止进程 中断进程
SIGKILL 终止进程 杀死进程
SIGPIPE 终止进程 向一个没有读进程的管道写数据
SIGALARM 终止进程 计时器到时
SIGTERM 终止进程 软件终止信号
SIGSTOP 停止进程 非终端来的停止信号
SIGTSTP 停止进程 终端来的停止信号
SIGCONT 忽略信号 继续执行一个停止的进程
SIGURG 忽略信号 I/O紧急信号
SIGIO 忽略信号 描述符上可以进行I/O
SIGPROF 终止进程 统计分布图用计时器到时
SIGUSR1 终止进程 用户定义信号1
SIGUSR2 终止进程 用户定义信号2
SIGVTALRM 终止进程 虚拟计时器到时
swoole热重启命令:
1、kill -SIGTERM|-15 master_pid 终止Swoole程序,一种优雅的终止信号,会待进程执行完当前程序之后中断,而不是直接干掉进程
2、kill -USR1|-10 master_pid 重启所有的Worker进程
3、kill -USR2|-12 master_pid 重启所有的Task Worker进程
重启子进程、拉起子进程代码:
<?php
class Worker {
//监听socket
protected $socket = NULL;
//连接事件回调
public $onConnect = NULL;
//接收消息事件回调
public $onMessage = NULL;
public $workerNum = 4;
public $addr;
public $worker_pid;
public $master_pid; public function __construct($socket_address) {
$this->addr=$socket_address;
$this->master_pid = posix_getpid();
} //创建子进程
public function fork($worker_num) {
for ($i = 0; $i < $worker_num; $i++) {
$pid = pcntl_fork();
if ($pid < 0) {
exit('创建失败');
} else if ($pid > 0) {
//存储子进程id
$this->worker_pid[]=$pid;
} else {
$this->accept();
exit();
}
}
} public function accept() {
$opts = array(
'socket' => array(
'backlog' => '10240',
),
); $context = stream_context_create($opts); stream_context_set_option($context,'socket','so_reuseport',1); $this->socket = stream_socket_server($this->addr,$error,$errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,$context);
swoole_event_add($this->socket, function ($fd) {
//服务端接收客户端请求
$clientSocket = stream_socket_accept($this->socket);
if (!empty($clientSocket) && is_callable($this->onConnect)) {
call_user_func($this->onConnect, $clientSocket);
}
swoole_event_add($clientSocket, function ($fd) {
$buffer = fread($fd, 65535);
//如果数据为空,或者为false,不是资源类型
if (empty($buffer)) {
if (feof($fd) || !is_resource($fd)) {
//触发关闭事件
fclose($fd);
}
}
if (!empty($buffer) && is_callable($this->onMessage)) {
call_user_func($this->onMessage, $fd, $buffer);
}
});
});
}
/**
* 捕获信号
* 监视worker进程.拉起进程
*/
public function monitorWorkers(){
//注册信号事件回调,是不会自动执行的
pcntl_signal(SIGUSR1, array($this, 'signalHandler'),false); //重启woker进程信号 // pcntl_signal(SIGUSR1,array($this,'signalHandler'),false); //重启worker进程信号
$status = 0;
//回收子进程
while(1){
//reload
// 当发现信号队列,一旦发现有信号就会触发进程绑定事件回调
pcntl_signal_dispatch();
$pid = pcntl_wait($status); //当信号到达之后就会被中断
//ctrl+c
//如果进程不是正常情况下的退出,重启子进程,我想要维持子进程个数
if($pid>1 && $pid != $this->master_pid && !pcntl_wifexited($status)){
$index=array_search($pid,$this->worker_pid);
$this->fork(1);
var_dump('拉起子进程');
unset($this->worker_pid[$index]);
}
pcntl_signal_dispatch();
//进程重启的过程当中会有新的信号过来,如果没有调用pcntl_signal_dispatch,信号不会被处理
}
} public function signalHandler($sigo){
switch ($sigo){
case SIGUSR1:
$this->reload();
echo '收到重启信号';
break;
}
} public function reload(){
foreach($this->worker_pid as $index =>$pid){
posix_kill($pid,SIGKILL);
var_dump("杀掉的子进程$pid");
unset($this->worker_pid[$index]);
$this->fork(1);
}
} public function start() {
$this->fork($this->workerNum);
$this->monitorWorkers(); //监视程序,捕获信号,监视worker进程 }
} $worker = new Worker('tcp://0.0.0.0:9801'); $worker->onConnect = function ($args) {
echo "新的连接来了.{$args}.PHP_EOL";
};
$worker->onMessage = function ($conn, $message) {
// var_dump($conn, $message);
$content = "hello word qwe";
$http_resonse = "HTTP/1.1 200 OK\r\n";
$http_resonse .= "Content-Type: text/html;charset=UTF-8\r\n";
$http_resonse .= "Connection: keep-alive\r\n";
$http_resonse .= "Server: php socket server\r\n";
$http_resonse .= "Content-length: " . strlen($content) . "\r\n\r\n";
$http_resonse .= $content;
fwrite($conn, $http_resonse);
};
$worker->start();
cli运行:

二:inotify热重启
inotify:是linux内核提供的一组系统调用,她可以监控文件系统操作,比如文件或者目录的创建、读取、写入、权限修改、删除等
public function start() {
//获取配置文件
$this->watch();
$this->fork($this->workerNum);
$this->monitorWorkers(); //监视程序,捕获信号,监视worker进程
}
/**
* 文件监视,自动重启
*/
protected function watch(){
$init=inotify_init(); //初始化
$files=get_included_files();
foreach ($files as $file){
inotify_add_watch($init,$file,IN_MODIFY); //监视相关的文件
}
//监听
swoole_event_add($init,function ($fd){
$events=inotify_read($fd);
if(!empty($events)){
posix_kill($this->master_pid,SIGUSR1);
}
});
}
swoole(5)信号监听、热重启的更多相关文章
- swoole多端口监听
今天测试swoole写webserver实现多端口监听.记录下爬过的坑:关于tcp协议监听触发不到receive!!!!! 首先上服务端代码 class Http { /** * 服务实例 * @va ...
- 监听服务器 重启apache
import requests import os import time url = 'http://www.ydyigo.com/findPwd.php' def get_server_statu ...
- Oracle 监听器日志文件过大导致监听异常
Oracle 监听器日志文件过大导致监听异常 db版本:11.2.0.1 os版本:windows2008 现象: 应用异常,无法连接数据库.登陆数据库服务器,查看监听已经断掉.尝试重启监听,重启失败 ...
- java监听事件
2014年2月23日 09:51:54 成功添加了打开官网的事件, 回头研究下,那个打开url的类 java的System.getProperty()方法可以获取的值 ################ ...
- ORACLE的监听日志太大,客户端无法连接
数据库sqlplus能连接,plsql连接失败,也不报错,就定位到了是不是监听出了什么问题,删除监听,重建监听,重启监听,各种尝试都没解决问题. 却是监听日志太大导致的问题,一下是处理步骤: 查看监听 ...
- oracle连接错误:ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务解决
自己的解决办法是,把数据库连接字符串的默认SID_NAME = ORCL改为 sid_name =test(自己安装数据库时候改的名字).即可正常连接. 网上搜罗的其他问题:把监听服务重启下.(自己的 ...
- java 监听控制台输入
分享一下我写的java监听控制台输入并可以给出响应的功能. 很多时候需要监听控制台的输入内容,相当于信号监听,根据输入的内容做出相应的动作,这里给出我的一个简单实现. 要注意的是:监听得到的消息中前后 ...
- libvert开启TCP监听
1.设置libvirtd 编辑/etc/libvirt/libvirtd.conf listen_tls = 0 listen_tcp = 1 auth_tcp="none" tc ...
- 安装完oracle重新启动后报ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务(重启前正常)
安装完oracle重新启动后报ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务(重启前正常) 刚安装完后用plSql登录正常. 在dos命令行下 输入 sqlplus 用户 ...
- Java线程监听,意外退出线程后自动重启
Java线程监听,意外退出线程后自动重启 某日,天朗气清,回公司,未到9点,刷微博,顿觉问题泛滥,惊恐万分! 前一天写了一个微博爬行程序,主要工作原理就是每隔2分钟爬行一次微博,获取某N个关注朋友微博 ...
随机推荐
- Python 潮流周刊#82:美国 CIA 如何使用 Python?(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- 【Rive】Android与Rive交互
1 Android与Rive交互的常用接口 1.1 RiveAnimationView参数 <app.rive.runtime.kotlin.RiveAnimationView android: ...
- JVM简介—1.Java内存区域
大纲 1.运行时数据区的介绍 2.运行时数据区各区域的作用 3.各个版本内存区域的变化 4.直接内存的使用和作用 5.站在线程的角度看Java内存区域 6.深入分析堆和栈的区别 7.方法的出入栈和栈上 ...
- 组件漏洞测试工具---Dependency-Check
目录 文章综述 Dependency-Check简介 工作原理 常用命令 报告解读 使用场景 缺点 文章综述 本文主要介绍Dependency-Check工具的工作原理和使用方法,并提供一个开源方案帮 ...
- 阿里云maven仓库地址的配置
两种配置方式: 1. maven 配置文件配置settings.xml中设置mirror节点 <mirror> <id>nexus-aliyun</id> < ...
- IM跨平台技术学习(四):蘑菇街基于Electron开发IM客户端的技术实践
本文由蘑菇街前端技术团队分享,原题"Electron 从零到一",有修订和改动. 1.引言 本系列文章的前面几篇主要是从Electron技术本身进行了讨论(包括:第1篇初步了解El ...
- 关于vue加element-ui上传文件获取文件的sha256的值
首先使用element的上传文件的组件 安装依赖crypto-js npm i crypto-js <el-upload class="upload-demo" drag : ...
- CDS标准视图:维护通知数据 I_PMNotifMaintenanceData
视图名称:维护通知数据 I_PMNotifMaintenanceData 视图类型:基础视图 视图代码: 点击查看代码 @EndUserText.label: 'Notification Mainte ...
- JavaBean、this:“当前对象的.”、
this:区分类的属性和形参
- Zino pg walkthrough Intermediate
nmap 扫描 发现smba共享文件 ┌──(root㉿kali)-[~] └─# nmap -p- -A 192.168.167.64 Starting Nmap 7.94SVN ( https:/ ...