1、什么是消息中间件
利用可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,他可以在分布式环境下扩展进程间通信。
应用程序之间异步通信
2、消息中间件的作用
异步
解耦
削峰
冗余
3、JMS协议
JavaMessageService sun 01年发布的 规范,用来统一所有的mq规范,提供了一个JavaAPI
AMQP协议 04年出现的
单播
广播
4、AMQP协议
AMQP包含如下几个组件
- 生产者
- 消费者
- 消息:有效载荷与标签
- 连接、信道:一个tcp连接里有多个信道,节省资源
- 交换器、队列、路由键、绑定: 交换器和队列通过路由键来绑定
5、RabbitMQ简介
RabbitMQ的一些特性:
消息确认机制
队列、消息持久化
消息拒收
默认交换器 mandatory(防止丢失)
官方文档:https://www.rabbitmq.com/documentation.html
6、Centos7下RabbitMQ安装
6.1、安装Erlang
版本选择:https://www.rabbitmq.com/which-erlang.html
下载地址:https://github.com/rabbitmq/erlang-rpm/releases
选择:rabbitmq官方维护的专为rabbitmq准备的erlang版本
vi /etc/yum.repos.d/rabbitmq_erlang.repo
写入:
1 | [rabbitmq-erlang] |
安装:yum install erlang -y
6.2、安装RabbitMQ
官网:https://github.com/rabbitmq/rabbitmq-server/releases
1 | rpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc |
1 | [bintray-rabbitmq-server] |
安装
1 | yum install -y rabbitmq-server |
6.3、开机启动RabbitMQ
1 | chkconfig rabbitmq-server on |
6.4、启动运行
1 | /sbin/service rabbitmq-server start |
6.5、防火墙设置
- 4369: epmd, a peer discovery service used by RabbitMQ nodes and CLI tools
- 5672, 5671: used by AMQP 0-9-1 and 1.0 clients without and with TLS
- 25672: used for inter-node and CLI tools communication (Erlang distribution server port) and is allocated from a dynamic range (limited to a single port by default, computed as AMQP port + 20000). Unless external connections on these ports are really necessary (e.g. the cluster uses federation or CLI tools are used on machines outside the subnet), these ports should not be publicly exposed. See networking guide for details.
- 35672-35682: used by CLI tools (Erlang distribution client ports) for communication with nodes and is allocated from a dynamic range (computed as server distribution port + 10000 through server distribution port + 10010). See networking guide for details.
- 15672: HTTP API clients, management UI and rabbitmqadmin (only if the management plugin is enabled)
- 61613, 61614: STOMP clients without and with TLS (only if the STOMP plugin is enabled)
- 1883, 8883: (MQTT clients without and with TLS, if the MQTT plugin is enabled
- 15674: STOMP-over-WebSockets clients (only if the Web STOMP plugin is enabled)
- 15675: MQTT-over-WebSockets clients (only if the Web MQTT plugin is enabled)
- 15692: Prometheus metrics (only if the Prometheus plugin is enabled)
1 | firewall-cmd --query-port=5672/tcp |
7、插件安装
1 | [root@dn1 ~]# rabbitmq-plugins disable rabbitmq_management |
8、配置优化
官方文档:https://www.rabbitmq.com/configure.html
rabbitmq的默认设置往往能够适应大多数开发或OA环境,但是对于生产环境来说还需要一定的优化。
8.1、配置文件
位置:https://www.rabbitmq.com/configure.html#config-file-location
1 | node : rabbit@example |
如果不能确定你的配置文件的路径,查阅 log文件。或者在ManagerUI中查找
1 | [root@dn1 rabbitmq]# find / -name rabbitmq.co* |
8.2、如何检查配置是否生效?
1 | rabbitmqctl environment |
8.3、新老配置文件格式
rabbitmq 3.7.0 之前格式 rabbitmq.config,使用erlang 配置格式
1 | [ |
rabbitmq 3.7.0 之后,推荐使用新的 sysctl格式
1 | ssl_options.cacertfile = /path/to/ca_certificate.pem |
8.4、rabbitmq-env.conf
样例
/usr/lib/rabbitmq/lib/rabbitmq_server-3.7.24/sbin/rabbitmq-defaults
配置
1 | !/bin/sh -e |
查看
1 | rabbitmqctl environment |
8.5、rabbitmq.conf
样例:https://github.com/rabbitmq/rabbitmq-server/blob/v3.7.x/docs/rabbitmq.conf.example
通过 rabbitmq-env.conf
来指定使用哪个配置文件,可以用来指定rabbitmq-dev.conf
或 rabbitmq-prod.conf
:
其实是 RABBITMQ_CONFIG_FILE
省略了前缀 RABBITMQ_
,就变成了 CONFIG_FILE
.
核心配置选项
1 | listeners.tcp.default = 5672 # AMQP 对外服务端口 |
vi /etc/rabbitmq/rabbitmq.conf
1 | listeners.tcp.default = 5672 |
1 | [root@dn1 rabbitmq]# chown rabbitmq:rabbitmq rabbitmq.conf |
8.6、advanced.config
样例:https://github.com/rabbitmq/rabbitmq-server/blob/master/docs/advanced.config.example
核心配置选项
1 | {msg_store_index_module, rabbit_msg_store_ets_index} |
8.7、配置加密项
8.8、操作系统Kernel限制
1 | 永久更改最大打开文件描述符数 |
1 | [root@dn1 ~]# vi /etc/sysctl.conf |
8.9、生产环境检查
官方文档:https://www.rabbitmq.com/production-checklist.html
9、集群配置
为什么需要集群? 保证高可用
可以保证消息的万无一失吗?不能,队列跟消息存储在单一节点上。exchange和绑定可以复制。默认不会对队列中的消息进行复制。但可以解决
队列在及集群是如何存在的?默认不会复制
交换器在集群中如何存在的?会复制
集群中的节点有什么要求? 为了保障高可用,建议至少在集群中设置两个磁盘节点,其他为内存节点,提高集群的吞吐量
9.1、单机多节点集群
一台机器上,开不同端口
9.2、多机多节点集群
1、前提
只能在内网使用,对网络非常敏感
停止rabbitmq节点:/sbin/service rabbitmq-server stop
2、修改3台节点host文件
1 | vi /etc/hosts |
3、修改 erlang.cookie
1 | cat /var/lib/rabbitmq/.erlang.cookie |
4、配置集群
1、启动节点
1 | service rabbitmq-server start |
2、查看集群状态
1 | rabbitmqctl cluster_status |
3、将节点2,3加入集群
node2作为磁盘节点加入集群
1 | [root@dn2 ~]# rabbitmqctl stop_app |
node3 作为内存节点加入集群
1 | [root@dn3 ~]# rabbitmqctl stop_app |
5、踢出单个节点
方法一:
1 | [root@dn2 ~]# service rabbitmq-server stop |
方法二:
1 | [root@dn3 ~]# rabbitmqctl start_app |
问题解决:
1 | 2020-04-03 15:36:52.980 [error] <0.165.0> Mnesia(rabbit@dn2): ** ERROR ** (core dumped to file: "/var/lib/rabbitmq/MnesiaCore.rabbit@dn2_1585_899412_979927") |
6、异常处理
确保节点可以启动,即使它不是最后一个关闭的节点
1 | rabbitmqctl force_boot |
设置集群名称
1 | rabbitmqctl set_cluster_name {name} |
修改集群节点的类型。在这个命令执行前需要停止RabbitMQ应用
1 | rabbitmqctl stop_app |
10、负载均衡
10.1、使用HAProxy实现负载均衡
配置各个负载的内核参数
1 | vim /etc/sysctl.conf |
安装Haproxy
安装依赖包
1 | yum install gcc openssl-devel readline-devel systemd-devel make pcre-devel -y |
1 | cd /data/soft/new/ |
- PREFIX 为指定的安装路径
- TARGET则根据当前操作系统内核版本指定
- - linux22 for Linux 2.2
- - linux24 for Linux 2.4 and above (default)
- - linux24e for Linux 2.4 with support for a working epoll (> 0.21)
- - linux26 for Linux 2.6 and above
- - linux2628 for Linux 2.6.28, 3.x, and above (enables splice and tproxy)
本文的操作系统内核版本为3.10.0,TARGET指定为 linux2628。
make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1
# # USE_PCRE=1 开启正则 USE_OPENSSL=1 开启openssl USE_ZLIB=1
# # USE_CPU_AFFINITY=1 为开启haproxy进程与CPU核心绑定,USE_SYSTEMD=1为支持使用 -Ws参数(systemd-aware master-worker 模式)启动Haproxy,从而实现单主进程多子进程运行模式。
配置Haproxy
1 | mkdir /etc/haproxy |
日志配置
1 | 打开rsyslog配置: |
准备system启动脚本
1 | cp /usr/local/haproxy/sbin/haproxy /usr/sbin/ |
如果服务器安装后修改了hostname,出现了 unable to connect to epmd (port 4369) on bogon: nxdomain (non-existing domain) 这个问题,请看下是否 /etc/hosts 文件、/etc/hostname文件和环境变量$HOSTNAME 是否一致。
如果启动HAProxy出现 /etc/rc.d/init.d/haproxy: line 26: [: =: unary operator expected 这个错误,修改/etc/init.d/haproxy 文件的26行 [ ${NETWORKING} = “no” ] && exit 0 为 [ “${NETWORKING}” = “no” ] && exit 0
启动haproxy
1 | 检查配置文件语法 |
开机启动
1 | /sbin/chkconfig haproxy on |
安装keepalived
官网:https://www.keepalived.org/download.html
下载安装
1 | cd /data/soft/new |
配置系统服务
1 | [root@dn1 keepalived-1.4.5]# cd ~ |
配置keepalived
1 | [root@dn1 ~]# vi /etc/keepalived/check_haproxy.sh |
启动
1 | service keepalived start && systemctl status keepalived.service -l |
1 | [root@dn1 ~]# ip add show |
11、性能测试
11.1、RabbitMQ PerfTest
PerfTest 是一个基于Java的吞吐量测试工具
1)、下载安装
1 | 文档 |
1 | cd /data/message-queue/rabbitmq |
2)、开始压测
单压各个节点
1-p, 2-c:发现内存节点和磁盘节点差距不大,应该是消费速度足够快,不需要落到磁盘上
1 | cd /data/message-queue/rabbitmq/rabbitmq-perf-test-2.11.0/bin |
1 | ./runjava com.rabbitmq.perf.PerfTest -h amqp://admin:admin@192.168.145.135:5672 -x 5 -y 10 -u "throughput-test-2" -a --id "test 2" |
1
1 | 压整个集群 |
使用vmstat 观察到cpu不够用,加cpu以后,效率直线上升
1 | netstat -tan |grep ^tcp |awk '{++a[$6]} END{for (i in a) print i, a[i]}' |