• RabbitMQ消息队列


    RabbitMQ消息队列

      !!!  注意,保证服务器的内存足够,磁盘足够,以及删除/etc/hosts中没有用的dns解析

    # 优点,能够保证消息数据持久化,不丢失,支持高并发
    
    安装学习rabbitmq消息队列,配置好阿里云的yum源
    
    1.yum -y install erlang  rabbitmq-server
    
    2.启动rabbitmq服务端
    systemctl start rabbitmq-server
    
    3.开启rabbitmq的web控制台
    rabbitmq-plugins enable rabbitmq_management
    
    4.重启后生效web界面
    systemctl restart rabbitmq-server
    # 查看是否生效,出现登录页面就成功了
    http://192.168.81.130:15672/    # 端口必须是这个
    
    5.创建rabbitmq用户
    sudo rabbitmqctl add_user attila 6666.设置用户的权限,为admin管理员权限
    sudo rabbitmqctl set_user_tags attila administrator
    
    7.允许attila这个用户对所有的队列进行读写
    sudo rabbitmqctl set_permissions -p "/" attila ".*" ".*" ".*"
    
    8.可以用attila登录 rabbitmq的后台界面管理了

      no-ack机制

        不确定机制,就是每次消费者接收完数据后,不管是否处理完毕,rabbitmq-server都会把这个消息标记完成,从队列中删除

    # 建一个py文件,叫做生产者.py
    #!/usr/bin/env python
    import pika
    # 创建凭证,使用rabbitmq用户密码登录
    # 去邮局取邮件,必须得验证身份
    credentials = pika.PlainCredentials("attila","666")
    # 新建连接,这里localhost可以更换为服务器ip
    # 找到这个邮局,等于连接上服务器
    connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.81.130',credentials=credentials))
    # 创建频道
    # 建造一个大邮箱,隶属于这家邮局的邮箱,就是个连接
    channel = connection.channel()
    # 声明一个队列,用于接收消息,队列名字叫“笑傲江湖”
    channel.queue_declare(queue='笑傲江湖')
    # 注意在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),初学可以使用空字符串交换(exchange=''),
      它允许我们精确的指定发送给哪个队列(routing_key=''),参数body值发送的数据
    channel.basic_publish(exchange='',
                          routing_key='笑傲江湖',
                          body='独孤九剑潇洒非凡')
    print("已经发送了消息")
    # 程序退出前,确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接
    connection.close()
    # 启动py文件,查看浏览器上的RabbitMQ, http://192.168.81.130:15672/  必须是这个端口  此时,浏览器上应该有一条数据了

      生产者已经有了,这时候准备一个消费者

    import pika
    # 建立与rabbitmq的连接
    credentials = pika.PlainCredentials("attila","666")
    connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.81.130',credentials=credentials))
    channel = connection.channel()
    channel.queue_declare(queue="笑傲江湖")
    
    def callbak(ch,method,properties,body):
        print("消费者接收到了任务:%r"%body.decode("utf8"))
    # 有消息来临,立即执行callbak,没有消息则夯住,等待消息
    # 老百姓开始去邮箱取邮件啦,队列名字是水许传
    channel.basic_consume(callbak,queue="笑傲江湖",no_ack=True)  # no_ack=True, 就是不需要回复,我只负责取走,不给你反馈
    # 开始消费,接收消息
    channel.start_consuming()
    
    # 在浏览器上查看rabbitmq,发现消息没有了 

      ACK机制(用于单发送多接收)

    一个发送端,多个接收端,如分布式的任务派发。为了保证消息发送的可靠性,不丢失消息,使消息持久化了。
      同时为了防止接收端在处理消息时down掉,只有在消息处理完成后才发送ack消息。
    # ACK机制用于保证消费者如果拿了队列的消息,客户端处理时出错了,那么队列中任然还存在这个消息,等待下一位消费者继续取.

      建一个 生产者.py文件

    #!/usr/bin/env python
    import pika
    # 创建凭证,使用rabbitmq用户密码登录
    # 比如去邮局取邮件,必须得验证身份
    credentials = pika.PlainCredentials("attila","666")
    # 新建连接,这里localhost可以更换为服务器ip
    # 找到这个邮局,等于连接上服务器
    connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.81.130',credentials=credentials))
    # 创建频道
    # 建造一个大邮箱,隶属于这家邮局的邮箱,就是个连接
    channel = connection.channel()
    # 新建一个hello队列,用于接收消息
    # 这个邮箱可以收发各个班级的邮件,通过
    channel.queue_declare(queue='笑傲江湖')
    # 注意在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),初学可以使用空字符串交换(exchange=''),
      它允许我们精确的指定发送给哪个队列(routing_key=''),参数body值发送的数据
    channel.basic_publish(exchange='',
                          routing_key='笑傲江湖',
                          body='令狐冲独孤九剑笑傲江湖')
    print("已经发送了消息")
    # 程序退出前,确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接
    connection.close()
    # 启动py文件,查看浏览器上的RabbitMQ, http://192.168.81.130:15672/  此时,浏览器上应该有一条数据了

       创建一个消费者

    import pika
    
    credentials = pika.PlainCredentials("s14","123")
    connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.119.10',credentials=credentials))
    channel = connection.channel()
    
    # 声明一个队列(创建一个队列)
    channel.queue_declare(queue='笑傲江湖')
    
    def callback(ch, method, properties, body):
        print("消费者接受到了任务: %r" % body.decode("utf-8"))
        # int('嘻嘻嘻')   # 强转为了让他报错,但是消息取出来了,也就是没有消息了,那么这样会丢数据,所以需要把no-ack改为False
        # 我告诉rabbitmq服务端,我已经取走了消息
        # 回复方式在这
        ch.basic_ack(delivery_tag=method.delivery_tag)
    # 关闭no_ack,代表给与服务端ack回复,确认给与回复,这样如果取数据过程中出错,rabbitmq中消息不会被取走.
    channel.basic_consume(callback,queue='笑傲江湖',no_ack=False)
    
    channel.start_consuming()

      消息持久化

    # 演示
    1.执行生产者,向队列写入数据,产生一个新队列queue
    2.重启服务端,队列丢失
    
    3.开启生产者数据持久化后,重启rabbitmq,队列不丢失
    4.依旧可以读取数据

      创建可持久化的队列

        生产者.py

    import pika
    # 无密码
    # connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.81.130'))
    # 有密码
    credentials = pika.PlainCredentials("attila","666")
    connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.81.130',credentials=credentials))
    channel = connection.channel()
    # 声明一个队列(创建一个队列)
    # 默认此队列不支持持久化,如果服务挂掉,数据丢失
    # durable=True 开启持久化,必须新开启一个队列,原本的队列已经不支持持久化了
    '''
    实现rabbitmq持久化条件
     delivery_mode=2
    使用durable=True声明queue是持久化
     
    '''
    channel.queue_declare(queue='天龙八部',durable=True)
    channel.basic_publish(exchange='',
                          routing_key='天龙八部', # 消息队列名称
                          body='降龙十八掌天下第一',
                          # 支持数据持久化
                          properties=pika.BasicProperties(
                              delivery_mode=2,#代表消息是持久的  2
                          )
                          )
    connection.close()

      消费者.py

    import pika
    credentials = pika.PlainCredentials("attila","666")
    connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.81.30',credentials=credentials))
    channel = connection.channel()
    # 确保队列持久化
    channel.queue_declare(queue='天龙八部',durable=True)
    
    '''
    必须确保给与服务端消息回复,代表我已经消费了数据,否则数据一直持久化,不会消失
    '''
    def callback(ch, method, properties, body):
        print("消费者接受到了任务: %r" % body.decode("utf-8"))
        # 模拟代码报错
        # int('asdfasdf')    # 此处报错,没有给予回复,保证客户端挂掉,数据不丢失
       
        # 告诉服务端,我已经取走了数据,否则数据一直存在
        ch.basic_ack(delivery_tag=method.delivery_tag)
    # 关闭no_ack,代表给与回复确认
    channel.basic_consume(callback,queue='天龙八部',no_ack=False)
    channel.start_consuming()
  • 相关阅读:
    关于代码片段
    感谢visual studio(git插件)救我一命
    SRX一些配置命令
    .NET Core Policy和Claim
    .NET Core Identity 用户管理和策略
    .NET Core基础配置、注册服务、中间件、ViewComponent、DbContext
    table非常细边框
    js数字转大写金额
    蓝牙开发
    Laravel artisan 命令
  • 原文地址:https://www.cnblogs.com/attila/p/10705287.html
Copyright © 2020-2023  润新知