Swoole笔记(二)

简介:

本文示例代码详见:https://github.com/52fhy/swoole_demo

重新打开日志

在1.8.11及之后版本支持重新打开日志:向Server主进程发送SIGRTMIN信号。假设主进程id是3427,那么我们可以:

kill -34 3427

注:SIGRTMIN信号的id是34。通过kill -l查看。

那么如何利用这个特征实现每天自动写入新的日志文件里面呢?

假设日志文件是/log/swoole.log,我们可以在每天0点运行shell命令:

mv /log/swoole.log /log/$(date -d '-1 day' +%y-%m-%d).log
kill -34 $(ps aux|grep swoole_task|grep swoole_task_matser|grep -v grep|awk '{print $2}') # 找到主进程,需要提前命名

我们也可以把master进程的PID写入到文件

$server->set(array(
    'pid_file' => __DIR__.'/server.pid',
));

在Server关闭时自动删除PID文件。此选项在1.9.5或更高版本可用。

信号管理

Swoole支持的信号:

SIGKILL -9 pid 强制杀掉进程
SIGUSR1 -10 master_pid 重启所有worker进程
SIGUSR2 -12 master_pid 重启所有task_worker进程
SIGRTMIN -34 master_pid 重新打开日志(版本1.8.11+)

master_pid代表主进程pid。示例(假设主进程名称是swoole_server,pid是3427):

# 杀掉进程swoole_server
kill -9 $(ps aux|grep swoole_server|grep -v grep|awk '{print $2}')

# 重启swoole_server的worker进程
kill -10 $(ps aux|grep swoole_server|grep -v grep|awk '{print $2}')

# 重新打开日志
kill -34 3427

Task

我们可以在worker进程中投递一个异步任务到task_worker池中。此函数是非阻塞的,执行完毕会立即返回。worker进程可以继续处理新的请求。

通常会把耗时的任务交给task_worker来处理。

我们可以通过如下代码判断是Worker进程还是TaskWorker进程:

function onWorkerStart($serv, $worker_id) {
    if ($worker_id >= $serv->setting['worker_num']) {  //超过worker_num,表示这是一个task进程

    }
}

看一个示例:

<?php
$server = new \swoole_server("127.0.0.1",8088);

$server->set(array(
    'daemonize' => false,
    'reactor_num' => 2,
    'worker_num' => 1,
    'task_worker_num' => 1,
));

$server->on('start', function ($serv){ 
    swoole_set_process_name("swoole_task_matser"); //主进程命名
});

$server->on('connect', function ($serv, $fd){ 
    echo "client connect. fd is {$fd}\n";
});

$server->on('receive', function ($serv, $fd, $from_id, $data){
    
    echo sprintf("onReceive. fd: %d , data: %s\n", $fd, json_encode($data) );
    
    $serv->task(json_encode([
        'fd' => $fd,
        'task_name' => 'send_email',
        'email_content' => $data,
        'email' => 'admin@qq.com'
    ]));
});

$server->on('close', function ($serv, $fd){
    echo "client close. fd is {$fd}\n";
});

$server->on('task', function (swoole_server $serv, $task_id, $from_id,  $data){
    echo $data;
    
    $data = json_decode($data, true);
    $serv->send($data['fd'], "send eamil to {$data['email']}, content is : {$data['email_content']}\n");
    
    //echo 'task finished';
    //return 'task finished';
    $serv->finish('task finished');
});

$server->on('finish', function (swoole_server $serv, $task_id, $data){
    echo 'onFinish:' .$data;
});

$server -> start();

这里新建了一个tcp服务器,参数里设置worker_num进程为1,task_worker_num为1。

配置了task_worker_num参数后将会启用task功能,swoole_server务必要注册onTask/onFinish2个事件回调函数。如果没有注册,服务器程序将无法启动。

onTask回调接收4个参数,分别是serv对象、任务ID、自于哪个worker进程、任务的内容。注意的是,$data必须是字符串。我们可以在worker进程里使用`swoole_server->task
($data)`进行任务投递。

onFinish回调用于将处理结果告知worker进程,此回调必须有,但是否被调用由OnTask决定。在OnTask里使用return或者finish()可以将处理结果发生到onFinish回调,否则onFinish回调是不会被调用的。也就是说:finish()是可选的。如果worker进程不关心任务执行的结果,不需要调用此函数。onFinish回调里的$data同样必须是字符串。

我们新起一个窗口,使用telnet发送消息到服务端进行测试:
client端:

telnet 127.0.0.1 8088
Trying 127.0.0.1...
Connected to 127.0.0.1.

hhh
send eamil to admin@qq.com, content is : hhh

server端:

client connect. fd is 1
onReceive. fd: 1 , data: "hhh\r\n"
{"fd":1,"task_name":"send_email","email_content":"hhh\r\n","email":"admin@qq.com"}
onFinish:task finished

onFinish回调里不使用return或者finish(),我们将看不到server端最后一行输出。

此时服务器进程模型:

pstree -ap | grep swoole
  |   |       `-php,3190 swoole_task.php
  |   |           |-php,3192 swoole_task.php
  |   |           |   |-php,3194 swoole_task.php
  |   |           |   `-php,3195 swoole_task.php

看到两个worker进程,其中一个是worker进程,另外一个是task_worker进程。

定时器

Swoole提供强大的异步毫秒定时器,基于timerfd+epoll实现。主要方法:
1、swoole_timer_tick:周期性定时器,类似于JavaScript里的setInterval()
2、swoole_timer_after:一次性定时器。
3、swoole_timer_clear:清除定时器。

# 周期性定时器
int swoole_timer_tick(int $ms, callable $callback, mixed $user_param);

# 一次性定时器
swoole_timer_after(int $after_time_ms, mixed $callback_function, mixed $user_param);

# 清除定时器
bool swoole_timer_clear(int $timer_id)

# 定时器回调函数
function callbackFunction(int $timer_id, mixed $params = null);

注意:

  • $ms 最大不得超过 86400000。
  • manager进程中不能添加定时器。
  • 建议在WorkerStart回调里写定时器。

定时器示例:

$server->on('WorkerStart', function (\swoole_server $server, $worker_id){
    if ($server->worker_id == 0){//防止重复
        //每隔2000ms触发一次
        swoole_timer_tick(2000, function ($timer_id) {
            echo "tick-2000ms\n";
        });
        
        //3000ms后执行此函数
        swoole_timer_after(3000, function () {
            echo "after 3000ms.\n";
        });
    }
});
相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
分布式计算 资源调度 Hadoop
Hadoop常见错误及解决方案、Permission denied: user=dr.who, access=WRITE, inode=“/“:summer:supergroup:drwxr-xr-x
Hadoop常见错误及解决方案、Permission denied: user=dr.who, access=WRITE, inode=“/“:summer:supergroup:drwxr-xr-x
Hadoop常见错误及解决方案、Permission denied: user=dr.who, access=WRITE, inode=“/“:summer:supergroup:drwxr-xr-x
|
定位技术 开发工具 芯片
HackRF实现ADS-B飞机信号跟踪定位
硬件平台:HackRF One软件平台:MAC运行环境搭建系统平台:OS X 10.11 EI Capitan文章特点:捕捉程序支持HackRF One且基于MAC平台验证通过有效。 1. 原理概述 之所以能够很容易的跟踪飞机,是因为航空CNS(通信导航监视)系统里大量采用非常古老的无线标准.
2976 0
|
缓存 监控 网络协议
|
网络协议 应用服务中间件 开发工具
IM开源项目OpenIM部署文档-从准备工作到nginx配置
IM开源项目OpenIM部署文档-从准备工作到nginx配置 2022-11-14 22:27·OpenIM 一、准备工作 运行环境 linux系统即可, Ubuntu 7.5.0-3ubuntu1~18.04最优 图片视频文件存储 支持cos/MinIO https/wss协议 1. 需申请域名或者子域名(web im端登录注册及im 服务端使用)建议:web.xx.xx 2. 若使用MinIO作为对象存储,建议:storage.xx.xx 3. 管理后台子域名,建议:admin.xx.xx 4. 部署nginx,并配置证书。 离线推送(app被杀死或未启动时推送) 国内申请
1569 0
IM开源项目OpenIM部署文档-从准备工作到nginx配置
|
算法 关系型数据库 MySQL
索引合并机制详解
索引合并机制详解
1351 0
索引合并机制详解
最大最小归一化的demo
最大最小归一化的代码解释 最大最小归一化,顾名思义,就是利用数据列中的最大值和最小值进行标准化处理,标准化后的数值处于[0,1]之间,计算方式为数据与该列的最小值作差,再除以极差。
1059 0
最大最小归一化的demo
|
数据格式
跟着Cell学作图 | 2.柱状图+误差棒+散点+差异显著性检验
这篇2020年发表在cell上关于新冠的组学文章里面有大量的生信内容。今天带大家复现其中的一个Supplemental Figure:带散点的柱状图。
1714 0
跟着Cell学作图 | 2.柱状图+误差棒+散点+差异显著性检验
|
Arthas 监控 Java
Arthas(java 诊断工具):安装和常用命令
Arthas(java 诊断工具):安装和常用命令
Arthas(java 诊断工具):安装和常用命令
|
开发框架 JavaScript 前端开发
Vue 3最新力作!《Vue.js 3企业级应用开发实战》简介
《Vue.js 3企业级应用开发实战》一书由电子工业出版社出版,已经于2022年1月出版上市。近日拿到了样书,第一时间希望与读者朋友们分享下这本书里面的内容。
1283 0
|
编解码 5G
大规模天线理论 | 带你读《大规模天线波束赋形技术原理与设计 》之十一
本章将从信道容量和频谱效率理论入手,给出 大规模天线系统性能分析,从而揭示其性能增益。
大规模天线理论 | 带你读《大规模天线波束赋形技术原理与设计 》之十一