使用RabbitMQ和Plone - 芹菜与否?

 霸道Q丫头 发布于 2023-01-04 14:57

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

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

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

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

谢谢你的时间!

1 个回答
  • 首先,问问自己,如果你需要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脚本适配器调用自定义外部方法.

    2023-01-04 14:59 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有