排队系统 - 启动多个员工的好方法是什么?

时间:2009-02-08 21:51:50

标签: queue message-queue worker-process gearman amazon-sqs

  • 如何为面向队列的系统设置一个或多个工作脚本?
  • 如何安排启动 - 并在必要时重新启动 - 工作人员脚本? (我正在考虑使用init.d /,基于Ruby的'上帝',DJB的Daemontools等工具)

我正在开发一个异步队列/工作系统,在这种情况下使用PHP& BeanstalkdD(虽然实际的语言和守护进程并不重要)。任务本身并不太难 - 将带有命令和参数的数组编码到JSON中,以便通过Beanstalkd守护程序进行传输,在工作脚本中将它们拾取以根据需要对其进行操作。

还有许多其他类似的队列/工作人员设置,例如StarlingGearmanAmazon's SQS以及其他更多'企业'导向系统,如IBM的MQ和RabbitMQ。如果你运行像Gearman或SQS这样的东西 - 如何启动和控制工作池?问题出在最初的工人启动上,然后能够添加额外的额外工作人员,随意关闭它们(虽然我可以通过队列发送消息来关闭它们 - 只要一些'观察者'不会自动关闭它们重启它们)。这不是一个PHP问题,它是关于设置一个或多个进程在启动时运行的直接Unix进程,或者向池中添加更多工作程序。

已经存在bash script to loop a script - 这会调用PHP脚本,然后从队列中收集并运行任务,偶尔退出以便能够自我清理(它也可以在失败时暂停几秒钟,或者通过计划的活动)。这样可以正常工作,并且在此基础上构建工作流程并不会非常困难。

获得一个好的工作者控制器系统是关于灵活性,在机器启动时自动启动一个或两个,并且能够在队列繁忙时从命令行添加更多,在不再需要时关闭额外的东西。

4 个答案:

答案 0 :(得分:4)

我一直在帮助一个正在开发项目的朋友,该项目涉及一个基于Gearman的队列,该队列将各种异步作业分配给多个服务器池上的各种PHP和C守护进程。

由于/etc/init.d/中的简单shell脚本和以下命令,工作人员的行为与经典的unix / linux守护进程相似;

invoke-rc.d myWorker start|stop|restart|reload

这种机制简单而有效。由于它依赖于标准的Linux功能,即使对应用程序知识有限的人也可以启动守护程序或停止守护程序,如果他们知道它是如何被称为系统的(在上例中也称为“myWorker”)。

这种机制的另一个优点是它使您的工作人员池管理变得容易。您的计算机上可以有10个守护进程(myWorker1,myWorker2,...),并根据队列长度让“worker manager”启动或停止它们。由于这些命令可以通过ssh运行,因此您可以轻松管理多个服务器。

这个解决方案可能听起来很便宜,但是如果你使用编码良好的守护进程和可靠的管理脚本来构建它,我不明白为什么它对于任何平均值来说都不如大块解决方案效率低(如“非关键” “)项目。

答案 1 :(得分:0)

像WebSphere MQ或MSMQ这样的真实消息队列中间件提供“触发器”,其中作为MQM一部分的服务将在将新消息放入队列时启动工作程序。

AFAIK,没有“网络服务”排队系统可以通过野兽的性质来做到这一点。但是我只是很努力地看待SQS。在那里你必须轮询队列,在亚马逊的情况下,过于急切的轮询会花费你一些真正的$$。

答案 2 :(得分:0)

我最近一直在研究这样一个工具。它还没有完全完成(我认为它应该花费更多的时间才能达到我可以称之为1.0的东西)并且显然尚未准备好进行生产,但重要部分已经编码。任何人都可以在这里查看代码:https://gitorious.org/workers_pool

答案 3 :(得分:0)

Supervisor是一款不错的监控工具。它包括一个Web UI,您可以在其中监视和管理工作人员。

这是一个简单的工作人员配置文件。

[program:demo]
command=php worker.php ; php command to run worker file
numprocs=2 ; number of processes
process_name=%(program_name)s_%(process_num)03d ; unique name for each process if numprocs > 1
directory=/var/www/demo/ ; directory containing worker file
stdout_logfile=/var/www/demo/worker.log ; log file location
autostart=true ; auto start program when supervisor starts
autorestart=true ; auto restart program if it exits