1 结构
1.0 RabbitMQ结构及流程图
1.2 组件
- (1)Broker
RabbitMQ服务器,用于对外提供服务,客户端(生产者及消费者)使用RabbitMQ消息中间件均需要连接到Broker,使用Rabbit的消息队列服务 - (2)Virtual Host
Broker(服务器)的虚拟机,提供多租户,实现租户的权限分离 - (3)Publiser
消息生产者 - (4)Connection
客户端与RabbitMQ服务器连接服务(TCP),其中Connection中可建立多个Chennel,在生成和消费消息过程中,客户端无需与服务器建立多次TCP连接,通过共用Connection中的Channel(虚拟TCP连接),降低多次TCP连接及断开的性能消耗 - (5)Exchange
消息交换器,指定消息发送规则及发送到指定的消息队列 - (6)Binding
绑定,即把交换器与消息队列进行绑定,用于队列向队列存储消息 - (7)Queue
消息队列,存储消息 - (8)Consumer
消息消费者 - (9)WebServiceClient
Web服务,对于RabbitMQ而言是客户端
2 工作过程
2.1 部署RabbitMQ
- 安装erlang
sudo apt-get install erlang-nox
- 安装RabbitMQ
sudo apt-get install rabbitmq-server
- 查看RabbitMQ状态
service rabbitmq-server status
- 添加用户
sudo rabbitmqctl add_user admin admin
- 用户授权
sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
- 开启Web端监控
sudo rabbitmq-plugins enable rabbitmq_management
- 登录RabbitMQ管理平台
http://localhost:15672
- RabbitMQ密令
序号 | 描述 | 命令 |
---|---|---|
1 | 启动 | sudo rabbitmq-server start |
2 | 停止 | sudo rabbitmq-server stop |
3 | 重启 | sudo rabbitmq-server restart |
4 | 状态 | sudo rabbitmqctl status |
2.2 消息传递过程
RabbitMQ消息传递流程如图1所示,详细解析如下:
- (1)生产消息客户端通过Connection与Broker连接
- (2)客户端中的租户信息与Virtual Host匹配,连接到Virtual Host
- (3)生产的消息经过交换器
- (4)交换器绑定到特定的消息队列
- (5)生产者生产的消息存储到消息队列
- (6)消费者通过Connection与Broker连接
- (7)消费者通过配置的队列信息,从消息队列中获取数据
2.3 租户及队列配置信息
- 租户:admin
- 队列:testqueue
- 交换机方式:dircet
{"rabbit_version":"3.6.10","users":[{"name":"admin","password_hash":"1/hXieLSCl6dpkUWcXhBXvCq1R0BOKSEjpo8GtX9PMzw1MQJ","hashing_algorithm":"rabbit_password_hashing_sha256","tags":"administrator"},{"name":"guest","password_hash":"Wy4saet6gG7VqxTMLnaXdrgnWwUyz3npPPuQVEgb7wsuP5cr","hashing_algorithm":"rabbit_password_hashing_sha256","tags":"administrator"}],"vhosts":[{"name":"/"}],"permissions":[{"user":"guest","vhost":"/","configure":".*","write":".*","read":".*"},{"user":"admin","vhost":"/","configure":".*","write":".*","read":".*"}],"parameters":[],"global_parameters":[{"name":"cluster_name","value":"rabbit@xdq"}],"policies":[],"queues":[{"name":"testqueue","vhost":"/","durable":true,"auto_delete":false,"arguments":{}}],"exchanges":[],"bindings":[]}
2.4 交换机消息传递方式
- 直连direct(默认)
消息队列直接绑定到交换机上,交换机将消息发送至与特定的路由完全匹配的队列中,如特定消息队列为queue1,则只有queue1队列可以接收到消息,其他队列无法收到消息 - 主题topic
主题交换器,交换器将消息发送至与路由匹配模式相同的所有队列,如队列模式(ROUTING_KEY)为test.queue,交换器将分发消息至*.queue
,test.queue
,*.*
,及#.test.queue
,其中,*为任意词组,#为匹配0个或多个词组 - 标题headers
消息体的header匹配(忽略) - 分发fanout
广播交换器,此时的ROUTING_KEY无效,因为交换机会将消息发送给所有绑定的队列
2.5 消息确认
RabbitMQ消息确认方式有三种,即不确认(none),手动确认(manual),自动确认(auto),若客户端不确认接收到消息,RabbitMQ不会清除当时已被消费过的消息,知道客户端消息确认后,才会将消息队列中的消息移除(remove),否则,每次只要客户端重连到RabbitMQ都会重新收到消息队列中的消息.
-
未确认消息
图2.5 客户端未确认接受的消息 -
已确认消息
2.5.1 手动确认
- 配置文件
spring:
profiles: dev
application:
name: quartz-cluster-node-second
rabbitmq:
host: localhost
port: 5672
username: admin
password: admin
publisher-confirms: true
publisher-returns: true
listener:
direct:
acknowledge-mode: manual
simple:
acknowledge-mode: manual
- 接收消息及手动确认
package com.company.web.service;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.beans.factory.annotation.Autowired;
import com.rabbitmq.client.Channel;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import java.util.Map;
/**
* @author xindaqi
* @description 消息消费者
* @date 2020-06-29
*/
@Component
public class MQReceiveService {
@Autowired
private AmqpTemplate template;
@Autowired
private RabbitTemplate rabbitTempalte;
@RabbitListener(queues="testqueue")
public String receive(String msg, @Headers Map<String, Object> headers, Channel channel){
try{
System.out.println("msg:"+msg);
Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
// 消息手动确认
channel.basicAck(deliveryTag, false);
//TODO 写入数据库等其他操作
return msg;
}catch(Exception e){
e.printStackTrace();
}
return "ERROR";
}
}
2.2 自动确认消息
- 配置信息
spring:
profiles: dev
application:
name: quartz-cluster-node-second
rabbitmq:
host: localhost
port: 5672
username: admin
password: admin
publisher-confirms: true
publisher-returns: true
listener:
direct:
acknowledge-mode: auto
simple:
acknowledge-mode: auto
[参考文献]
[1]https://my.oschina.net/u/2364788/blog/2875902
[2]https://blog.csdn.net/yangshengwei230612/article/details/105913074
[3]https://www.jianshu.com/p/24e541170ace
[4]https://blog.csdn.net/xiaobaixiongxiong/article/details/89071917
[5]http://www.uml.org.cn/zjjs/201909092.asp
[6]https://www.cnblogs.com/ybjourney/p/12130985.html
[7]https://www.cnblogs.com/gne-hwz/p/10717473.html
[8]https://www.cnblogs.com/nizuimeiabc1/p/9397326.html
[9]https://blog.csdn.net/Xin_101/article/details/107026296