python – 使用RabbitMQ和Plone – 芹菜与否?

我希望我把它发布在正确的地方.

我正在研究RabbitMQ在Plone站点中的潜在用途.我们目前在Plone服务器上的专用工作者客户端上使用Async,但我们正在考虑构建一个专用的RabbitMQ服务器,它将处理所有Plone消息传递和其他活动.

我的具体问题是,使用Celery在Plone中使用RabbitMQ与仅使用RabbitMQ有什么好处?我找到了this plone add-on用于Celery集成,但不确定这是否是最好的路线.我注意到Celery有用于监控队列的Flower工具,这将是一个巨大的优势.

作为一个附带问题,如果您有这种倾向,是否有人有任何关于将RabbitMQ与Plone集成以处理所有这些请求的提示或参考?我一直在做研究,并获得RabbitMQ的一般要点,但我似乎无法与Plone活动建立联系,例如Content Rules和PloneFormGen提交.到目前为止,我看到this add-on我要安装,看看我是否可以搞清楚,但我只是想尽可能得到一点指导.

谢谢你的时间!

最佳答案 首先,问问自己,如果你需要RabbitMQ的功能,或者只是想用Plone在Python中做一些异步任务.

如果你真的不需要RabbitMQ,你可以查看David Glick关于如何将Celery与Plone集成(以及仍然使用RabbitMQ和Celery)的要点:

> https://gist.github.com/davisagli/5824662
> https://gist.github.com/davisagli/5824709

您还可以查看collective.taskqueue(没有Celery和RabbitMQ的简单队列),但它还没有提供任何监控解决方案.

如果你真的需要RabbitMQ,请跳过Celery,然后尝试collective.zamqp.Celery试图成为经纪人,并且会阻止你使用大部分AMQP和RabbitMQ的内置功能.

RabbitMQ附带了很棒的Web管理插件用于监控,还有第三方监控系统的插件(如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>

无法从RestrictedPython直接调用c.zamqp,因此将其集成到PloneFormGen需要自定义操作适配器或从PFG的Python脚本适配器调用自定义外部方法.

点赞