1rabbitMq安装
1.1上传软件 相关软件下载链接
- erlang18.31.el7.centos.x86_64.rpm
- socat1.7.3.25.el7.lux.x86_64.rpm
- rabbitmqserver3.6.51.noarch.rpm
1.2安装软件
- rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm
- rpm -ivh socat-1.7.3.2-1.1.el7.x86_64.rpm --force --nodeps
- rpm -ivh rabbitmq-server-3.6.5-1.noarch.rpm
1.3开启管理界面
rabbitmq-plugins enable rabbitmq_management
1.4修改默认配置信息
vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.5/ebin/rabbit.app
loopback_users 中的 <<"guest">>,只保留guest
修改密码、配置等等
1.5启动服务
service rabbitmq-server start # 启动服务
service rabbitmq-server stop # 停止服务
service rabbitmq-server restart # 重启服务
1.6设置配置文件
cd /usr/share/doc/rabbitmq-server-3.6.5/
cp rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
关闭防火墙
firewall-cmd --zone=public --add-port=15672/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
1.7设置开机自启动
chkconfig rabbitmq-server on
1.8配置虚拟主机及用户
访问http://ip地址:15672 默认账号guest 密码guest
新增用户
角色说明
超级管理员(administrator)
可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操 作。
监控者(monitoring)
可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用 情况,磁盘使用情况等)
策略制定者(policymaker)
可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上 图红框标识的部分)。
普通管理者(management)
仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。
其他
无法登陆管理控制台,通常就是普通的生产者和消费者。
Virtual Hosts配置
像mysql拥有数据库的概念并且可以指定用户对库和表等操作的权限。
RabbitMQ也有类似的权限管理;在RabbitMQ中可以虚拟消息服务器Virtual Host,每个Virtual
Hosts相当于一个相对独立的RabbitMQ服务器,每个
VirtualHost之间是相互隔离的。exchange、queue、message不能互通。 相当 于mysql的db。Virtual
Name一般以/开头。
创建hosts
设置权限
2rabbitMQ集群搭建
2.1环境准备
准备至少2个节点
在rabbit-node1节点执行 hostnamectl set‐hostname rabbit-node1
在rabbit-node1节点执行 hostnamectl set‐hostname rabbit-node2
在每个节点 vi /etc/hosts 添加
10.1.68.153 rabbit-node1
10.1.68.155 rabbit-node2
2.2统一cookie
将node1的cookie同步到node2中
scp /var/lib/rabbitmq/.erlang.cookie root@rabbit-node2:/var/lib/rabbitmq/
2.3打开防火墙开放端口
firewall-cmd --zone=public --add-port=25672/tcp --permanent
firewall-cmd --zone=public --add-port=4369/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
2.4集群添加节点
systemctl restart rabbitmq-server.service
rabbitmqctl stop_app
#节点2链接节点1 节点3链接节点2
rabbitmqctl join_cluster --ram rabbit@rabbit-node1
rabbitmqctl start_app
rabbitmq-plugins enable rabbitmq_management
2.5查看集群信息
rabbitmqctl cluster_status
3负载均衡HAProxy
3.1安装HProxy
mkdir /usr/local/haproxy
cp haproxy-2.4.4.tar.gz /usr/local/haproxy/
cd /usr/local/haproxy
tar -zxvf haproxy-2.4.4.tar.gz
cd haproxy-2.4.4
make TARGET=linux-glibc PREFIX=usr/local/haproxy/haproxy-2.4.4
make install PREFIX=/usr/local/haproxy/haproxy-2.4.4
vi /etc/profile
--------------
export HAPROXY_HOME=/usr/local/haproxy/haproxy-2.4.4
export PATH=$PATH:$HAPROXY_HOME/sbin
--------------
source /etc/profile
haproxy -v
mkdir /etc/haproxy
vi /etc/haproxy/haproxy.cfg
firewall-cmd --zone=public --add-port=5672/tcp --permanent
firewall-cmd --zone=public --add-port=8100/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
#启动命令
haproxy -f /etc/haproxy/haproxy.cfg
systemctl restart firewalld.service
3.2haproxy.cfg内容
#全局配置
global
# 日志输出配置、所有日志都记录在本机,通过 local0 进行输出
log 127.0.0.1 local0 info
# 最大连接数
maxconn 4096
# 改变当前的工作目录
chroot /usr/local/haproxy/haproxy-2.4.4
# 以指定的 UID 运行 haproxy 进程
uid 99
# 以指定的 GID 运行 haproxy 进程
gid 99
# 以守护进行的方式运行
daemon
# 当前进程的 pid 文件存放位置
pidfile /usr/local/haproxy/haproxy-2.4.4/haproxy.pid
# 默认配置
defaults
# 应用全局的日志配置
log global
# 使用4层代理模式,7层代理模式则为"http"
mode tcp
# 日志类别
option tcplog
# 不记录健康检查的日志信息
option dontlognull
# 3次失败则认为服务不可用
retries 3
# 每个进程可用的最大连接数
maxconn 2000
# 连接超时
timeout connect 5s
# 客户端超时
timeout client 120s
# 服务端超时
timeout server 120s
# 绑定配置
listen rabbitmq_cluster
bind :5671
# 配置TCP模式
mode tcp
# 采用加权轮询的机制进行负载均衡
balance roundrobin
# RabbitMQ 集群节点配置
server mq-node1 rabbit-node1:5672 check inter 5000 rise 2 fall 3 weight 1
server mq-node2 rabbit-node2:5672 check inter 5000 rise 2 fall 3 weight 1
# 配置监控页面
listen monitor
bind :8100
mode http
option httplog
stats enable
stats uri /stats
stats refresh 5s
4keeplived安装
上传keepalived 的rpm离线包
rpm -Uvh *.rpm
vi /etc/keepalived/keepalived.conf
chmod +x /etc/keepalived/haproxy_check.sh
su root
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
sysctl -p
systemctl start keepalived
systemctl enable keepalived
ip a
#测试 (查看虚拟ip查看是否成功)
yum -y install tcpdump
tcpdump -i eth0 vrrp -n
4.1主节点keepalived.conf
! Configuration File for keepalived
global_defs {
# 路由id,主备节点不能相同
router_id node1
notification_email {
# email 接收方
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# email 发送方
notification_email_from Alexandre.Cassen@firewall.loc
# 邮件服务器, smtp 协议
smtp_server 192.168.200.1
smtp_connect_timeout 30
#router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# 使用 unicast_src_ip 需要注释 vrrp_strict,而且也可以进行 ping 测试
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
# 自定义监控脚本
vrrp_script chk_haproxy {
# 脚本位置
script "/etc/keepalived/haproxy_check.sh"
# 脚本执行的时间间隔
interval 5
weight 10
}
vrrp_instance VI_1 {
# Keepalived的角色,MASTER 表示主节点,BACKUP 表示备份节点
state MASTER
# 指定监测的网卡,可以使用 ifconfig 进行查看
interface eth0
# 虚拟路由的id,主备节点需要设置为相同
virtual_router_id 51
# 优先级,主节点的优先级需要设置比备份节点高
priority 100
# 设置主备之间的检查时间,单位为秒
advert_int 1
# 如果两节点的上联交换机禁用了组播,则采用 vrrp 单播通告的方式
unicast_src_ip 10.1.68.153
#备机ip
unicast_peer {
10.1.68.155
}
# 定义验证类型和密码
authentication {
auth_type PASS
auth_pass 123456
}
# 调用上面自定义的监控脚本
track_script {
chk_haproxy
}
virtual_ipaddress {
10.1.68.253
}
}
4.2其他节点keepalived.conf
global_defs {
# 路由id,主备节点不能相同
router_id node2
notification_email {
# email 接收方
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# email 发送方
notification_email_from Alexandre.Cassen@firewall.loc
# 邮件服务器, smtp 协议
smtp_server 192.168.200.1
smtp_connect_timeout 30
vrrp_skip_check_adv_addr
# 使用 unicast_src_ip 需要注释 vrrp_strict,而且也可以进行 ping 测试
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
script "/etc/keepalived/haproxy_check.sh"
interval 5
weight 10
}
vrrp_instance VI_1 {
# BACKUP 表示备份节点
state BACKUP
# 指定监测的网卡
interface eth0
# 虚拟路由的id,主备节点需要设置为相同
virtual_router_id 51
# 优先级,备份节点要比主节点低
priority 50
advert_int 1
# 如果两节点的上联交换机禁用了组播,则采用 vrrp 单播通告的方式
unicast_src_ip 10.1.68.155
unicast_peer {
10.1.68.153
}
authentication {
auth_type PASS
auth_pass 123456
}
track_script {
chk_haproxy
}
virtual_ipaddress {
10.1.68.253
}
}
4.3haproxy_check.sh配置
#!/bin/bash
# 判断haproxy是否已经启动
if [ ${ps -C haproxy --no-header |wc -l} -eq 0 ] ; then
#如果没有启动,则启动
haproxy -f /etc/haproxy/haproxy.cfg
fi
#睡眠3秒以便haproxy完全启动
sleep 3
#如果haproxy还是没有启动,此时需要将本机的keepalived服务停掉,以便让VIP自动漂移到另外一台haproxy
if [ ${ps -C haproxy --no-header |wc -l} -eq 0 ] ; then
systemctl stop keepalived
fi
5SpringBoot整合rabbitMQ
5.1发布者(生产端)
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置 yml(基本信息配置)
server.port=8080
#这几个是默认配置。 不配也行。
#spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#spring.rabbitmq.addresses=81.71.140.7
spring.rabbitmq.virtual-host=/
spring.rabbitmq.addresses=10.1.68.153:5672,10.1.68.155:5672
定义交换机,队列以及绑定关系配置类
@Configuration
public class HelloWorldConfig {
@Bean
public Queue setQueue() {
return new Queue("rtio_real_01");
}
}
注入Rabbittemplate ,调用方法,完成消息发送
//helloWorld 直连模式
@ApiOperation(value="helloWorld发送接口",notes="直接发送到队列")
@GetMapping(value="/helloWorldSend")
public Object helloWorldSend(String message) throws AmqpException, UnsupportedEncodingException {
//设置部分请求参数
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);
//发消息
rabbitTemplate.send("rtio_real_01",new Message(message.getBytes("UTF-8"),messageProperties));
return "message sended : "+message;
}
5.2消费者(消费端)
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置yml (基本信息配置)
server.port=8080
#这几个是默认配置。 不配也行。
#spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#spring.rabbitmq.addresses=81.71.140.7
spring.rabbitmq.virtual-host=/
spring.rabbitmq.addresses=10.1.68.153:5672,10.1.68.155:5672
定义监听类,使用@RabbitListener注解完成队列监听
@RabbitListener(queues="rtio_real_01")
public void helloWorldReceive(String message) {
System.out.println("helloWorld模式 received message : " +message);
}
6rabbitMq工作模式
简单模式 HelloWorld
一个生产者、一个消费者,不需要设置交换机(使用默认的交换机)。
工作队列模式 Work Queue
一个生产者、多个消费者(竞争关系),不需要设置交换机(使用默认的交换机)。
发布订阅模式 Publish/subscribe
需要设置类型为 fanout的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列。
路由模式 Routing
需要设置类型为 direct 的交换机,交换机和队列进行绑定,并且指定 routing key,当发送消息到交换机后,交换机会根据 routing key 将消息发送到对应的队列。
通配符模式 Topic
需要设置类型为 topic 的交换机,交换机和队列进行绑定,并且指定通配符方式的 routing key,当发送消息到交换机后,交换机会根据 routing key 将消息发送到对应的队列。
RPC 远程调用模式(远程调用,不太算 MQ,不使用)
7rabbitMQ高级特性
消息的可靠投递:
confirm 确认模式
- 设置ConnectionFactory的publisher-confirms=“true” 开启 确认模式
- 发布者将消息发送到mq的exchange中 判断 消息是否发送成功 返回confirmCallback
- 调用 rabbitTemplate.setConfirmCallback 设置回调函数 当消息发送到exchange后回调confirm方法 在方法中判断ack 如果为true 则发送成功 如果false 则发送失败 ,需要处理
return 退回模式
- 设置 Connectionfactory的publisher-returns="true"开启 退回模式
- mq的消息从exchange 发送queue中 发送失败则返回 returnCallback
- 调用rabbitTemplate.setReturnCallBack 设置退回函数 当消息从exchange路由到queue失败后,如果设置了rabbitTemplate.setMandatory(true) 参数 则会将消息退回给发布者 并执行回调函数returnedMessage
ack确认方式:
自动确认
- acknowledge=“none”
- 消息接收 自动确认收到 ,将相应的message从rabbitMQ 的消息缓存移除
手动确认
- acknowledge=“manual”
- 消息接收 业务处理成功后 ,调用 channel.basicAck();方法 手动确认
异常确认
- acknowledge=“auto”
- 消息接收 业务处理过程中 出现异常 调用 channel.basicNack()方法 让Mq自动重新发送消息
消费限流
- 用户请求大于服务器承受能力 mq设置每秒限流 后台系统每秒从mq中处理系统承受的住的最大请求数量
- 在《rabbit:listener-container》中配置prefetch属性设置消费端一次拉去多少消息
- 消费段的ack确认模式一定要设置为 “手动确认”acknowledge=“manual”
TTL
- TTL (存活时间/过期时间) 当消息到达存活时间还没有没消费,会被自动清除
TTL设置过期是将两种方式
1单个消息设置过期时间 :expiration ,单位:ms(毫秒)
2整个队列(Queue)设置过期时间 : x-message-ttl,单位是ms(毫秒),
注释:如果两个都设置了 ,以时间短的为准
死信队列
- 1DLX 当消息成为Deadmessage后,可以被重新发送到另一个交换机,这个交换机就是DLX
- 队列设置参数 x-dead-letter-exchange 和 xdead-letter-routing-key 设置 绑定死信队列
成为死信的三种情况
1队列消息长度到达限制
2消费者拒绝消费消息,basicNack/basicReject 并且不把消息重新放入原目标队列,requeue=false
3原队列存在消息过期设置,消息到达超时时间未被消费
延时消息
- TTL设置消息过期时间 过期时间过了进入死信模式 通过别的queue完成延时消息