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了,主要最近维护的框架问题也是层出不穷,而且对技术交流群的解答也让我身心疲惫,所以在这里跟关注我的人说声抱歉,没有定期给你们带来福利,那么这里 ...
随机推荐
- gcc编译系统
一. C语言编译过程 C语言的编译过程可分为四个阶段: 1.预处理(Preprocessing) 对源程序中的伪指令(即以#开头的指令)和特殊符号进行处理的过程. 伪指令包括:1)宏定义指令: 2)条 ...
- bzoj4289 PA2012 Tax——点边转化
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 好巧妙的转化!感觉自己难以想出来... 参考了博客:https://blog.csdn ...
- Bootstrap 垂直(默认)表单
在建立asp.net mvc视图中,默认的表单是垂直表单,与vs 自动创建的T4模板是水平表单,相比较,没有了<div class="form-horizontal"> ...
- SQL Server 日期转换成字符串
参考网址:http://wenku.baidu.com/view/970c6c1655270722192ef70e.html 下面是常用的几个 --返回06-27-13 ), ) --2013-06- ...
- LUR和缺页次数
缺页:缺页中断就是要访问的页不在主存,需要操作系统将其调入主存后再进行访问. LRU(Least recently used)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问 ...
- bzoj 4606: [Apio2008]DNA【dp】
写题五分钟读题两小时系列-- 看懂题的话不算难,然而我去看了大佬的blog才看懂题-- 题目大意是:一个原字符串,其中有一种通配符,合法串的定义是这个串(不含通配符))可以匹配原串并且这个串最多分成k ...
- bzoj 2508: 简单题【拉格朗日乘数法】
大概是对于f(x,y)求min,先把x看成常数,然后得到关于y的一元二次方程,然后取一元二次极值把y用x表示,再把x作为未知数带回去化简,最后能得到一个一元二次的式子,每次修改这个式子的参数即可. 智 ...
- bzoj 4819: [Sdoi2017]新生舞会【二分+最小费用最大流】
如果\( b[i]==0 \)那么就是裸的费用流/KM,当然KM快一些但是为什么不写KM呢因为我不会打板子了 考虑二分答案,那么问题变成了判定问题. \[ ans=\frac {a_1+a_2+... ...
- 题解报告:hdu 4704 Sum(扩展欧拉定理)
Problem Description Sample Input 2 Sample Output 2 Hint 1. For N = 2, S(1) = S(2) = 1. 2. The input ...
- Android偏好设置(2)为应用定义一个偏好设置xml
1.Defining Preferences in XML Although you can instantiate new Preference objects at runtime, you sh ...