zoukankan      html  css  js  c++  java
  • rabbitmq

    rabbitmq的安装(ubuntu):

    echo 'deb http://www.rabbitmq.com/debian/ testing main' |      
               sudo tee /etc/apt/sources.list.d/rabbitmq.list
    
    wget -O- https://www.rabbitmq.com/rabbitmq-signing-key-public.asc |
       sudo apt-key add -
    
    sudo apt-get update
    sudo apt-get install rabbitmq-server
    
    #启动
    sudo /etc/init.d/rabbitmq start

     

    rabbitmq三种模式:

       一. Direct Exchage:

             1. 可以不绑定exchange, 消息传递时需要一个'routeKey'

             2. 消息会被发送到RouteKey中指定的队列, 如果不存在则抛弃消息

       二. Fanout Exchange

             1. 不需要routekey

             2. 需要将exchange与queue绑定,一个exchange可以绑定多个queue,一个queue也可以绑定到多个exchange

             3. 如果接受到消息的exchange没有与任何queue绑定,则消息会被抛弃

       三. Topic Exchange

             1. 每个队列都有其关心的主题, 所有的消息都带有routekey,  消息会被转发到 关注主题与routekey模糊匹配的队列

             2. ‘#’表示0个或多个关键字, ’*‘ 表示一个关键字

    例如:

    #.a   匹配a.a, aa.a, aaa.a等

    *.a   匹配a.a, b.a, c.a等

    最简单的队列通信:

    send.py

    #!/usr/bin/env python3
    
    import pika
    
    #连接rabbitmq
    connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    
    #生成一个管道,在管道中跑各种队列
    channal = connection.channel()
    
    #声明queue, queue默认会在rabbitmq重启后丢失;需要注意的是queue一旦声明就不允许修改了,
    #比如从非持久化修改成持久化
    channal.queue_declare(queue='hello')      #创建队列hello
    
    #下面这句是将queue持久化,rabbitmq重启后不会丢失,但queue中未被消费的数据会丢失
    #channal.queue_declare(queue='hello', durable=True)
    
    #rabbitmq不能直接发送数据到队列里,需要一个Exchange, Exchange为空则使用默认Exchange.
    #routing_key是队列名称,body是数据内容
    channal.basic_publish(exchange='', routing_key='hello', body='Hello World!')
    
    print('Sent "Hello Wrold!"')
    
    #关闭连接
    connection.close()

    recv.py

    #!/usr/bin/env python3
    
    import pika
    
    #连接rabbitmq
    connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    
    #生成一个管道,在管道里跑各种队列
    channal = connection.channel()
    
    #这里又生成一个队列,是说如果发送端定义了队列,这里就忽略;
    #如果接收端启动的时候,发送端还没有启动,它就创建一个队列,代码不会出错
    channal.queue_declare(queue='hello')
    
    #这里的参数必须这样定义
    def callback(ch, method, properties, body):
        print('Received %r' % body)
        #如果是持久化队列就需要加上面面这句,保证消息持久化
        #ch.basic_ack(delivery_tag=method.delivery_tag)
    
    #rabbitmq如果有多个消费者,默认情况下,消息会依次分发给各个消费者,但是消费端往往
    #处理能力不同,这种模式就会造成处理能力低的消费都信息堆积,处理能力高的却空闲着。
    #为了解决这个问题,可以在各个消费者端,配置prefetch, 意思是告诉rabbitmq在我这个消费者当前消费还没有处理完的时候不要再给我发消息了。
    channal.basic_qos(prefetch_count=1)
    
    #no_ack的意思是不发送接收回执, 设置成False能保证客户端正确接收
    channal.basic_consume(callback, queue='hello', no_ack=False)
    
    #开始接收
    channal.start_consuming()

    direct模式,绑定Exchange

    发布端:

    import pika
    import sys
    
    #连接rabbitmq
    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
    #创建管道
    channel = connection.channel()
    
    #创建direct Exchange, 名称direct_logs
    channel.exchange_declare(exchange='direct_logs', type='direct')
    
    #定义routing_key,设置默认值为info
    severity = sys.argv[1] if len(sys.argv) > 1 else 'info'
    
    #要发送的消息, 默认为hello world
    message = ' '.join(sys.argv[2:]) or 'hello world!'
    
    #exchange和routing_key共同决定发送到哪个队列
    channel.basic_publish(exchange='direct_logs', routing_key=serverity, body=message)
    
    print('Sent %r:%r' % (severity, message))
    
    #关闭连接
    connection.close()

    接收端:

    import pika
    import sys
    
    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
    
    channel = connection.channel()
    
    channel.exchange_declare(exchange='direct_logs', type='direct')
    
    result = channel.queue_declare(exclusive=True)
    queue_name = result.method.queue
    
    severities = sys.argv[1:]
    
    if not severities:
        sys.stderr.write('Usage; %s [info] [warning] [error]
    ' % sys.argv[0])
        sys.exit()
    
    #绑定exchange, 这样循环是因为可以接收好几种日志类型,比如执行 python3 接收端.py info warning error
    for severity in severities:
        channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key=severity)
    
    print('Waiting for logs To exit press CTRL+C')
    
    def callback(ch, method, properties, body):
        print('%r:%r' % (method.routing_key, body))
    
    channel.basic_consume(callback, queue=queue_name, no_ack=True)
    
    channel.start_consuming()

    发布端运行:

    $ python3 发布端.py
    Sent 'info':'hello world!'
    $ python3 发布端.py info warning 1111
    Sent 'info':'warning 1111'
    $ python3 发布端.py error 22222
    Sent 'error':'22222'

    接收端运行:

    $ python3 接收端.py info warning error
    waiting for logs To exit press CTRL+C
    'info':b'hello world!'
    'info':b'warning 1111'
    'error':b'22222'
  • 相关阅读:
    LeetCode c++-- 118.杨辉三角
    LeetCode c++ --896. 单调数列
    LeetCode c++--1551. 使数组中所有元素相等的最小操作数
    LeetCode c++:1550. 存在连续三个奇数的数组
    LeetCode c++--字符串转换整数 (atoi)
    c++ 顺序容器常用知识总结
    c++基础知识之容器一:顺序容器
    小菜鸡c++ LeetCode初级算法之一——数组(删除排序数组中的重复项)
    JVM
    BATCH、事务、CLOB、BLOB
  • 原文地址:https://www.cnblogs.com/huangxm/p/5739011.html
Copyright © 2011-2022 走看看