首先,问问自己,是否需要 RabbitMQ 的功能,或者只是想用 Plone 在 Python 中做一些异步任务。
如果您真的不需要 RabbitMQ,您可以查看 David Glick 关于如何将 Celery 与 Plone 集成的要点(并且仍然将 RabbitMQ 与 Celery 一起使用):
您也可以查看collective.taskqueue(没有 Celery 和 RabbitMQ 的简单队列),但它还没有提供任何监控解决方案。
如果你真的需要 RabbitMQ,跳过 Celery,试试collective.zamqp。 Celery 试图自己成为代理,并且会阻止您使用大多数 AMQP 和 RabbitMQ 的内置功能。
RabbitMQ 附带用于监控的出色 Web 管理插件,还有用于 3rd 方监控系统(如 Zenoss)的插件。
很抱歉 collective.zamqp 仍然缺少叙述性文档,但您可以查看 collective.zamqpdemo 以获取其配置和使用的各种示例。
简而言之,c.zamqp 允许您根据生产者和消费者定义配置代理使用:
from five import grok
from zope.interface import Interface
from collective.zamqp.producer import Producer
from collective.zamqp.consumer import Consumer
class CreateItemProducer(Producer):
"""Produces item creation requests"""
grok.name("amqpdemo.create") # is also used as default routing key
connection_id = "superuser"
serializer = "msgpack"
queue = "amqpdemo.create"
durable = False
class ICreateItemMessage(Interface):
"""Marker interface for item creation message"""
class CreateItemConsumer(Consumer):
"""Consumes item creation messages"""
grok.name("amqpdemo.create") # is also used as the queue name
connection_id = "superuser"
marker = ICreateItemMessage
durable = False
通过事务绑定生产者发布消息(仅在事务成功后发布消息):
import uuid
from zope.component import getUtility
from collective.zamqp.interfaces import IProducer
producer = getUtility(IProducer, name="amqpdemo.create")
producer._register() # register to bound to successful transaction
message = {"title": u"My title"}
producer.publish(message)
并在熟悉的内容事件处理程序环境中使用消息:
from zope.component.hooks import getSite
from collective.zamqp.interfaces import IMessageArrivedEvent
from plone.dexterity.utils import createContentInContainer
@grok.subscribe(ICreateItemMessage, IMessageArrivedEvent)
def createItem(message, event):
"""Consume item creation message"""
portal = getSite()
obj = createContentInContainer(
portal, "Document", checkConstraints=True, **message.body)
message.ack()
最后,它将代理连接配置与代码解耦,实际连接参数可以在 buildout.cfg 中定义(允许所需数量的消费实例):
[instance]
recipe = plone.recipe.zope2instance
...
zope-conf-additional =
%import collective.zamqp
<amqp-broker-connection>
connection_id superuser
heartbeat 120
# These are defaults, but can be defined when required:
# hostname localhost
# virtual_host /
# username guest
# password guest
</amqp-broker-connection>
<amqp-consuming-server>
connection_id superuser
site_id Plone
user_id admin
vhm_method_prefix /VirtualHostBase/https/example.com:443/Plone/VirtualHostRoot
</amqp-consuming-server>
c.zamqp 不能直接从 RestrictedPython 调用,因此将其集成到 PloneFormGen 需要自定义操作适配器或自定义外部方法,以便从 PFG 的 Python 脚本适配器调用。