博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Linux]使用PHP编写Gearman的Worker守护进程
阅读量:4323 次
发布时间:2019-06-06

本文共 2615 字,大约阅读时间需要 8 分钟。

在我之前的文章中,介绍过Gearman的使用。在我的项目中,我使用了PHP来编写一直运行的Worker。如果按照Gearman官方推荐的例子,只是简单的一个循环来等待任务,会有一些问题,包括:1、当代码进行过修改之后,如何让代码的修改生效;2、重启Worker的时候,如何保证当前的任务处理完成才重启。
 
针对这个问题,我考虑了以下的解决方法:
1、每次修改完代码后,Worker需要手工重启(先杀死然后启动)。这个只能解决重新加载配置文件的问题。
2、在Worker中设置,单次任务循环完成后,就对Worker进行重启。这个方案的问题在于消耗比较大。
3、在Worker中添加一个退出函数,如果需要Worker退出的时候,在Client端发送一个优先级比较高的退出调用。这个需要客户端配合,在使用后台类任务时,不太适合。
4、在Worker中检查文件是否发生变化,如果发生了变化,退出并重启自身。
5、为Worker编写信号控制,接受重启指令,类似于 http restart graceful 指令。
 
最后,结合4和5两种方法,可以实现这样一个Daemon,如果配置文件发生了变化,他就会自动重启;如果接受到了用户的 kill  -1 pid 信号,也会重新启动。
 
代码如下:
 
at 2011-12-04$init_md5 = md5_file( 'config.php');// register signal handlerpcntl_signal( SIGALRM, "signal_handler", true );pcntl_signal( SIGHUP, 'signal_handler', TRUE );$job_flag = FALSE; //Job status flag, to justify if the job has been finished$signal_flag = FALSE; //Signal status flag, to justify whether we received the kill -1 signalwhile( 1 ){ $job_flag = FALSE; //Job status flag print "Worker start running ... \n"; sleep(5); print "Worker's task done ... \n"; $flag = TRUE; //Job status flag AutoStart( $signal_flag );}function signal_handler( $signal ) { global $job_flag; global $signal_flag; switch( $signal ){ case SIGQUIT: print date('y-m-d H:i:s', time() ) . " Caught Signal : SIGQUIT - No : $signal \n"; exit(0); break; case SIGSTOP: print date('y-m-d H:i:s', time() ) . " Caught Signal : SIGSTOP - No : $signal \n"; break; case SIGHUP: print date('y-m-d H:i:s', time() ) . " Caught Signal : SIGHUP - No : $signal \n"; if( $flag === TRUE ){ AutoStart( TRUE ); }else{ $signal_flag = TRUE; } break; case SIGALRM: print date('y-m-d H:i:s', time() ) . " Caught Signal : SIGALRM - No : $signal \n"; //pcntl_exec( '/bin/ls' ); pcntl_alarm( 5 ); break; default: break; }}function AutoStart( $signal = FALSE, $filename = 'config.php' ){ global $init_md5; if( $signal || md5_file( $filename ) != $init_md5 ){ print "The config file has been changed, we are going to restart. \n"; $pid = pcntl_fork(); if( $pid == -1 ){ print "Fork error \n"; }else if( $pid > 0 ){ print "Parent exit \n"; exit(0); }else{ $init_md5 = md5_file( $filename ); print "Child continue to run \n"; } }}

  

参考资料:
1、
2、
3、
4、
5、
6、
7、
 
再参考一下下面的片段:
 

  

转载于:https://www.cnblogs.com/yiyide266/p/5538202.html

你可能感兴趣的文章
初识ionic
查看>>
java 中打印调用栈
查看>>
开发 笔记
查看>>
数据挖掘算法比赛 - 简单经验总结
查看>>
生成商户订单号/退款单号
查看>>
使用Android OpenGL ES 2.0绘图之六:响应触摸事件
查看>>
我们过去几年做对了哪些事
查看>>
ubuntu 16.04LTS
查看>>
javascript深入理解js闭包
查看>>
Oracle的安装
查看>>
Android Socket连接PC出错问题及解决
查看>>
Android Studio-—使用OpenCV的配置方法和demo以及开发过程中遇到的问题解决
查看>>
第2天线性表链式存储
查看>>
python自动化测试-D11-学习笔记之一(yaml文件,ddt)
查看>>
mysql存储过程使用游标循环插入数据
查看>>
Ubuntu 12.04 添加新用户并启用root登录
查看>>
20145309信息安全系统设计基础第9周学习总结上
查看>>
c# 字段、属性get set
查看>>
td内容超出隐藏
查看>>
Spring CommonsMultipartResolver 上传文件
查看>>