管理Gearman

赞助

如果你觉得我写得还行,并且愿意付费,那么我会更有动力写下去。

通常,Gearman被用来分发任务,以便实现非堵塞。下面捋捋如何管理Gearman。

说明:请自行安装好Gearman和PHP PECL Gearman。

准备

我们先来创建一个Worker,实现一个简单的显示功能:

<?php

$worker= new GearmanWorker();

$worker->addServer('127.0.0.1', '4730');

$worker->addFunction('echo', 'my_echo_function');

while ($worker->work());

function my_echo_function($job) {
    return $job->workload();
}

?>

然后我们运行它:

shell> php /path/to/worker/file

可能你已经注意到,代码里有一个死循环,是不是需要Sleep一下?让我们监测看看:

shell> strace -r php /path/to/worker/file
0.000099 poll([{fd=3, events=POLLIN}], 1, 10000) = 0 (Timeout)
10.006522 write(3, "\0REQ\0\0\0\t\0\0\0\0", 12) = 12

可见PHP PECL Gearman内部已经做了休息十秒的设置,我们就不用杞人忧天了。

接下来我们以Shell为Client来调用一下:

shell> gearman -f echo "hello, world."

到这里,准备工作基本就齐活儿了,相信大家已经对Gearman有了一个初步的认识。

管理

出于效率的考虑,我们往往会启动很多个Worker,但具体应该启动多少个呢?十个还是一百个?少了不够,多了浪费,到底应该如何度量呢?

其实Gearman本身已经提供了相应的命令供我们查看状态:

shell> (echo status; sleep 0.1) | nc 127.0.0.1 4730

命令的结果会分为四列,它们的含义从左到右依次是:

  1. Function name: A string denoting the name of the function of the job
  2. Number in queue: A positive integer indicating the total number of jobs for this function in the queue. This includes currently running ones as well (next column)
  3. Number of jobs running: A positive integer showing how many jobs of this function are currently running
  4. Number of capable workers: A positive integer denoting the maximum possible count of workers that could be doing this job. Though they may not all be working on it due to other tasks holding them busy.

从这些信息可以推断出:如果系统比较繁忙的话,Number of jobs running的数值会接近Number of capable workers;Number in queue可能会大于Number of capable workers。此时我们应该增加Worker的数量,反之则应该考虑减少Worker的数量。

另外,推荐大家结合使用watch命令来监控Gearman的状态,这样更直观一些:

shell> watch -n 1 "(echo status; sleep 0.1) | nc 127.0.0.1 4730"

实际应用中,还有很多特殊情况需要考虑,比如说:程序代码更新后,如何避免手动重启Worker?还需要注意的是Worker长时间运行,一旦意外中断或者内存泄漏怎么办?通常这类进程控制问题用Supervisor都可以轻松搞定,有兴趣的读者自己看看吧。此外网络上还有一些不错的工具可以玩玩,比如:GearmanManagerGearman-Monitor

 

管理Gearman》上有17条评论

    • 囧,我一般是工作中遇到什么问题就写什么文章,最近ngx_lua很稳定。

  1. 感谢分享,有什么好的mysql数据转移到mongodb的工具没有推荐一下。谢谢。

  2. 你好老王,可否详细解释下gearman中代码更新避免worker的手动重启的方法?另外worker长时间运行的时候产生的问题如何解决?谢谢

    • 比如你可以通过CRON定期重启Worker,这样代码更新问题,长时间运行的意外中断或者内存泄漏问题,就都解决了。

  3. 我使用gearman实现有些复杂的mysql操作,有时候会出现:Warning: MySQL server has gone away的错误提示,我使用的是PHP语言,发现在执行完类中的方法的时候并没有调用__destruct方法来回收资源,除非这个进程被杀死,否则一直处于执行状态,后来我在方法执行完后主动释放资源。现在也是使用的cron每小时重启一次服务,但总觉得这不是完美的解决办法,请问还有其它的方法解决意外中断,以及内存泄漏的问题吗?
    另外我觉得老王可否在回复的时候加上一个邮件提醒的功能呢?:)

    • 因为Worker本来就是长时间运行的,所以你描述的现象是正常的。除了CRON的方法,你还可以使用类似最大执行次数的方法:比如说,一个Worker最多服务一百个请求,达到阈值就自动退出,并启动一个全新的Worker。

      BTW:通常没几个人留言,邮件提醒就算了。

  4. HI,博主,有没有碰到job server不响应的情况?运行一段时间就挂掉了

  5. 大神博主,我新手用Gearman遇到问题想请教了一下。client里能否根据一个任务的返回结果再重复执行这个任务或者启动另一任务,不知道怎么写。另外就是在框架比如Yii框架里边使用Gearman是不是不合适,执行函数要进行很多增删改查,都是在框架里面写好了的,不用单独拿到一文件里再写一遍吧,跟框架结合不起来,很是纠结,希望能得到大神指点!谢谢。

  6. Pingback引用通告: php安装gearman扩展实现异步分步式任务 | 小喵爱你

  7. Pingback引用通告: php安装gearman扩展实现异步分步式任务

  8. Pingback引用通告: redis作为mysql的缓存服务器(读写分离) | zzQ的博客

  9. 遇到这样一个现象,还没搞明白原因:job server 中有 task 排队,而 woker 也在空闲,一段时间后才分发调度上,不知道是否有遇到过?

发表评论

电子邮件地址不会被公开。 必填项已用*标注