我有一个 Gearman 队列,它通过多个工作人员处理一些用户特定的数据。我不希望特定用户一次占用多个工人。
假设我有一个名为 process_user_data() 的队列,我运行 4 个工人 W1、W2、W3、W4 当用户 ID 1 提交 10 个作业时,我只希望 W1 处理它。W2-W4 不应该选择工作。
这在齿轮人中可以吗?
没有 Gearman 本身不支持这一点。我相信最简单的方法是为函数添加前缀/后缀以指示它们所属的用户。例如:用户 1 的工作应该提交给process_data_1()
,并且工人 1 会连接到那个而不是通用的process_data()
. 在内部,worker 仍然可以拥有相同的代码库,因为这只是与 Gearman 服务器挂钩的问题(您可以在通过命令行参数启动 worker 时对其进行管理):
class Worker
public function __construct() {
$this->user = argv[1];
$this->worker = new GearmanWorker();
$this->worker->addServer();
$this->worker->addFunction("process_data_" . $this->user, array($this, 'process_data'));
}
public function process_data() {
//work code
}
}
如果工作人员在不同的服务器上,这很容易 - 只是不要GearmanClient->addServer()
在您的客户端中声明它们。如果在同一台服务器上,我想你可以在单台机器上运行多个 gearmand 实例,在一系列端口上。然后,您可以addServer(host, port)
有选择地声明哪些“组”应该有机会获得您即将添加的工作/任务。
如果这对您来说太麻烦了,那么您可能需要选择不同的排队系统。我似乎记得读过 Gearman 不允许基于作业类型的过滤,但恐怕我没有参考。也许看看 RabbitMQ 或 BeanStalk?