当前位置: 首页 > 后端技术 > PHP

Swoole笔记(二)

时间:2023-03-30 01:54:01 PHP

本文示例代码详见:https://github.com/52fhy/swoo....重开日志支持1.8.11及以后版本重开日志:发送SIGRTMIN信号给服务器主进程。假设主进程id是3427,那么我们可以:kill-343427注意:SIGRTMIN信号的id是34,通过kill-l查看。那么如何利用这个功能每天自动写入一个新的日志文件呢?假设日志文件为/log/swoole.log,我们可以在每天0:00运行shell命令:mv/log/swoole.log/log/$(date-d'-1day'+%y-%m-%d).logkill-34$(psaux|grepswoole_task|grepswoole_task_matser|grep-vgrep|awk'{print$2}')#找到master进程,需要提前命名。我们也可以将master进程的PID写入文件:$server->set(array('pid_file'=>__DIR__.'/server.pid',));服务器关闭时自动删除PID文件。此选项在1.9.5或更高版本中可用。信号管理Swoole支持信号:SIGKILL-9pid强制杀掉进程SIGUSR1-10master_pid重启所有worker进程SIGUSR2-12master_pid重启所有task_worker进程SIGRTMIN-34master_pid重新开启日志(1.8.11+版本)master_pid代表主进程pid.示例(假设主进程名称为swoole_server,pid为3427):#杀死进程swoole_serverkill-9$(psaux|grepswoole_server|grep-vgrep|awk'{print$2}')#重启swoole_server的worker进程kill-10$(psaux|grepswoole_server|grep-vgrep|awk'{print$2}')#reopenthelogkill-343427Task我们可以将worker进程中的一个异步任务post到task_worker池中。该函数是非阻塞的,执行后立即返回。工作进程可以继续处理新的请求。通常比较耗时的任务交给task_worker处理。我们可以通过下面的代码判断是Worker进程还是TaskWorker进程:表示这是一个任务进程}}看一个例子: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"clientconnect.fdis{$fd}\n";});$server->on('receive',function($serv,$fd,$from_id,$data){echosprintf("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"客户端关闭。fd为{$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'],"发送电子邮件至{$data['email']},内容为:{$data['email_content']}\n");//echo'任务完成';//return'任务完成';$serv->finish('任务完成');});$server->on('完成',function(swoole_server$serv,$task_id,$data){echo'onFinish:'.$data;});$server->start();这里新建了一个tcpserver,参数中设置worker_num进程为1,task_worker_num设置为1.task_worker_num参数配置后,任务会启用函数,swoole_server必须注册onTask/onFinish2个事件回调函数,如果不注册,server程序将不会启动,onTask回调接收4个参数,分别是serv对象,taskID,来自哪个worker进程,以及task的内容。注意最重要的是$data必须是字符串,我们c在工作进程中使用swoole_server->task($data)来传递任务。onFinish回调用于通知工作进程处理结果。这个回调必须存在,但是是否被调用是由OnTask决定的。在OnTask中使用return或finish()可以将处理结果发送给onFinish回调,否则不会调用onFinish回调。也就是说:finish()是可选的。如果工作进程不关心任务执行的结果,则不需要调用该函数。onFinish回调中的$data也必须是一个字符串。我们新建一个窗口,使用telnet向服务器发送消息进行测试:client:telnet127.0.0.18088Trying127.0.0.1...Connectedto127.0.0.1.hhhsendeamiltoadmin@qq.com,contentis:hhhserver:clientconnect.fd为1onReceive.fd:1,data:"hhh\r\n"{"fd":1,"task_name":"send_email","email_content":"hhh\r\n","email":"admin@qq.com"}onFinish:taskfinishedonFinish回调没有使用return或finish(),我们将看不到服务器端的最后一行输出。此时服务器进程模型:pstree-ap|grepswoole||`-php,3190swoole_task.php|||-php,3192swoole_task.php||||-php,3194swoole_task.php|||`-php,3195swoole_task.php看到两个worker进程,一个是worker进程,一个是task_worker进程。TimerSwoole提供了一个强大的异步毫秒定时器,基于timerfd+epoll。主要方法:1.swoole_timer_tick:周期性定时器,类似于JavaScript中的setInterval()。2.swoole_timer_after:一次性定时器。3.swoole_timer_clear:清除定时器。#周期定时器intswoole_timer_tick(int$ms,callable$callback,mixed$user_param);#一次性定时器swoole_timer_after(int$after_time_ms,mixed$callback_function,mixed$user_param);#清除定时器boolswoole_timer_clear(int$timer_id)#定时器回调函数functioncallbackFunction(int$timer_id,mixed$params=null);注意:$ms最多不能超过86400000。管理器进程中不能添加定时器。建议在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"3000ms后.\n";});}});