生活就像海洋
只有意志坚强的人
才能到达彼岸。
文章目录
ActiveMQ整合Spring
关于ActiveMQ消息队列配置可查看ActiveMQ消息队列的配置和使用操作
涉及知识点:
Solr索引库,Redis缓存数据库,ActiveMQ消息队列,Dubbo+Zookeeper实现负载均衡和分布式架构,Maven项目管理工具,SSM三大框架,Nginx服务器实现图片存储。
1,准备工作
这边项目使用消息队列的场景是:
原始方法:添加商品后,需要导入索引库solr进行搜索索引,而导入索引库非常麻烦,使用一键导入会重新导入所有商品,商品较多的话,会影响工程速度和用户体验。
采用Active消息队列:在每次添加商品后获取商品id,通过消息队列把商品id发送给负责索引库导入的业务层,业务层接受id,查找数据库,把当前添加的商品导入索引库,提升商品导入效率。
->>>>这种情况在MVC架构会很好解决,只是这边使用的是SOA架构,项目模块分离,用过消息队列交流数据会好一点。
1.1,导包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
</dependency>
1.2,配置配置文件
1.2.1,消费者配置
分为三部分。
全局ActiveMQ配置
Queue配置+自己的消息监听容器
Topic配置+自己的消息监听容器
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://1.1.1.1:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!-- queue消息监听容器 -->
<bean id="myMessageListener" class="cn.e3mall.search.message.MyMessageListener"/>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicDestination" />
<property name="messageListener" ref="myMessageListener" />
</bean>
<!--这个是队列目的地,点对点的 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>spring-queue</value>
</constructor-arg>
</bean>
<!-- topic消息监听容器 -->
<bean id="itemAddMessageListener" class="cn.e3mall.search.message.ItemAddMessageListener" />
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicDestination" />
<property name="messageListener" ref="itemAddMessageListener" />
</bean>
<!--这个是主题目的地,一对多的 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="spring-topic" />
</bean>
1.2.2,生产者配置
分为三部分。
全局ActiveMQ配置
Queue配置
Topic配置
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://1.1.1.1:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!--这个是队列目的地,点对点的 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>spring-queue</value>
</constructor-arg>
</bean>
<!--这个是主题目的地,一对多的 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="spring-topic" />
</bean>
2,实际开发
2.1,Dao层
//定义Mapper映射文件接口
SearchItem getItemById(Long itemId);
//多表查询,xml映射文件
<select id="getItemById" parameterType="Long" resultType="cn.e3mall.common.pojo.SearchItem">
SELECT
a.id,
a.title,
a.sell_point,
a.price,
a.image,
b. NAME category_name
FROM
tb_item a
LEFT JOIN tb_item_cat b ON a.cid = b.id
WHERE
a.status = 1
AND a.id=#{itemId}
</select>
2.2,Service层(接受消息)
@Override
public void onMessage(Message message) {
try {
//提取商品id
TextMessage textMessage=(TextMessage) message;
String text = textMessage.getText();
//转换为Long
Long itemId=new Long(text);
System.out.println("------"+itemId);
//通过id查询商品信息,返回SearchItem
//让线程休眠0.5秒,须确保商品添加到数据库之后再查询
Thread.sleep(1000);
SearchItem searchItem = itemMapper.getItemById(itemId);
System.out.println("-------"+searchItem);
//把商品信息添加到solr服务器
//创建文档对象
SolrInputDocument document = new SolrInputDocument();
//向文档对象中添加域
document.addField("id", searchItem.getId());
document.addField("item_title", searchItem.getTitle());
document.addField("item_sell_point", searchItem.getSell_point());
document.addField("item_price", searchItem.getPrice());
document.addField("item_image", searchItem.getImage());
document.addField("item_category_name", searchItem.getCategory_name());
//把文档对象写入索引库
solrServer.add(document);
//提交SolrServer
solrServer.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
2.3,Service层(发送消息)
//添加消息队列,生产者发送消息
jmsTemplate.send(topicDestination,new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
TextMessage message = session.createTextMessage(itemId+"");
return message;
}
});
3,测试
这是之前索引库的数据
添加商品
查看索引库数据
文章持续更新,可以微信搜索「 绅堂Style 」第一时间阅读,回复【资料】有我准备的面试题笔记。
GitHub https://github.com/dtt11111/Nodes 有总结面试完整考点、资料以及我的系列文章。欢迎Star。