消息队列和微服务1-MQ

1.MQ

1.1 定义

消息队列的目的是为了实现各个 APP 之间的通讯,APP 基于 MQ 实现消息的发送和接收实现应用程序之间的通讯,这样多个应用程序可以运行在不同的主机上,通过 MQ 就可以实现跨网络通信,因此 MQ 实现了业务的解耦和异步机制。
消息队列和微服务1-MQ_第1张图片

1.2 MQ特点

帮助业务系统结构提升开发效率和系统稳定性,消息队列主要具有以下特点:

  • 削峰填谷(主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题)
  • 系统解耦(解决不同重要程度、不同能力级别系统之间依赖导致一死全死)
  • 提升性能(当存在一对多调用时,可以发一条消息给消息系统,让消息系统通知相关系统)
  • 蓄流压测(线上有些链路不好压测,可以通过堆积一定量消息再放开来压测)

1.3 RabbitMQ

1.3.1 特点

RabbitMQ是一款使用Erlang语言开发的,实现AMQP(高级消息队列协议)的开源消息中间件。首先要知道一些RabbitMQ的特点,官网可查:

  • 可靠性。支持持久化,传输确认,发布确认等保证了MQ的可靠性。
  • 灵活的分发消息策略。这应该是RabbitMQ的一大特点。在消息进入MQ前由Exchange(交换机)进行路由消息。分发消息策略有:简单模式、工作队列模式、发布订阅模式、路由模式、通配符模式。
  • 支持集群。多台RabbitMQ服务器可以组成一个集群,形成一个逻辑Broker。
  • 多种协议。RabbitMQ支持多种消息队列协议,比如 STOMP、MQTT 等等。
  • 支持多种语言客户端。RabbitMQ几乎支持所有常用编程语言,包括 Java、.NET、Ruby 等等。
  • 可视化管理界面。RabbitMQ提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker。
  • 插件机制。RabbitMQ提供了许多插件,可以通过插件进行扩展,也可以编写自己的插件

1.3.2 单机版部署

环境:centos7.9

1.3.2.1 下载RabbitMQ rpm文件

下载地址:https://www.rabbitmq.com/download.html
image.png

1.3.2.2 下载Erlang

RabbitMQ是采用 Erlang语言开发的,所以系统环境必须提供 Erlang环境,需要是安装 Erlang
这里安装最新版本3.8.14的RabbitMQ,对应的Erlang版本推荐23.x,我们下载erlang-23.2.7-2.el7.x86_64.rpm

[root@localhost ~]# wget  https://packagecloud.io/rabbitmq/erlang/packages/el/7/erlang-23.2.7-2.el7.x86_64.rpm

1.3.2.3 安装Erlang
root@localhost(192.168.1.52)~>rpm -ivh erlang-23.2.7-2.el7.x86_64.rpm 
warning: erlang-23.2.7-2.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 6026dfca: NOKEY
Preparing...                          ################################# [100%]
Updating / installing...
   1:erlang-23.2.7-2.el7              ################################# [100%]
root@localhost(192.168.1.52)~>

查看版本
root@localhost(192.168.1.52)~>erl -v
Erlang/OTP 23 [erts-11.1.8] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V11.1.8  (abort with ^G)
1> 

1.3.2.4 安装rabbitmq

解决依赖
在RabiitMQ安装过程中需要依赖socat插件,首先安装该插件

root@localhost(192.168.1.52)~>yum install -y socat
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com

解压rabbitmq安装包

root@localhost(192.168.1.52)~>rpm -Uvh rabbitmq-server-3.12.4-1.el8.noarch.rpm 
warning: rabbitmq-server-3.12.4-1.el8.noarch.rpm: Header V4 RSA/SHA512 Signature, key ID 6026dfca: NOKEY
error: Failed dependencies:
	erlang >= 25.0 is needed by rabbitmq-server-3.12.4-1.el8.noarch
root@localhost(192.168.1.52)~>

报错 因为rabbit-3-12要求erlang版本大于25
但是我上面的版本是23 所以我才去降低rabbitmq的版本

root@localhost(192.168.1.52)~>rpm -ivh rabbitmq-server-3.8.14-1.el7.noarch.rpm 
warning: rabbitmq-server-3.8.14-1.el7.noarch.rpm: Header V4 RSA/SHA256 Signature, key ID 6026dfca: NOKE
Preparing...                          ################################# [100%]
	package rabbitmq-server-3.8.14-1.el7.noarch is already installed

1.3.2.5 启动服务
# 启动rabbitmq
systemctl start rabbitmq-server

# 查看rabbitmq状态
systemctl status rabbitmq-server
1.3.2.6 RabbitMQWeb管理界面及授权操作

默认情况下,rabbitmq没有安装web端的客户端软件,需要安装才可以生效

# 打开RabbitMQWeb管理界面插件
rabbitmq-plugins enable rabbitmq_management
root@localhost(192.168.1.52)~>rabbitmq-plugins enable rabbitmq_management
Enabling plugins on node rabbit@localhost:
rabbitmq_management
The following plugins have been configured:
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_web_dispatch
Applying plugin configuration to rabbit@localhost...
The following plugins have been enabled:
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_web_dispatch

started 3 plugins.
root@localhost(192.168.1.52)~>

1.3.2.7 访问

rabbitmq有一个默认的账号密码guest,但该情况仅限于本机localhost进行访问,所以需要添加一个远程登录的用户

添加远程用户
# 添加用户
rabbitmqctl add_user 用户名 密码

# 设置用户角色,分配操作权限
rabbitmqctl set_user_tags 用户名 角色

# 为用户添加资源权限(授予访问虚拟机根节点的所有权限)
rabbitmqctl set_permissions -p / 用户名 ".*" ".*" ".*"

  • administrator:可以登录控制台、查看所有信息、并对rabbitmq进行管理
  • monToring:监控者;登录控制台,查看所有信息
  • policymaker:策略制定者;登录控制台指定策略
  • managment:普通管理员;登录控制
这里创建用户zfl,密码123456,设置administrator角色,赋予所有权限

root@localhost(192.168.1.52)~>rabbitmqctl add_user zfl 123456
Adding user "zfl" ...
Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more.
root@localhost(192.168.1.52)~>rabbitmqctl set_user_tags  zfl administrator
Setting tags for user "zfl" to [administrator] ...
root@localhost(192.168.1.52)~>rabbitmqctl set_permissions -p / zfl  ".*" ".*" ".*"
Setting permissions for user "zfl" in vhost "/" ...
root@localhost(192.168.1.52)~>

消息队列和微服务1-MQ_第2张图片

旧版本允许登录方式:
# vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.3/ebin/rabbit.app
39 {loopback_users, []}, #删除被禁止登陆的 guest 账户
# systemctl restart rabbitmq-server.service #重启 rabbitmq 服务

新版本的guset远程登录方式

开启guest用户远程登录功能
ls /etc/rabbitmq
enabled_plugins
#创建配置文件开启远程登录功能
echo " loopback_users = none"> /etc/rabbitmq/rabbitmq.conf
systemcti restart rabbitmg-server.service

消息队列和微服务1-MQ_第3张图片

其他命令
# 修改密码
rabbitmqctl change_ password 用户名 新密码

# 删除用户
rabbitmqctl delete_user 用户名

# 查看用户清单
rabbitmqctl list_users

1.3.3 docker部署

docker run -itd --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.12-management

输入默认的guset出现,也是因为没有创建用户
消息队列和微服务1-MQ_第4张图片

docker run -itd --name rabbitmq -e RABBITMQ_DEFAULT_USER=zfl -e RABBITMQ_DEFAULT_PASS=123456 -p 5672:5672 -p 15672:15672 rabbitmq:3.12-management

消息队列和微服务1-MQ_第5张图片

1.3.4 rabbitmq的命令

创建 vhost
root@localhost(192.168.1.52)~>rabbitmqctl add_vhost zoey
Adding vhost "zoey" ...
root@localhost(192.168.1.52)~>


列出所有 vhost
root@localhost(192.168.1.52)~> rabbitmqctl list_vhosts
Listing vhosts ...
name
/
zoey
root@localhost(192.168.1.52)~>


# 添加用户
rabbitmqctl add_user 用户名 密码

# 设置用户角色,分配操作权限
rabbitmqctl set_user_tags 用户名 角色

# 为用户添加资源权限(授予访问虚拟机根节点的所有权限)
rabbitmqctl set_permissions -p / 用户名 ".*" ".*" ".*"

2 rabbitmq集群部署

2.1 普通模式

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

2.2 镜像集群模式

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

2.3 集群中有两种节点类型

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

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

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

2.4 推荐设计架构

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

2.5 集群部署

2.5.1 环境

192.168.199.50
192.168.199.51
192.168.199.52

2.5.2 配置域名解析及名称

hostnamectl set-hostname mq-server1
[root@master ~]# cat >> /etc/hosts <

2.5.3 在各自机器安装单机的rabbitmq并配置web端

写好一个脚本 直接执行

[root@mq-server1 rabbit]# cat rabbitmqinstall.sh 
#! /bin/bash
rpm -ivh erlang-23.2.7-2.el7.x86_64.rpm
if [ $? -eq 0 ];then
	echo erlang安装成功;
else
	break
fi
yum install -y socat
if [ $? -eq 0 ];then
        echo socat安装成功;
else
        break
fi

rpm -ivh rabbitmq-server-3.8.14-1.el7.noarch.rpm 
if [ $? -eq 0 ];then
        echo rabbitmq安装成功;
else
        break
fi
systemctl start rabbitmq-server
if [ $? -eq 0 ];then
        echo rabbitmq启动成功;
else
        echo rabbitmq启动失败
fi
#配置web端
rabbitmq-plugins enable rabbitmq_management
#修改guest用户可以直接登录
echo " loopback_users = none"> /etc/rabbitmq/rabbitmq.conf
systemctl restart rabbitmq-server

2.5.4 同步 magic cookie

   Rabbitmq 的集群是依赖于 erlang 的集群来工作的,所以必须先构建起 erlang 的集群环境,而 Erlang 的集群中各节点是通过一个 magic cookie 来实现的,这个cookie 存放在/var/lib/rabbitmq/.erlang.cookie 中,文件是 400 的权限,所以必须保证各节点 cookie 保持一致,否则节点之间就无法通信。
  各服务器关闭RabbitMQ: 
[root@mq-server1 rabbit]# systemctl stop rabbitmq-server
在192.168.199.50上
[root@mq-server1 rabbit]scp -r /var/lib/rabbitmq/.erlang.cookie 192.168.199.51:/var/lib/rabbitmq/.erlang.cookie

[root@mq-server1 rabbit]# scp -r /var/lib/rabbitmq/.erlang.cookie 192.168.199.52:/var/lib/rabbitmq/.erlang.cookie

在启动服务rabbitmq

[root@mq-server1 rabbit]#  systemctl start rabbitmq-server

2.5.5 查看集群状态

[root@mq-server1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@mq-server1 ...
Basics

Cluster name: rabbit@mq-server1

Disk Nodes

rabbit@mq-server1

Running Nodes

rabbit@mq-server1

Versions

rabbit@mq-server1: RabbitMQ 3.8.14 on Erlang 23.2.7

Maintenance status

Node: rabbit@mq-server1, status: not under maintenance

Alarms

(none)

Network Partitions

(none)

Listeners

Node: rabbit@mq-server1, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@mq-server1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@mq-server1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0

Feature flags

Flag: drop_unroutable_metric, state: enabled
Flag: empty_basic_get_metric, state: enabled
Flag: implicit_default_bindings, state: enabled
Flag: maintenance_mode_status, state: enabled
Flag: quorum_queue, state: enabled
Flag: user_limits, state: enabled
Flag: virtual_host_metadata, state: enabled

2.5.6 各节点加入到集群

 rabbitmqctl stop_app
 rabbitmqctl reset
 rabbitmqctl join_cluster rabbit@rabbitmqserver1 --ram

mq-server1默认为disk节点
只需要将mq-server2 mq-server3设置为内存节点

在mq-server2上面将 加入到mq-server1上并作为内存节点

并设置将rabbitmqserver2  为磁盘存储
rabbitmqctl stop_app		
rabbitmqctl reset	       reset #清空元数据
rabbitmqctl join_cluster rabbit@mq-server1 mq-server1  
并成为内存节点,不加--ram 默认是磁盘



[root@mq-server2 ~]# rabbitmqctl stop_app
[root@mq-server2 ~]# rabbitmqctl reset
Resetting node rabbit@mq-server2 ...
[root@mq-server2 ~]# rabbitmqctl join_cluster rabbit@mq-server1  --ram
Clustering node rabbit@mq-server2 with rabbit@mq-server1  
[root@mq-server2 ~]# 

mq-server3上面将 加入到mq-server1上
[root@mq-server3 ~]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@mq-server3 ...
[root@mq-server3 ~]#  rabbitmqctl reset
Resetting node rabbit@mq-server3 ...
[root@mq-server3 ~]# rabbitmqctl join_cluster rabbit@mq-server1 --ram
Clustering node rabbit@mq-server3 with rabbit@mq-server1
[root@mq-server3 ~]# 

2.5.7 查看集群状态

[root@mq-server1 ~]#  rabbitmqctl cluster_status
Cluster status of node rabbit@mq-server1 ...
Basics

Cluster name: rabbit@mq-server1

Disk Nodes

rabbit@mq-server1

RAM Nodes

rabbit@mq-server2
rabbit@mq-server3

Running Nodes

rabbit@mq-server1
rabbit@mq-server2
rabbit@mq-server3

Versions

rabbit@mq-server1: RabbitMQ 3.8.14 on Erlang 23.2.7
rabbit@mq-server2: RabbitMQ 3.8.14 on Erlang 23.2.7
rabbit@mq-server3: RabbitMQ 3.8.14 on Erlang 23.2.7

消息队列和微服务1-MQ_第6张图片

你可能感兴趣的:(大数据,微服务,ruby,架构)