• rabbitmq消息消费




    消费方法


    Basic.Get

    • 每次接收消息必须发送一次请求
    • 有消息可用,RabbitMQ返回Basic.GetOk以及消息
    • 无消息可用,RabbitMQ返回Basic.GetEmpty 应用程序需要评估RPC响应以及是否接收到消息。

    示例程序

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            queue = rabbitpy.Queue(channel, 'test-messages')
            queue.declare()
            while True:
                message = queue.get()
                if message:
                    message.pprint()
                    # 确认消息
                    message.ack()
                    if message.body == 'stop':
                        break
    

    Basic.Consume

    • 消费者可用时,异步方式发送消息
    • 应用程序自动接收消息,直到Basic.Cancel
    • 仍然需要确认消息

    示例程序

    import rabbitpy
    
    for message in rabbitpy.consume('amqp://guest:guest@localhost:5672/%2f',
                                    'test-messages'):
        message.pprint()
        # 消息确认
        message.ack()
    

    消费者标签
    应用程序发出Basic.Comsume时,创建唯一字符串(消费者标签),标识应用程序。RabbitMQ每次都会把该字符串和消息一同发送给应用程序。
    客户端库对消费者标签封装,以确定如何处理消息。开发者不用处理消费者标签。

    示例代码:监听消息直到,收到停止消息

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            for message in rabbitpy.Queue(channel, 'test-messages'):
                message.pprint()
                message.ack()
                if message.body == 'stop':
                    break
    

    对比

    Consume吞吐量更大。Get包含了每条消息的同步通信开销。


    消费性能优化


    1、no-ack

    应用程序发送Basic.Comsume请求时,设置no-ack。表明消费者不进行消费确认。

    示例代码:消费不确认

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            queue = rabbitpy.Queue(channel, 'test-messages')
            for message in queue.consume_messages(no_ack=True):
                message.pprint()
    

    2、预取

    QoS(Quality of service)中,可设置消费者预先接收一定数量的消息。Basic.Qos一般在Basic.Consume之前设置。

    示例程序:指定QoS

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            #预取数为10
            channel.prefetch_count(10)
            for message in rabbitpy.Queue(channel, 'test-messages'):
                message.pprint()
                message.ack()
    

    应用程序不需要确认每条消息,可确认所有以前未读消息。

    示例程序:多消息确认

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            channel.prefetch_count(10)
            for message in rabbitpy.Queue(channel, 'test-messages'):
                message.pprint()
                unacknowledged += 1
                if unacknowledged == 10:
                    # 确认所有未确认消息
                    message.ack(all_previous=True)
                    unacknowledged = 0
    
    

    3、事务

    事务允许消费者应用程序提交和回滚批量操作。不适用QoS时,可以获得轻微的性能提升。


    拒绝消息


    Basic.Reject

    通知rabbitmq无法处理投递的消息(拒绝一个消息),可指示rabbitMQ丢弃消息或使用requeue重发消息。

    示例程序:消息拒绝

    import rabbitpy
    
    for message in rabbitpy.consume('amqp://guest:guest@localhost:5672/%2f',
                                    'test-messages'):
        message.pprint()
        print('Redelivered: %s' % message.redelivered)
        message.reject(True)
    

    Basic.Nack

    同时拒绝多个消息

    死信交换器(DLX)

    创建队列时声明该交换器用于保存被拒绝的消息。队列x-dead-letter-exchange参数(RPC请求)指定死信交换器。

    示例程序:指定死信交换器

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            #死信交换器
            rabbitpy.Exchange(channel, 'rejected-messages').declare()
            queue = rabbitpy.Queue(channel, 'dlx-example',
                                   dead_letter_exchange='rejected-messages')
            queue.declare()
    
    

    控制队列


    临时队列

    自动删除队列
    消费者完成连接和检索消息,所有消费者断开连接时,队列将被删除。

    示例程序:自动删除队列auto_delete=True

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            queue = rabbitpy.Queue(channel, 'ad-example', auto_delete=True)
            queue.declare()
    

    只允许单个消费者
    只有单个消费者能够消费队列中的消息。消费者断开连接后,会自动删除队列。

    示例程序:独占队列exclusive

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            queue = rabbitpy.Queue(channel, 'exclusive-example',
                                   exclusive=True)
            queue.declare()
    

    自动过期队列
    如果一段时间没有使用该队列就删除它,一般用于RPC回复队列。

    示例程序:自动过期队列

    import rabbitpy
    import time
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            queue = rabbitpy.Queue(channel, 'expiring-queue',
                                   arguments={'x-expires': 1000})
            queue.declare()
            messages, consumers = queue.declare(passive=True)
            time.sleep(2)
            try:
                messages, consumers = queue.declare(passive=True)
            except rabbitpy.exceptions.AMQPNotFound:
                print('The queue no longer exists')
    

    永久队列

    队列持久性
    服务器重启后队列仍然存在。
    示例程序:持久队列

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            queue = rabbitpy.Queue(channel, 'durable-queue',
                                   durable=True)
            if queue.declare():
                print('Queue declared')
    

    队列消息自动过期
    同时指定死信交换器和消息TTL,过期消息将成为死信消息。

    示例程序:消息TTL

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            queue = rabbitpy.Queue(channel, 'expiring-msg-queue',
                                   arguments={'x-message-ttl': 1000})
             queue.declare()
    
    

    最大队列长度
    一旦达到最大值,添加新消息时,删除队列前端的消息。声明队列时,如果指定死信交换器,前端移除的消息将成为死信。

    示例程序:最大长度队列

    import rabbitpy
    
    with rabbitpy.Connection() as connection:
        with connection.channel() as channel:
            queue = rabbitpy.Queue(channel, 'max-length-queue',
                                   arguments={'x-max-length': 1000})
            queue.declare()
    
    

    队列设置参数

    参数 说明
    x-dead-letter-exchange 死信交换器,路由不重发且被拒绝的消息
    x-dead-letter-routing-key 死信消息的可选路由键
    x-expires 队列在指定的毫秒数后删除
    x-ha-proxy 创建HA队列
    x-ha-nodes HA队列分布的节点
    x-max-length 队列的最大消息数
    x-message-ttl 毫秒为单位的队列过期时间
    x-max-priority 队列优先级排序
  • 相关阅读:
    .Net Web开发技术栈
    C#foreach原理
    C#位运算符
    python写12306抢票
    java语法学习
    建立个人知识体系
    struts2静态方法和动态方法调用
    springmvc跳转的几种方式
    JDBC驱动程序的四种方式
    eclipse用axis2发布webserver
  • 原文地址:https://www.cnblogs.com/hainingwyx/p/13770050.html
Copyright © 2020-2023  润新知