• 消息队列之RabbitMQ


    一、RabbitMQ

    官方网址: https://www.rabbitmq.com/

    1.1 RabbitMQ 简介:

    RabbitMQ 采用 Erlang 语言开发,Erlang 语言由 Ericson 设计,Erlang 在分布式编程和故障恢复方面表现出色,电信领域被广泛使用。

    Erlang语言官方网址:https://www.erlang.org/

    Broker: 接收和分发消息的应用,RabbitMQ Server 就是 Message Broker。

    Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念,当多个不同的用户使用同一个RabbitMQ server 提供的服务时,可以划分出多个 vhost,每个用户在自己的 vhost创建 exchange/queue 等。

    Connection:publisher/consumer 和 broker 之间的 TCP 连接。

    Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection 的开销将是巨大的,效率也较低。Channel 是在 connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个 thread 创建单独的channel 进行通讯,AMQP method 包含了 channel id 帮助客户端和 message broker识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection极大减少了操作系统建立 TCP connection 的开销。

    Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到 queue 中去。常用的类型有:direct (point-to-point),topic (publish-subscribe) and fanout (multicast)。

    Queue:消息最终被送到这里等待 consumer 取走。

    Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据。

    RabbitMQ的优势:

    1、基于 erlang 语言开发,具有高并发优点、支持分布式;

    2、具有消息确认机制、消息持久化机制,消息可靠性和集群可靠性高;

    3、简单易用、运行稳定、跨平台、多语言;

    4、开源。

    Queue 的特性:

    1、消息基于先进先出的原则进行顺序消费;

    2、消息可以持久化到磁盘节点服务器;

    3、消息可以缓存到内存节点服务器提高性能。

    1.2 RabbitMQ中的生产者消费者示例:

    生产者发送消息到 broker server(RabbitMQ),在 Broker 内部,用户创建

    Exchange/Queue,通过 Binding 规则将两者联系在一起,Exchange 分发消息,根据类型/binding 的不同分发策略有区别,消息最后来到 Queue 中,等待消费者取走。

    JMS 是在 2001 年发布的 Java 消息服务(Java Message Service)应用程序接口,是一个 Java 平台中关于面向消息中间件(MOM,message oriented middleware)的 API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

    1.3 RabbitMQ单机部署:

    官网下载地址:

    https://www.rabbitmq.com/download.html

    github下载地址:

    https://github.com/rabbitmq/rabbitmq-server/releases

    1.3.1 ubuntu1804部署单机版RabbitMQ

    官方参考: https://www.rabbitmq.com/install-debian.html

    1.3.1.1 主机名解析:在当前MQ服务器配置本地主机名解析

    #编辑hosts文件,添加本地主机名解析
    root@ubuntu1804-40:~# vim /etc/hosts
    10.0.0.40 ubuntu1804-40
    #测试是否添加成功
    root@ubuntu1804-40:~# ping ubuntu1804-40
    PING ubuntu1804-40 (10.0.0.40) 56(84) bytes of data.
    64 bytes from ubuntu1804-40 (10.0.0.40): icmp_seq=1 ttl=64 time=0.033 ms
    64 bytes from ubuntu1804-40 (10.0.0.40): icmp_seq=2 ttl=64 time=0.030 ms

    1.3.1.2 服务器安装RabbitMQ

    #安装基础命令及添加key
    sudo apt-get -y install curl gnup
    curl -1sLf 'https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey' | sudo apt-key add -
    
    #安装apt HTTPS传输
    sudo apt-get -y install apt-transport-https
    
    #添加apt源
    sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF
    deb http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main
    deb-src http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main
    deb https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main
    deb-src https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main
    EOF
    
    #更新apt源
    sudo apt update
    
    #查看可安装的RabbitMQ版本
    sudo apt-cache madison rabbitmq-server
    
    #安装erlang
    sudo apt-get install -y erlang-base 
                            erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets 
                            erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key 
                            erlang-runtime-tools erlang-snmp erlang-ssl 
                            erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
    
    #安装RabbitMQ
    sudo apt-get install rabbitmq-server -y --fix-missing

    1.3.1.3 启动RabbitMQ

    #启动RabbitMQ,ubuntu安装完成后自动启动
    systemctl start rabbitmq-server.service
    
    #停止RabbitMQ
    systemctl stop rabbitmq-server.service
    
    #查看RabbitMQ状态
    systemctl status rabbitmq-server.service

    1.3.1.4 RabbitMQ常用命令

    #查看节点状态
    rabbitmqctl status

    #查看所有可用插件
    rabbitmq-plugins list
    #启用插件
    rabbitmq-plugins enable <plugin-name>
    #停用插件
    rabbitmq-plugins disable <plugin-name>

    #列出所有用户
    rabbitmqctl list_users
    #添加用户
    rabbitmqctl add_user <username> <password>
    #删除用户
    rabbitmqctl delete_user <username>
    #清除用户权限
    rabbitmqctl clear_permissions -p vhostpath <username>
    #列出用户权限
    rabbitmqctl list_user_permissions <username>
    #设置用户权限
    rabbitmqctl set_permissions -p vhostpath <username> ".*" ".*" ".*"
    #修改用户密码
    rabbitmqctl change_password <username> <newpassword>

    1.3.1.5 RabbitMQ插件管理

    官方参考:https://www.rabbitmq.com/management.html

    #开启web界面管理插件
     rabbitmq-plugins enable rabbitmq_management

    5672:消费者访问端口

    15672:web管理端口

    25672:集群状态通信端口

    1.3.1.6 登录web管理界面

    登录地址:服务器ip:15672

    RabbitMQ从3.3.0开始禁止使用guest/guest权限通过除了localhost外的访问,直接访问会报以下错误:

     登录web界面方法:

    #由于我的RabbitMQ版本是3.8.16,没有rabbit.app文件,只能重新添加用户并授权
    #添加用户
    rabbitmqctl add_user <username> <password>
    #设置添加的用户为管理员
    rabbitmqctl set_user_tags <username> administrator
    #赋予权限
    rabbitmqctl set_permissions -p / <username> ".*" ".*" ".*"
    #重启服务
    systemctl restart rabbitmq-server.service

    1.4 RabbitMQ集群部署

    Rabbitmq 集群分为二种方式:

    普通模式:创建好 RabbitMQ 集群之后的默认模式。

    镜像模式:把需要的队列做成镜像队列。

    普通集群模式:

    queue 创建之后,如果没有其它 policy,消息实体只存在于其中 一个节点,A、B 两个 Rabbitmq 节点仅有相同的元数据,即队列结构,但队列的数据仅保存有一份,即创建该队列的 rabbitmq 节点(A 节点),当消息进入 A 节 点的 Queue 中后,consumer 从 B 节点拉取时,RabbitMQ 会临时在 A、B 间进行消息传输,把 A 中的消息实体取出并经过 B 发送给 consumer,所以 consumer 可以连接每一个节点,从中取消息,该模式存在一个问题就是当 A 节点故障后,B 节点无法取到 A 节点中还未消费的消息实体。

    镜像集群模式:

    把需要的队列做成镜像队列,存在于多个节点,属于 RabbitMQ 的 HA 方案(镜 像模式是在普通模式的基础上,增加一些镜像策略) 该模式解决了普通模式中的数据丢失问题,其实质和普通模式不同之处在于,消 息实体会主动在镜像节点间同步,而不是在 consumer 取数据时临时拉取,该模 式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之 大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉,所以在对可靠性要求较高的场合中适用,一个队列想做成镜像队列,需要先设置 policy, 然后客户端创建队列的时候,rabbitmq 集群根据“队列名称”自动设置是普通集群模式或镜像队列。

    集群种有两种节点类型:

    内存节点:只将数据保存到内存。

    磁盘节点:保存数据到内存和磁盘。

    内存节点虽然不写入磁盘,但是它执行比磁盘节点要好,集群中,只需要一个 磁盘节点来保存数据就足够了如果集群中只有内存节点,那么不能全部停止它 们,否则所有数据消息在服务器全部停机之后都会丢失。

    在一个 rabbitmq 集群里,有 3 台或以上机器,其中 1 台使用磁盘模式,其它节 点使用内存模式,内存节点无访问速度更快,由于磁盘 IO 相对较慢,因此可作为数据备份使用。

    1.4.1 debian10部署RabbitMQ集群

    环境配置:10.0.0.10,10.0.0.20,10.0.0.30

    1.4.1.1 主机名解析配置

    各 RabbitMQ 服务器配置本地主机名解析:

    10.0.0.10 debian10-10
    10.0.0.20 debian10-20
    10.0.0.30 debian10-30

    1.4.1.2 各服务器安装RabbitMQ

    #安装基础命令依赖及添加key
    sudo apt-get install curl gnupg debian-keyring debian-archive-keyring apt-transport-https -y
    sudo apt-key adv --keyserver "hkps://keys.openpgp.org" --recv-keys "0x0A9AF2115F4687BD29803A206B73A36E6026DFCA"
    sudo apt-key adv --keyserver "keyserver.ubuntu.com" --recv-keys "F77F1EDA57EBB1CC"
    curl -1sLf 'https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey' | sudo apt-key add -
    
    #添加apt源
    sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF
    deb https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/deb/debian buster main
    deb-src https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/deb/debian buster main
    deb https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/deb/debian buster main
    deb-src https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/deb/debian buster main
    EOF
    
    #更新apt源
    sudo apt update
    
    #查看可安装的RabbitMQ版本
    sudo apt-cache madison rabbitmq-server
    
    #安装erlang
    sudo apt-get install -y erlang-base 
                            erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets 
                            erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key 
                            erlang-runtime-tools erlang-snmp erlang-ssl 
                            erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
    
    #安装RabbitMQ
    sudo apt-get install rabbitmq-server -y --fix-missing

    1.4.1.3 创建RabbitMQ集群

    Rabbitmq 的集群是依赖于 erlang 的集群来工作的,所以必须先构建起 erlang 的 集群环境,而 Erlang 的集群中各节点是通过一个 magic cookie 来实现的,这个 cookie 存放在 /var/lib/rabbitmq/.erlang.cookie 中,文件是 400 的权限,所以必须 保证各节点 cookie 保持一致,否则节点之间就无法通信。

    debian10的ssh默认不能使用密码登录,如需使用scp,则需要修改/etc/ssh/sshd_config文件
    需要将PermitRootLogin no / without-password 改为 PermitRootLogin yes
    重启ssh服务:systemctl restart sshd

    拷贝前需要停止RabbitMQ服务。

    systemctl stop rabbitmq-server.service

    将节点1上的erlang.cookie文件拷贝到节点2和节点3服务器。

    scp /var/lib/rabbitmq/.erlang.cookie 10.0.0.20:/var/lib/rabbitmq/.erlang.cookie
    scp /var/lib/rabbitmq/.erlang.cookie 10.0.0.30:/var/lib/rabbitmq/.erlang.cookie

    查看节点1的集群名称,并将其余2个节点加入到集群

    #查看节点1的集群名称
    root@debian10-10:/# rabbitmqctl cluster_status
    Cluster status of node rabbit@debian10-10 ...
    #加入集群,以内存节点的模式
    root@debian10-20:~# rabbitmqctl join_cluster rabbit@debian10-10 --ram
    root@debian10-30:~# rabbitmqctl join_cluster rabbit@debian10-10 --ram
    #再次查看节点状态
    #3.7X版本
    root@debian10-10:/# rabbitmqctl cluster_status
    Cluster status of node rabbit@debian10-10 ...
    [{nodes,[{disc,['rabbit@debian10-10']},
             {ram,['rabbit@debian10-30','rabbit@debian10-20']}]},
     {running_nodes,['rabbit@debian10-30','rabbit@debian10-20',
                     'rabbit@debian10-10']},
     {cluster_name,<<"rabbit@debian10-10">>},
     {partitions,[]},
     {alarms,[{'rabbit@debian10-30',[]},
              {'rabbit@debian10-20',[]},
              {'rabbit@debian10-10',[]}]}]
    
    #3.8.X版本
     rabbitmqctl cluster_status 
    Cluster status of node rabbit@mq-server2 ...
    Basics
    Cluster name: rabbit@mq-server2
    Disk Nodes
    rabbit@mq-server2
    Running Nodes
    rabbit@mq-server2
    Versions
    rabbit@mq-server2: RabbitMQ 3.8.3 on Erlang 22.3

    要在web界面上看到3个节点正常,需要每个节点都开启web界面。

    #开启RabbitMQ的web界面
    rabbitmq-plugins enable rabbitmq_management

     

  • 相关阅读:
    c++新特性之std::atomic
    PyQt 演示Demo1
    RxCPP(二)关键元素
    c++11 random_device 真随机数最简单应用
    PyQT5 安装与入门
    RxCPP(一)编程模型入门 调度
    RxCpp(四)Qt/GUI编程
    RxCPP(一)编程模型入门
    Flask 学习80.FlaskRESTX使用reqparse 解析器trim=True去掉字符两边空格 上海
    Flask 学习81.FlaskRESTX使用reqparse 解析器去掉值为None的参数 上海
  • 原文地址:https://www.cnblogs.com/nj-duzi/p/14842237.html
Copyright © 2020-2023  润新知