ActiveMQ消息队列和SSM整合实际使用流程

生活就像海洋
只有意志坚强的人
才能到达彼岸。

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。
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章