e3mall專案:商品增刪改查同步索引庫(ActiveMQ相關)
阿新 • • 發佈:2019-02-13
e3mall專案:商品增刪改查同步索引庫
準備工作:在e3-search-service和e3-manager-service的pom檔案中,新增ActiveMQ的依賴
<!--ActiveMQ訊息中介軟體-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
</dependency>
一、在商品的增刪改查時,傳送需要同步索引庫的訊息。(訊息傳送端:e3-manager-service)
(1)在e3-manager-service中配置ActiveMQ。(在spring目錄中,新建配置檔案:applicationContext-activemq.xml)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> <!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供 --> <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="${activemq.url}" /> //這裡的activemq.url在resouce.properties中,你也可以直接寫在這裡 </bean> <!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory --> <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory --> <property name="targetConnectionFactory" ref="targetConnectionFactory" /> </bean> <!-- 配置生產者 --> <!-- Spring提供的JMS工具類,它可以進行訊息傳送、接收等 --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory物件 --> <property name="connectionFactory" ref="connectionFactory" /> </bean> <!--這個是佇列目的地,點對點的 --> <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg> <value>spring-queue</value> </constructor-arg> </bean> <!-- 商品資料更新訊息 --> <bean id="itemUpdate" class="org.apache.activemq.command.ActiveMQTopic"> <constructor-arg value="itemUpdate" /> </bean> </beans>
(2)在完成商品資料修改之前,傳送訊息同步索引庫。(我這裡對傳送訊息進行了封裝,只需要在商品操作完成之前,呼叫即可)
封裝的方法如下:
/** * 傳送訊息的方法 * @auther: xushuai * @date: 2018/5/26 15:26 */ private void sendMessage(final long itemId, Destination destination) { jmsTemplate.send(destination, new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { //將商品ID傳送 return session.createTextMessage(itemId + ""); } }); }
呼叫:
注意:需要注入JmsTemplate物件和Destination物件。(即spring容器中配置好的)
二、同步索引庫操作。(訊息接收端:e3-search-service)
(1)書寫訊息接收監聽器類(ItemUpdateMessageLinstener)package cn.e3mall.search.message;
import cn.e3mall.search.service.SearchService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
* 商品資料更新訊息監聽器
* Author: xushuai
* Date: 2018/5/26
* Time: 15:37
* Description:
*/
public class ItemUpdateMessageLinstener implements MessageListener{
@Autowired
private SearchService searchService;
@Override
public void onMessage(Message message) {
try {
//等待一秒,防止訊息傳送端事務沒有提交,發生不必要的錯誤
Thread.sleep(1000);
//執行更新索引庫操作
TextMessage textMessage = (TextMessage) message;
Long itemId = Long.valueOf(textMessage.getText());
searchService.syncIndex(itemId);
} catch (JMSException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(2)在e3-search-service中配置ActiveMQ。(在spring目錄中,新建applicationContext-activemq.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<!-- 真正可以產生Connection的ConnectionFactory,由對應的 JMS服務廠商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activemq.url}" />
</bean>
<!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!-- 配置生產者 -->
<!-- Spring提供的JMS工具類,它可以進行訊息傳送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory物件 -->
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!--這個是佇列目的地,點對點的 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>spring-queue</value>
</constructor-arg>
</bean>
<!-- 商品資料更新訊息 -->
<bean id="itemUpdate" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="itemUpdate" /> //這裡的值,需要和訊息傳送方的值一致
</bean>
<!--配置訊息接收監聽器-->
<bean id="itemUpdateMessageLinstener" class="cn.e3mall.search.message.ItemUpdateMessageLinstener"/>
<!--商品資料更新訊息監聽器容器-->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="itemUpdate" />
<property name="messageListener" ref="itemUpdateMessageLinstener" />
</bean>
</beans>
(3)在SearchService和SearchServiceImpl中,實現同步索引庫操作(抽象方法和實現)
/**
* 同步索引庫
* @auther: xushuai
* @date: 2018/5/26 15:40
*/
void syncIndex(Long itemId);
@Override
public void syncIndex(Long itemId) {
//根據ID查詢索引結果
SearchResult searchResult = searchMapper.getItemById(itemId);
if(searchResult != null){
//說明商品為正常狀態,更新其在索引庫中的資料
try {
write(searchResult); //這個方法在之前的一鍵匯入時,就已經封裝好了。可以在之前的一鍵匯入索引庫文章中檢視該方法
} catch (Exception e) {
e.printStackTrace();
}
}else{
try {
//說明商品狀態為下架或者刪除,執行刪除索引庫操作
solrServer.deleteById(itemId.toString());
//提交刪除操作
solrServer.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
(4)書寫Mapper介面和對映檔案(mybatis相關)
/**
* 根據ID查詢商品
* @auther: xushuai
* @date: 2018/5/26 15:41
* @return: 索引庫結果物件
*/
SearchResult getItemById(Long itemId);
<!--按查詢商品,返回索引結果物件-->
<select id="getItemById" parameterType="long" resultType="cn.e3mall.common.entity.SearchResult">
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>