[Linux]使用PHP编写Gearman的Worker守护进程

在我之前的文章中,介绍过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 信号,也会重新启动。

代码如下:

<?php

declare( ticks = 1 );

// This case will check the config file regularly, if the config file changed, it will restart it self

// If you want to restart the daemon gracefully, give it a HUP signal

// by shiqiang<[email protected]> at 2011-12-04

$init_md5 = md5_file( ‘config.php‘);

// register signal handler

pcntl_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 signal

while( 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、PHP-Daemon

2、IBM Developers 系统调用跟我学

3、如何用PHP编写Daemon Process

4、Function exit

5、PHPDaemon

6、Stoping Gearman worker nicely

7、Doing the worker elsewhere

再参考一下下面的片段:

<?php

function handle_http_request($address, $port){
	$max_backlog = 16;
	$res_content = "HTTP/1.1 200 OK \n".
				   "Content-Length: 15 \n".
				   "Content-Type: text/plain; charset=UTF-8 \n".
				   "PHP HTTP Server Hello World!!";
	$res_len = strlen($res_content);

	//Create, bind and listen to socket
	if(($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE){
		echo "Create socket failed!\n";
		exit;
	}

	if((socket_bind($socket, $address, $port)) === FALSE)
	{
		echo "Bind socket failed!\n";
		exit;
	}

	if((socket_listen($socket, $max_backlog)) === FALSE)
	{
	echo "Listen to socket failed!\n";
	exit;
	}

	//loop
	while (true) {
		if( ($accept_socket = socket_accept($socket)) === FALSE ){
			continue;
		}else{
			socket_write($accept_socket, $res_content, $res_len);
			socket_close($accept_socket);
		}
	}

}

//Run as daemon process.
function run(){

	if(($pid1 = pcntl_fork()) === 0){

		posix_setsid();//Set first child process as the session leader.

		if(($pid2 = pcntl_fork()) === 0){
			handle_http_request(‘192.168.255.131‘, 10101);
		}else{
			exit;
		}
	}else{
		pcntl_wait($status);
	}
}

run();
?>

  

时间: 2024-10-02 20:34:25

[Linux]使用PHP编写Gearman的Worker守护进程的相关文章

编写Linux/Unix守护进程

原文: http://www.cnblogs.com/haimingwey/archive/2012/04/25/2470190.html 守护进程在Linux/Unix系统中有着广泛的应用.有时,开发人员也想把自己的程序变成守护进程.在创建一个守护进程的时候,要接触到子进程.进程组.会晤期.信号机制.文件.目录和控制终端等多个概念.因此守护进程还是比较复杂的,在这里详细地讨论Linux/Unix的守护进程的编写,总结出八条经验,并给出应用范例. 编程要点 1.屏蔽一些有关控制终端操作的信号.防

Linux系统编程之--守护进程的创建和详解【转】

本文转载自:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务.Linux系统的大多数服务器就是通过守护进程实现的.常见的守护进程包括系统日志进程syslogd. web服务器httpd.邮件服务器sendmail和数据库服务器

创建守护进程步骤与setsid() -- linux deamon进程

原创:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务.Linux系统的大多数服务器就是通过守护进程实现的.常见的守护进程包括系统日志进程syslogd. web服务器httpd.邮件服务器sendmail和数据库服务器mys

Linux守护进程详解(init.d和xinetd)

一 Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程来执行的.守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.他们常常在系统引导装入时启动,在系统关闭时终止.linux系统有很多守护进程,大多数服务器都是用守护进程实现的.同时,守护进程完成许多系统任务,比如,作 业规划进程crond.打印进程lqd等.有些书籍

Linux守护进程(init.d和xinetd)

一 Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台 的守护进程来执行的.守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.他们常常在系统引导装入时启 动,在系统关闭时终止.linux系统有很多守护进程,大多数服务器都是用守护进程实现的.同时,守护进程完成许多系统任务,比如,作 业规划进程crond.打印进程lqd等.有些

深入理解Linux操作系统守护进程的意义

Linux服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程(daemons)来执行的.守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.他们常常在系统引导装入时启动,在系统关闭时终止.linux系统有很多守护进程,大多数服务器都是用守护进程实现的.同时,守护进程完成许多系统任务,比如,作业规划进程crond.打印进程lqd等.有些书籍和资料也把

linux的守护进程init.d和xinetd.d

Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程来执行的.守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.他们常常在系统引导装入时启动,在系统关闭时终止.linux系统有很多守护进程,大多数服务器都是用守护进程实现的.同时,守护进程完成许多系统任务,比如,作 业规划进程crond.打印进程lqd等.有些书籍和资料也把守护进程称作:

守护进程详解及创建,daemon()使用

一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而 且提供某种服务,不是对整个系统就是对某个用户程序提供服务.Linux系统的大多数服务器就是通过守护进程实现的.常见的守护进程包括系统日志进程 syslogd. web服务器httpd.邮件服务器sendmail和数据库服务器mysqld等. 守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行.守护进

简单实现一个守护进程(Daemon)

学习进程就不得不提到一个运行在后台的特殊进程--守护进程.(也称精灵进程).Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互.其它进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着而我们就将这种进程称为守护进程. 守护进程独立于控制终端并周期性的执行某种任务或者等待处理某些发生的事件.守护进程是一种很有用的进程.Linux的大多数服务器就是用1守护进程实现的,比如,Internet服务