RabbitMQ之项目中实战
说了那么多,还不是为了在项目中进行实战吗,在实践中检验真理,不然我学他干嘛,不能解决项目中的实际问题的技术都是耍流氓。。。
一、后台管理系统发送消息
瞎咧咧:后台管理系统发送消息到交换机中,然后通知其他系统进行相应的操作,这岂不是美滋滋
1、导入依赖
注意:这里使用的是spring封装的rabbitMQ,只需要导入这一个依赖就可以了,这个版本有点老了
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
2、队列和交换机的绑定关系
实现:
2.1 在配置文件中将队列和交换机完成绑定
2.2 可以在管理界面中完成绑定
2.2.1 绑定关系如果发生变化,需要修改配置文件,并且服务需要重启
2.2.2 管理更加灵活
2.2.3 更容易对绑定关系的权限管理,流程管理
3、配置文件
注意:这个单独的放在一个配置文件中 applicationContext-rabbitmq.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <!-- 定义RabbitMQ的连接工厂 -->
<rabbit:connection-factory id="connectionFactory"
host="${rabbitmq.host}" port="${rabbitmq.port}" username="${rabbitmq.username}"
password="${rabbitmq.password}" virtual-host="${rabbitmq.vhost}" /> <!-- 管理 -->
<rabbit:admin connection-factory="connectionFactory" /> <!-- 定义交换机 -->
<rabbit:topic-exchange name="TAOTAO-ITEM-EXCHANGE"
auto-declare="true" durable="true" /> <!-- 定义模板 -->
<rabbit:template id="rabbitTemplate"
connection-factory="connectionFactory" exchange="TAOTAO-ITEM-EXCHANGE" /> </beans>
4、具体代码实现
注意:这个实现是把发送消息的代码抽离出来了,具体发送的内容包括商品的id、操作类型(就是具体的删除、更新还是插入操作)、时间戳,那个ObjectMapper是jackson jar包中转json的类
@Autowired
private RabbitTemplate RabbitTemplate; private static final ObjectMapper MAPPER = new ObjectMapper(); private void sendMsg(Long itemId, String type) {
try {
// 发送消息到MQ队列中,并通知其他系统
Map<String, Object> msg = new HashMap<String, Object>();
msg.put("itemId", itemId);
msg.put("type", type);
msg.put("date", System.currentTimeMillis());
this.RabbitTemplate.convertAndSend("item." + type, MAPPER.writeValueAsString(msg));
} catch (Exception e) {
e.printStackTrace();
}
} //例如:更新操作中,在方法的最后就直接调用此方法就可以了
// 发送消息到MQ队列中,并通知其他系统
sendMsg(item.getId(), "update");
二、 前台系统接收消息
1、导入依赖
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
2、配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <!-- 定义RabbitMQ的连接工厂 -->
<rabbit:connection-factory id="connectionFactory"
host="${rabbitmq.host}" port="${rabbitmq.port}" username="${rabbitmq.username}"
password="${rabbitmq.password}" virtual-host="${rabbitmq.vhost}" /> <!-- 管理 -->
<rabbit:admin connection-factory="connectionFactory" /> <!-- 定义队列 -->
<rabbit:queue name="TAOTAO-WEB-ITEM-QUEUE" auto-declare="true"
durable="true" /> <!-- 消费者对象 -->
<bean id="itemMQHandler" class="com.taotao.web.mq.handler.ItemMQHandler" /> <!-- 监听队列 -->
<rabbit:listener-container
connection-factory="connectionFactory">
<rabbit:listener ref="itemMQHandler" method="execute"
queue-names="TAOTAO-WEB-ITEM-QUEUE" />
</rabbit:listener-container> </beans>
3、具体处理逻辑
@Autowired
private RedisService redisService; private static final ObjectMapper MAPPER = new ObjectMapper(); /**
* 删除缓存中的数据,完成数据同步
*
* @param msg
*/
public void execute(String msg) {
try {
JsonNode jsonNode = MAPPER.readTree(msg);
Long itemId = jsonNode.get("itemId").asLong();
String key = ItemService.REDIS_KEY + itemId;
this.redisService.del(key);
} catch (Exception e) {
e.printStackTrace();
} }
4、在界面管理工具中完成绑定关系
注意:这个操作是在 Exchanges菜单下面完成的

三、搜索系统中接收消息
1、导入依赖
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
2、配置文件
注意:基本上是复制粘贴那个前台系统的
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <!-- 定义RabbitMQ的连接工厂 -->
<rabbit:connection-factory id="connectionFactory"
host="${rabbitmq.host}" port="${rabbitmq.port}" username="${rabbitmq.username}"
password="${rabbitmq.password}" virtual-host="${rabbitmq.vhost}" /> <!-- 管理 -->
<rabbit:admin connection-factory="connectionFactory" /> <!-- 定义队列 -->
<rabbit:queue name="TAOTAO-SEARCH-ITEM-QUEUE" auto-declare="true"
durable="true" /> <!-- 消费者对象 -->
<bean id="itemMQHandler" class="com.taotao.search.mq.handler.ItemMQHandler" /> <!-- 监听队列 -->
<rabbit:listener-container
connection-factory="connectionFactory">
<rabbit:listener ref="itemMQHandler" method="execute"
queue-names="TAOTAO-SEARCH-ITEM-QUEUE" />
</rabbit:listener-container> </beans>
3、业务逻辑处理
@Service
public class ItemService { @Autowired
private ApiService apiService; @Value("${TAOTAO_MANAGE_URL}")
private String TAOTAO_MANAGE_URL; private static final ObjectMapper MAPPER = new ObjectMapper(); public Item queryById(Long itemId){
try {
String url = TAOTAO_MANAGE_URL + "/rest/api/item/"+itemId;
String jsonData = this.apiService.doGet(url);
if(StringUtils.isNotEmpty(jsonData)){
return MAPPER.readValue(jsonData, Item.class);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public class ItemMQHandler {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Autowired
private HttpSolrServer httpSolrServer;
@Autowired
private ItemService itemService;
/**
* 处理消息,新增、修改、删除的消息,将商品数据同步到solr中
* 消息中并没有上商品的信息,需要通过商品id通过后台接口进行查询
*
* @param msg
*/
public void execute(String msg){
try {
JsonNode jsonNode = MAPPER.readTree(msg);
Long itemId = jsonNode.get("itemId").asLong();
String type = jsonNode.get("type").asText();
if(StringUtils.equals(type, "insert") || StringUtils.equals(type, "update")){
Item item = this.itemService.queryById(itemId);
this.httpSolrServer.addBean(item);
this.httpSolrServer.commit();
}else if(StringUtils.equals(type, "delete")){
this.httpSolrServer.deleteById(String.valueOf(itemId));
this.httpSolrServer.commit();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
4、在界面管理工具中完成绑定关系

四、总结
使用MQ实现商品数据的同步优势:
1、 降低系统间耦合度
2、 便于管理数据的同步
RabbitMQ之项目中实战的更多相关文章
- rabbitmq在ios中实战采坑
1. rabbitmq在ios中实战采坑 1.1. 问题 ios使用rabbitmq连接,没过多久就断开,并报错.且用android做相同的步骤并不会报错,错误如下 Received connecti ...
- okHttp,greenDao,EventBus组合框架项目中实战
okHttp,greenDao,EventBus组合封装 zzyandroid 介绍 开门见山,大体思路是在Activity中启动服务,通过服务创建Http请求,请求处理结果通过EventBus通知前 ...
- Redis和RabbitMQ在项目中的使用
一:Redis的使用 1.先引入pom.xml的依赖 <dependency> <groupId>redis.clients</groupId> <artif ...
- StrangeIoc框架学习----在项目中实战
最近,因为公司的项目一直在研究StrangeIoc框架,小有所得,略作记录. StrangeIoc是一款基于MVCS的一种框架,是对MVC思想的扩展,是专门针对unity开发的一款框架,非常好用. 一 ...
- C# RabbitMQ延迟队列功能实战项目演练
一.需求背景 当用户在商城上进行下单支付,我们假设如果8小时没有进行支付,那么就后台自动对该笔交易的状态修改为订单关闭取消,同时给用户发送一份邮件提醒.那么我们应用程序如何实现这样的需求场景呢?在之前 ...
- 【一起学设计模式】观察者模式实战:真实项目中屡试不爽的瓜娃EventBus到底如何实现观察者模式的?
申明 本文章首发自本人公众号:壹枝花算不算浪漫,如若转载请标明来源! 感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫 22.jpg 前言 之前出过一个设计模式的系列文章,这些文章和其他讲设计模式的文 ...
- 实战派 | Java项目中玩转Redis6.0客户端缓存!
原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是Hydra. 在前面的文章中,我们介绍了Redis6.0中的新特性客户端缓存client-side caching,通过tel ...
- MVC项目中WebViewPage的实战应用
由于公司的项目可能会卖到国外,所以需要支持多语言.今天我就在目前的项目中实现了多语言功能,下面记录我的具体实现. 1.相信很多朋友在用MVC做项目时候,都会遇到“视图必须派生自 WebViewPage ...
- 【知识必备】浅淡MVP在Android项目中的实战演习,让代码结构更简单~
一.写在前面 讲道理,这次是真的笔者很久都没有更新blog了,主要最近维护的框架问题也是层出不穷,而且对技术交流群的解答也让我身心疲惫,所以在这里跟关注我的人说声抱歉,没有定期给你们带来福利,那么这里 ...
随机推荐
- hdu 5119 (类似于划分数的状态定义) (DP中的计数问题)
题目描述:求n个数中异或值大于m的方案数有多少个? 设状态f[i][j]代表前i个数异或值为j的方案数有f[i][j]种,那么对于j来说要么选第i个数与前面的i-1个数中的某些数构成j,f[i-1][ ...
- c语言和c++栈的简单实现以及构造器的原理
也就是训练将原来的c语言 用类表示出来.. 关于构造器: //1与类名相同 没有返回值 被系统生成对象时自动调用,用于初始化 //2 可以有参数 构造器重载 默认参数 //3 重载和默认不能同时存在, ...
- bzoj 2257[Jsoi2009]瓶子和燃料 数论/裴蜀定理
题目 Description jyy就一直想着尽快回地球,可惜他飞船的燃料不够了. 有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子来换.jyy 的飞船上共有 N个瓶子(1< ...
- A - Supercentral Point CodeForces - 165A
One day Vasya painted a Cartesian coordinate system on a piece of paper and marked some set of point ...
- MoveTo和LineTo函数的意思
这是个画线函数, moveto是移动到某个坐标,lineto是从当前坐标, 移动的某个坐标连接早当前坐标.这两个函数加起来就是画一条直线.
- head first python /chapter7 web(python 3 转 python 2.7)
前言 书中使用的是python3,我这里使用的是python2.7 Web 的目录树 webapp/ ├── cgi-bin │ ├── athletelist.py │ ├── athletemod ...
- [C++11新特性] 智能指针详解
动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极为困难的.有时我们会忘记释放内存产生内存泄漏,有时提前释放了内存,再使用指针去引用内存就会报错. 为了更容易(同时也更安全)地使用动态内存, ...
- New Article For Test
\[ a ^ 2 + b ^ 2 ~-~ 2 \times a \times b \times cos~ \theta = c ^ 2 \] #include<stdio.h> int m ...
- composer 加快更新速度
一.使用代理 set http_proxy=http://127.0.0.1:8087 //Windows export http_proxy=http://127.0.0.1:8087 //linu ...
- APP多渠道打包
多渠道打包的概念: 打包是指使用证书文件对app签名生成一个apk文件. 多渠道打包指的就是我们的app在开发完成之后需要投放到不同的市场,比如说Google市场.百度市场等,为了统计应用在各个市场的 ...