• 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()
    

      

  • 相关阅读:
    Codeforces Round #183 (Div. 2) B. Calendar
    FZU Problem 2030 括号问题
    NEU(1262: ASCII Sequence II)动态规划
    ZOJ(1711)Sum It Up (DFS+剪枝+去重复)
    ZOJ(1004)Anagrams by Stack (DFS+stack)
    HDU(3374) (KMP + 最小表示法)
    FZU Problem 1926 填空(KMP好题一枚,确实好)
    POJ(2481)Cows 树状数组
    HOJ (1042) 整数划分
    LeetCode: Two Sum
  • 原文地址:https://www.cnblogs.com/workherd/p/14320696.html
Copyright © 2020-2023  润新知