Commit 55de25e3 authored by 冯景珉's avatar 冯景珉

Update RabbitMq消息队列.md

parent 379568b3
# RabbitMq消息队列 # RabbitMq消息队列
## 1.简介 ## 1.简介
融租易 的消息系统提供`唯一``广播`以及`主题`三种模式,实现方式为 RabbitMQ。 融租易 的消息系统提供`唯一``广播`以及`主题`三种模式,实现方式为 RabbitMQ。
### 1.1 RabbitMQ介绍 ### 1.1 RabbitMQ介绍
RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦。rabbitmq多应用于批量数据异步处理、并行任务串行化,高负载任务的负载均衡等 重量级,高并发,异步高可靠性场景。 RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦。rabbitmq多应用于批量数据异步处理、并行任务串行化,高负载任务的负载均衡等 重量级,高并发,异步高可靠性场景。
### 1.2 配置rabbit ### 1.2 配置rabbit
(1)用户要先在 `applicationContext-rabbitmq.xml` 中 添加`<beans:import resource="rabbitmq.xml"/>` (1)用户要先在 `applicationContext-rabbitmq.xml` 中 添加`<beans:import resource="rabbitmq.xml"/>`
(2)然后在`config.properties`中自行添加mq相关的配置如图: (2)然后在`config.properties`中自行添加mq相关的配置如图:
![](/assets/config.png) ![](/assets/config.png)
## 2 自定义消息 ## 2 自定义消息
在融租易的接口管理的消息队列模块定义功中,提供了自定义队列和交换机的功能,可以根据配置实现自定义的队列和交换机的匹配,避免了在xml中的繁琐配置。 在融租易的接口管理的消息队列模块定义功中,提供了自定义队列和交换机的功能,可以根据配置实现自定义的队列和交换机的匹配,避免了在xml中的繁琐配置。
### 2.1 定义交换机 ### 2.1 定义交换机
在接口管理的消息队列定义模块中,首先进行交换机的定义,界面如图:![](/assets/exchange.png)注意: 在接口管理的消息队列定义模块中,首先进行交换机的定义,界面如图:![](/assets/exchange.png)注意:
交换机名称不可以重复定义,一个交换机可以对应多个队列。 交换机名称不可以重复定义,一个交换机可以对应多个队列。
交换机类型可以分为**direct\(唯一模式\),topic\(主题模式\),fanout\(广播模式\),**rabbitmq会根据你的交换机类型和定义的路由键,完成消息的转发**。** 交换机类型可以分为**direct\(唯一模式\),topic\(主题模式\),fanout\(广播模式\),**rabbitmq会根据你的交换机类型和定义的路由键,完成消息的转发**。**
持久化(durable):交换机在服务关闭后,清除与否。 持久化(durable):交换机在服务关闭后,清除与否。
自动删除(auto-delete):当交换机没有队列绑定时,删除与否。 自动删除(auto-delete):当交换机没有队列绑定时,删除与否。
### 2.2 定义队列和路由键 ### 2.2 定义队列和路由键
定义完交换机后,你还需要定义你的队列和相应的匹配模式(既路由键)界面如图:![](/assets/queue.png)注意: 定义完交换机后,你还需要定义你的队列和相应的匹配模式(既路由键)界面如图:![](/assets/queue.png)注意:
队列名称不可以重复,但是一个队列可以对应多个交换机。 队列名称不可以重复,但是一个队列可以对应多个交换机。
匹配模式(routing-key):此处的匹配模式即为路由键 匹配模式(routing-key):此处的匹配模式即为路由键
持久化(durable):队列在服务关闭后,清除与否。 持久化(durable):队列在服务关闭后,清除与否。
自动删除(auto-delete):当队列没有绑定交换机时,删除与否。 自动删除(auto-delete):当队列没有绑定交换机时,删除与否。
私有队列(exclusive): 仅创建者可以使用的私有队列,断开后自动删除. 私有队列(exclusive): 仅创建者可以使用的私有队列,断开后自动删除.
## 3 发送消息/接收消息 ## 3 发送消息/接收消息
在融租易中,消息的发送和接收都提供了可以直接调用的接口 在融租易中,消息的发送和接收都提供了可以直接调用的接口
### 3.1 消息的匹配规则 ### 3.1 消息的匹配规则
1.唯一模式\(**Direct Exchange**\): 1.唯一模式\(**Direct Exchange**\):
处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “hls”,则只有被标记为“hls”的消息才被转发,不会转发hls.sys,也不会转发hls.fnd,只会转发hls。 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “hls”,则只有被标记为“hls”的消息才被转发,不会转发hls.sys,也不会转发hls.fnd,只会转发hls。
2.广播模式\(**Fanout Exchange**\): 2.广播模式\(**Fanout Exchange**\):
不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。 不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
3.主题模式\(**Topic Exchange**\): 3.主题模式\(**Topic Exchange**\):
将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“\#”匹配一个或多个词,符号“\*”匹配不多不少一个词。因此“hls.\#”能够匹配到“hls.sys.adaptor”,但是“hls.\*” 只会匹配到“hls.sys”。 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“\#”匹配一个或多个词,符号“\*”匹配不多不少一个词。因此“hls.\#”能够匹配到“hls.sys.adaptor”,但是“hls.\*” 只会匹配到“hls.sys”。
### 3.2 发送消息 ### 3.2 发送消息
融租易中,通过调用`IRabbitProducerService`接口中的`sendMessage(JSONObject json)`方法,来实现消息的发送 融租易中,通过调用`IRabbitProducerService`接口中的`sendMessage(JSONObject json)`方法,来实现消息的发送
注意: 注意:
接口调用时必须使用spring中的注入方式。 接口调用时必须使用spring中的注入方式。
json必须按照格式如: json必须按照格式如:
```json ```json
{ {
"header":{ "header":{
"orgCode":"hls", "orgCode":"hls",
"apiName":"demoMQ", "apiName":"demoMQ",
"sysCode":"fnd", "sysCode":"fnd",
"routingKey":"hls", "routingKey":"hls",
"respCode":"sys", "respCode":"sys",
"respMsg":"recived", "respMsg":"recived",
"transDate":"Thu Jul 27 2017 10:47:17 GMT+0800 (CST)", "transDate":"Thu Jul 27 2017 10:47:17 GMT+0800 (CST)",
"transNo":"123" "transNo":"123"
}, },
"busiData":{ "busiData":{
"contractId":1 "contractId":1
}, },
"securityInfo":{ "securityInfo":{
"userName":"hd001", "userName":"hd001",
"userPassword":"123456" "userPassword":"123456"
} }
} }
``` ```
### 3.3 接收消息 ### 3.3 接收消息
融租易中对消息的接收进行了统一处理,只需要单独编写业务的实现类即可(此处必须实现IRabbitMessageConsumerService接口),消息会先被内部的消息监听接口统一处理,然后再根据消息中的apiName找到对应的接口实现类,调用其中的process方法。 融租易中对消息的接收进行了统一处理,只需要单独编写业务的实现类即可(此处必须实现IRabbitMessageConsumerService接口),消息会先被内部的消息监听接口统一处理,然后再根据消息中的apiName找到对应的接口实现类,调用其中的process方法。
示例代码: 示例代码:
```java ```java
@Service @Service
public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService { public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService {
@Autowired(required = false) @Autowired(required = false)
private IRabbitProducerService iRabbitProducerService;//消息发送类 private IRabbitProducerService iRabbitProducerService;//消息发送类
@Autowired @Autowired
private IXXXService service;//业务类 private IXXXService service;//业务类
@Override @Override
public String getApiName() { public String getApiName() {
return "demoMQ"; return "demoMQ";
} }
@Override @Override
public void process(JSONObject json) { public void process(JSONObject json) {
//业务处理 //业务处理
service.doSomething(json) service.doSomething(json)
//返回消息 //返回消息
ResponseInfo responseInfo = null; ResponseInfo responseInfo = null;
try { try {
responseInfo = RabbitMQUtils.getResposeInfo(json); responseInfo = RabbitMQUtils.getResposeInfo(json);
} catch (ParseException e) { } catch (ParseException e) {
e.printStackTrace(); e.printStackTrace();
} }
JSONObject respose= new JSONObject().fromObject(responseInfo); JSONObject respose= new JSONObject().fromObject(responseInfo);
iRabbitProducerService.sendMessage(respose); iRabbitProducerService.sendMessage(respose);
} }
} }
``` ```
### ###
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment