说了那么多,还不是为了在项目中进行实战吗,在实践中检验真理,不然我学他干嘛,不能解决项目中的实际问题的技术都是耍流氓。。。

一、后台管理系统发送消息

瞎咧咧:后台管理系统发送消息到交换机中,然后通知其他系统进行相应的操作,这岂不是美滋滋

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之项目中实战的更多相关文章

  1. rabbitmq在ios中实战采坑

    1. rabbitmq在ios中实战采坑 1.1. 问题 ios使用rabbitmq连接,没过多久就断开,并报错.且用android做相同的步骤并不会报错,错误如下 Received connecti ...

  2. okHttp,greenDao,EventBus组合框架项目中实战

    okHttp,greenDao,EventBus组合封装 zzyandroid 介绍 开门见山,大体思路是在Activity中启动服务,通过服务创建Http请求,请求处理结果通过EventBus通知前 ...

  3. Redis和RabbitMQ在项目中的使用

    一:Redis的使用 1.先引入pom.xml的依赖 <dependency> <groupId>redis.clients</groupId> <artif ...

  4. StrangeIoc框架学习----在项目中实战

    最近,因为公司的项目一直在研究StrangeIoc框架,小有所得,略作记录. StrangeIoc是一款基于MVCS的一种框架,是对MVC思想的扩展,是专门针对unity开发的一款框架,非常好用. 一 ...

  5. C# RabbitMQ延迟队列功能实战项目演练

    一.需求背景 当用户在商城上进行下单支付,我们假设如果8小时没有进行支付,那么就后台自动对该笔交易的状态修改为订单关闭取消,同时给用户发送一份邮件提醒.那么我们应用程序如何实现这样的需求场景呢?在之前 ...

  6. 【一起学设计模式】观察者模式实战:真实项目中屡试不爽的瓜娃EventBus到底如何实现观察者模式的?

    申明 本文章首发自本人公众号:壹枝花算不算浪漫,如若转载请标明来源! 感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫 22.jpg 前言 之前出过一个设计模式的系列文章,这些文章和其他讲设计模式的文 ...

  7. 实战派 | Java项目中玩转Redis6.0客户端缓存!

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是Hydra. 在前面的文章中,我们介绍了Redis6.0中的新特性客户端缓存client-side caching,通过tel ...

  8. MVC项目中WebViewPage的实战应用

    由于公司的项目可能会卖到国外,所以需要支持多语言.今天我就在目前的项目中实现了多语言功能,下面记录我的具体实现. 1.相信很多朋友在用MVC做项目时候,都会遇到“视图必须派生自 WebViewPage ...

  9. 【知识必备】浅淡MVP在Android项目中的实战演习,让代码结构更简单~

    一.写在前面 讲道理,这次是真的笔者很久都没有更新blog了,主要最近维护的框架问题也是层出不穷,而且对技术交流群的解答也让我身心疲惫,所以在这里跟关注我的人说声抱歉,没有定期给你们带来福利,那么这里 ...

随机推荐

  1. hdu 5119 (类似于划分数的状态定义) (DP中的计数问题)

    题目描述:求n个数中异或值大于m的方案数有多少个? 设状态f[i][j]代表前i个数异或值为j的方案数有f[i][j]种,那么对于j来说要么选第i个数与前面的i-1个数中的某些数构成j,f[i-1][ ...

  2. c语言和c++栈的简单实现以及构造器的原理

    也就是训练将原来的c语言 用类表示出来.. 关于构造器: //1与类名相同 没有返回值 被系统生成对象时自动调用,用于初始化 //2 可以有参数 构造器重载 默认参数 //3 重载和默认不能同时存在, ...

  3. bzoj 2257[Jsoi2009]瓶子和燃料 数论/裴蜀定理

    题目 Description jyy就一直想着尽快回地球,可惜他飞船的燃料不够了. 有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子来换.jyy 的飞船上共有 N个瓶子(1< ...

  4. A - Supercentral Point CodeForces - 165A

    One day Vasya painted a Cartesian coordinate system on a piece of paper and marked some set of point ...

  5. MoveTo和LineTo函数的意思

    这是个画线函数, moveto是移动到某个坐标,lineto是从当前坐标, 移动的某个坐标连接早当前坐标.这两个函数加起来就是画一条直线.

  6. head first python /chapter7 web(python 3 转 python 2.7)

    前言 书中使用的是python3,我这里使用的是python2.7 Web 的目录树 webapp/ ├── cgi-bin │ ├── athletelist.py │ ├── athletemod ...

  7. [C++11新特性] 智能指针详解

    动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极为困难的.有时我们会忘记释放内存产生内存泄漏,有时提前释放了内存,再使用指针去引用内存就会报错. 为了更容易(同时也更安全)地使用动态内存, ...

  8. New Article For Test

    \[ a ^ 2 + b ^ 2 ~-~ 2 \times a \times b \times cos~ \theta = c ^ 2 \] #include<stdio.h> int m ...

  9. composer 加快更新速度

    一.使用代理 set http_proxy=http://127.0.0.1:8087 //Windows export http_proxy=http://127.0.0.1:8087 //linu ...

  10. APP多渠道打包

    多渠道打包的概念: 打包是指使用证书文件对app签名生成一个apk文件. 多渠道打包指的就是我们的app在开发完成之后需要投放到不同的市场,比如说Google市场.百度市场等,为了统计应用在各个市场的 ...