大多数任务将被定向到单个工人(例如,“将'get_status'作业发送到'system51'”)——这会是一个问题吗?
一点也不。只需为每个工作人员创建一个队列,例如,假设每个节点都侦听一个循环队列default
,每个节点都有自己的队列,以其节点名称命名:
(a)$ celeryd -n a.example.com -Q default,a.example.com
(b)$ celeryd -n b.example.com -Q default,b.example.com
(c)$ celeryd -n c.example.com -Q default,c.example.com
将任务直接路由到节点很简单:
$ get_status.apply_async(args, kwargs, queue="a.example.com")
或通过配置使用Router
:
# Always route "app.get_status" to "a.example.com"
CELERY_ROUTES = {"app.get_status": {"queue": "a.example.com"}}
它是否能够优雅地处理不利的网络条件(例如,连接失效)?
工作人员从代理连接失败中优雅地恢复。(至少来自 RabbitMQ,我不确定所有其他后端,但这很容易测试和修复(您只需将相关异常添加到列表中)
对于客户端,如果连接断开,您可以随时重试发送任务,或者您可以使用 RabbitMQ 设置 HA:http ://www.rabbitmq.com/pacemaker.html
仅当 RabbitMQ 用作后端时,哪些功能才可用?(我宁愿不在现场系统上运行 RabbitMQ)
远程控制命令,仅支持“直接”交换(不支持“主题”或“扇出”)。但这将在Kombu (http://github.com/ask/kombu)中得到支持。
我会认真重新考虑使用 RabbitMQ。为什么你认为它不适合?恕我直言,我不会在其他地方寻找这样的系统(如果系统是瞬态的并且您不需要消息持久性,则可能是 ZeroMQ)。
如果我像我描述的那样使用芹菜,还有其他原因会让我的生活变得困难吗?
从你上面的描述中我想不出任何东西。由于并发模型是多处理的,它确实需要一些内存(我正在努力添加对线程池和事件池的支持,这在某些情况下可能会有所帮助)。
建议 Celery 有点矫枉过正是有道理的,但还有其他原因可以让我的生活更轻松,所以我想考虑一下)
在那种情况下,我认为您轻描淡写地使用了“矫枉过正”这个词。这实际上取决于没有它您需要编写多少代码和测试。我认为改进已经存在的通用解决方案会更好,从理论上讲,它听起来应该适合您的应用程序。