RabbitMQ 入门

rabbimq 常用架构

 

 

 exchange 3种模式

direct: 一对一 ,一个生产者 一个消费者,标准队列
fanout:一对多,一个生产者多个消费者,并行多处理时常用
topic:多对一,多个交换机到一个队列上,配合routting_key,可将指定类型发送到指定队列

信道(建立通道)、交换机(选择连接类型,选择队列)、路由键routing_key、队列放在一起用

 

Rabbitmq 支持持久化 队列要先注册进路由器 队列要先注册进路由器
A 可以开启消息事务,半消息。对于消费者不可见,可以回退。分布式的事务管理
实时性不搞的情况下,尽量等一会
B 生产者发的消息 消费者要确认,可通过序号检查的方式可以知道消息丢失了
C 至多一次的策略。消息最多呗送达一次。至少一次,保证消息呗接收一次。恰好一次,
解决方案:幂等性-, db非重复行,主键唯一约束

 

示例代码

# demo1 
# publisher
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pika


# 生产者
# 用户名密码, 不同业务分配不同的账号密码
credential = pika.PlainCredentials('guest', 'guest')

# 虚拟队列需指定参数virtual_host,
parameters = pika.ConnectionParameters(host='192.168.56.33',
                                       port=5672,
                                       virtual_host='/',
                                       credentials=credential)

# 阻塞方法
connection = pika.BlockingConnection(parameters)

# 建立信道
channel = connection.channel()

# 建立队列,若不存在会自动创建, durable=True 时队列有持久化功能
channel.queue_declare(queue='direct_demo', durable=False)

# exchange指定交换机,routing_key指定队列名
channel.basic_publish(exchange='', routing_key='direct_demo',
                      body='send message to rabbitmq')

# 关闭与rabbitmq server的连接
connection.close()

# subscribe
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pika

# 消费者
# 用户名密码, 不同业务分配不同的账号密码
credential = pika.PlainCredentials('guest', 'guest')

# 虚拟队列需指定参数virtual_host,
parameters = pika.ConnectionParameters(host='192.168.56.33',
                                       port=5672,
                                       virtual_host='/',
                                       credentials=credential)

# 阻塞方法
connection = pika.BlockingConnection(parameters)

# 建立信道
channel = connection.channel()

# 建立队列,若不存在会自动创建, durable=True 时队列有持久化功能
channel.queue_declare(queue='direct_demo', durable=False)

# 定义一个回调函数来处理消息队列中的消息
def callback(ch, method, properties, body):
    # 手动发送消息 ch.basic_ack(delivery_tag=method.delivery_tag)
    print(body.decode())

# 消费者使用队列和回调函数处理消息
channel.basic_consume('direct_demo', on_message_callback=callback)

# 开始接受消息,进入阻塞状态
channel.start_consuming()


##  demo2  publisher
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pika

# 生产者
# 用户名密码, 不同业务分配不同的账号密码
credential = pika.PlainCredentials('guest', 'guest')

# 虚拟队列需指定参数virtual_host,
parameters = pika.ConnectionParameters(host='192.168.56.33',
                                       port=5672,
                                       virtual_host='/',
                                       credentials=credential)

# 阻塞方法
connection = pika.BlockingConnection(parameters)

# 建立信道
channel = connection.channel()

# 建立队列,若不存在会自动创建, durable=True 时队列有持久化功能
channel.queue_declare(queue='task_queue', durable=True)

# exchange指定交换机,routing_key指定队列名
message = 'send message to task_queue'
channel.basic_publish(exchange='', routing_key='task_queue',
                      body=message,
                      properties=pika.BasicProperties(
                          delivery_mode = 2,  # 消息持久化
                      ))

# 关闭与rabbitmq server的连接
connection.close()

# sub
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pika
import time

# 消费者
# 用户名密码, 不同业务分配不同的账号密码
credential = pika.PlainCredentials('guest', 'guest')

# 虚拟队列需指定参数virtual_host,
parameters = pika.ConnectionParameters(host='192.168.56.33',
                                       port=5672,
                                       virtual_host='/',
                                       credentials=credential)

# 阻塞方法
connection = pika.BlockingConnection(parameters)

# 建立信道
channel = connection.channel()

# 建立队列,若不存在会自动创建, durable=True 时队列有持久化功能
channel.queue_declare(queue='task_queue', durable=True)

# 定义一个回调函数来处理消息队列中的消息
def callback(ch, method, properties, body):
    time.sleep(1)
    # 手动发送消息 ch.basic_ack(delivery_tag=method.delivery_tag)
    print(body.decode())
    ch.basic_ack(delivery_tag=method.delivery_tag)

# 如果该消费者的channel上未确认的消息数叨叨了prefetch_count数,则不向该消费者发送消息
channel.basic_qos(prefetch_count=1)

# 消费者使用队列和回调函数处理消息
channel.basic_consume('task_queue', callback)

# 开始接受消息,进入阻塞状态
channel.start_consuming()

# demo3 publisher
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pika

# 生产者
# 用户名密码, 不同业务分配不同的账号密码
credential = pika.PlainCredentials('guest', 'guest')

# 虚拟队列需指定参数virtual_host,
parameters = pika.ConnectionParameters(host='192.168.56.33',
                                       port=5672,
                                       virtual_host='/',
                                       credentials=credential)

# 阻塞方法
connection = pika.BlockingConnection(parameters)

# 建立信道
channel = connection.channel()

# 建立队列,若不存在会自动创建, durable=True 时队列有持久化功能
channel.exchange_declare(exchange='logs',
                      exchange_type='fanout')  # 默认是derict

# exchange指定交换机,routing_key指定队列名
message = 'send message to task_queue'
channel.basic_publish(exchange='logs',
                      routing_key='',
                      body=message,
                      )

# 关闭与rabbitmq server的连接
connection.close()

# sub
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pika
import time

# 消费者
# 用户名密码, 不同业务分配不同的账号密码
credential = pika.PlainCredentials('guest', 'guest')

# 虚拟队列需指定参数virtual_host,
parameters = pika.ConnectionParameters(host='192.168.56.33',
                                       port=5672,
                                       virtual_host='/',
                                       credentials=credential)

# 阻塞方法
connection = pika.BlockingConnection(parameters)

# 建立信道
channel = connection.channel()

# 建立队列,若不存在会自动创建, durable=True 时队列有持久化功能
channel.exchange_declare(exchange='logs',
                         exchange_type='fanout')

# 声明消息队列
# exclusive 当与消费者断开连接的时候,队列被立即删除
result = channel.queue_declare(queue='', exclusive=True) # queue=‘’ 系统产生随机队列

queue_name = result.method.queue

# 通过bind实现exchange将message发送到指定queue
channel.queue_bind(exchange='logs', queue=queue_name)


# 定义一个回调函数来处理消息队列中的消息
def callback(ch, method, properties, body):
    time.sleep(1)
    # 手动发送消息 ch.basic_ack(delivery_tag=method.delivery_tag)
    print(body.decode())
    # ch.basic_ack(delivery_tag=method.delivery_tag)

# 如果该消费者的channel上未确认的消息数叨叨了prefetch_count数,则不向该消费者发送消息
channel.basic_qos(prefetch_count=1)

# 消费者使用队列和回调函数处理消息
channel.basic_consume(queue=queue_name,
                      on_message_callback=callback,
                      auto_ack=True)

# 开始接受消息,进入阻塞状态
channel.start_consuming()

  

 

posted @ 2021-01-24 13:43  john221100  阅读(72)  评论(0编辑  收藏  举报