消息队列-RabbitMQ

1 篇文章 0 订阅
1 篇文章 0 订阅

文章目录


消息持久化存储
消息队列服务器停止会导致消息丢失, 为避免此类情况, 可使用消息持久化存储.
由生产者和消费者共同在代码中声明:

channel.queue_declare(queue='hello', durable=True)

消息在发布时还需标记为持久化:

channel.basic_publish(exchange='',
                      routing_key="task_queue",
                      body=message,
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # 2 for "persistent", 1 for "transient"
                      ))

消息的properties可参见:
添加链接描述
AMQP 0-9-1协议预先定义了一组与消息相关的14个属性。除下列情况外,大部分很少使用:

  • delivery_mode:将消息标记为持久化(值为2)或瞬态(任何其他值)。您可能还记得第二个教程中的这个属性。
  • content_type:用于描述编码的mime类型。例如,对于经常使用的JSON编码,最好将此属性设置为:application/ JSON。
  • reply_to:通常用于命名回调队列。
  • correlation_id:用于将RPC响应与请求关联起来

消息确认的重要性
消费者如不发送ACK确认, 消息会一直在队列之中. 当消费者退出时, 消息会被重新传递. 同时RabbitMQ会因为发布消息的增加而逐渐耗尽资源.
在这里插入图片描述
ACK确认由消费者注册时指定, 有2种方式:

  1. 自动确认(不推荐)
channel.basic_consume("hello", callback, auto_ack=True)

此种方式下, 消费者中途退出会导致消息丢失, 不会重传. 因而不建议采用此种方式

  1. 非自动确认(推荐)
def callback(ch, method, properties, body):
    print(f"[x] Received {body}")
    for _ in range(body.count(b'.')):
        time.sleep(1)
    print(" [x] Done")
    ch.basic_ack(delivery_tag=method.delivery_tag) # 发送ACK确认
channel.basic_consume("hello", callback, auto_ack=False) # 非自动确认

消费者注册时auto_ack为False, 同时回调函数中调用ch.basic_ack()发送确认.
此种方式消费者中途退出时, 所有未确认消息都会发送给其他消费者处理.

消息分配
默认情况下服务器会一次将所有消息平均发送个各个消费者, 而不确认消息负荷是否平均.
消费者可要求服务器一次只发送一条消息, 这样可达到负荷均衡:

def callback(ch, method, properties, body):
    print(f"[x] Received {body}")
    for _ in range(body.count(b'.')):
        time.sleep(1)
    print(" [x] Done")
    ch.basic_ack(delivery_tag=method.delivery_tag) # 发送ACK确认
    
channel.basic_qos(prefetch_count=1)  # 一次只向消费者发送一条消息
channel.basic_consume("hello", callback, auto_ack=False)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

交换器Exchange–fanout方式
实际上生产者是向交换器Exchange发送消息, 由exchange将消息推送到绑定的队列中. Exchange的类型有:direct, topic, headers 和 fanout, 其中fanout是广播方式.
广播方式的示例代码:
生产者:

#!/usr/bin/env python
import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
# 声明exchange(exchange与队列的绑定由消费者定义)
channel.exchange_declare(exchange='logs',
                         exchange_type='fanout') 

message = ' '.join(sys.argv[1:]) or "info: Hello World!"
channel.basic_publish(exchange='logs',
                      routing_key='',
                      body=message)
print(" [x] Sent %r" % message)
connection.close()

消费者:

#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
# 声明exchange
channel.exchange_declare(exchange='logs',
                         exchange_type='fanout')
# 声明一个随机队列
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue # 获得队列名
# 绑定exchange与队列
channel.queue_bind(exchange='logs',
                   queue=queue_name)

print(' [*] Waiting for logs. To exit press CTRL+C')

def callback(ch, method, properties, body):
    print(" [x] %r" % body)

channel.basic_consume(callback,
                      queue=queue_name,
                      no_ack=True)

channel.start_consuming()

广播型exchange:

  1. 声明exchange(生产者与消费者)
  2. 声明队列(消费者)
  3. 绑定exchange与队列(消费者)

交换器–direct方式和路由键routing_key
直接交换背后的路由算法很简单——消息转到队列,其绑定键与消息的路由键完全匹配(一个交换器可绑定多个路由键). 它们的绑定由消费者完成:

channel.queue_bind(exchange=exchange_name,
                   queue=queue_name,
                   routing_key='black')

交换器–topic方式
可基于多个标准进行路由.
主题为由点分隔的单词列表, 由参数routing_key指定, 有以下规则:

  • *(星号)只能代替一个单词。
  • #(哈希)可以替代0个或多个单词。
    在这里插入图片描述
    使用RPC服务器
    使用RPC服务器进行耗时计算, 由生产者在properties属性中指定回调队列(reply_to参数)和请求id(correlation_id参数)
    在这里插入图片描述
    当客户端启动时,它会创建一个匿名排他回调队列。
    对于RPC请求,客户端发送具有两个属性的消息:reply_to(设置为回调队列)和correlation_id(设置为每个请求的唯一值)。
    请求被发送到rpc_queue队列。

RPC工作人员(又名:服务器)正在等待该队列上的请求。当出现请求时,它会执行任务并使用reply_to字段中的队列将结果发送回客户机。

客户机等待回调队列上的数据。当消息出现时,它检查correlation_id属性。如果与请求中的值匹配,则返回对应用程序的响应。
详见:添加链接描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值