如何做一個(gè)電商系統(tǒng)(五)

1.同步Solr索引庫(kù)

問(wèn)題1:我們?cè)诤笈_(tái)管理系統(tǒng)中,新添加的商品,為什么在門(mén)戶(hù)系統(tǒng)中搜不到?

答:因?yàn)檫@個(gè)新添加的商品,只保存到了數(shù)據(jù)庫(kù)中,沒(méi)有保存到Solr索引庫(kù)中。

所以,我們需要將新添加的商品,同步到索引庫(kù)中。

問(wèn)題2:我們是在后臺(tái)管理系統(tǒng)中添加的商品,索引庫(kù)的相關(guān)操作是在Search搜索系統(tǒng)中,如何將商品從后臺(tái)管理系統(tǒng)發(fā)送給搜索系統(tǒng)呢?

答:使用ActiveMQ。

image.png

1.1.實(shí)現(xiàn)的思路

(1)搭建ActiveMQ服務(wù)器。

(2)修改添加商品的邏輯,將商品寫(xiě)入隊(duì)列模型中。

(3)在搜索系統(tǒng)中開(kāi)發(fā)同步索引庫(kù)業(yè)務(wù)。

1.2.實(shí)現(xiàn)步驟

1.2.1.第一部分:搭建ActiveMQ服務(wù)器

1.2.1.1.第一步:下載、上傳至Linux

--說(shuō)明:確保已經(jīng)安裝了jdk

image.png

1.2.1.2.第二步:安裝到/usr/local/activemq目錄

(1)解壓到/usr/local目錄下

[root@node07192 ~]# tar -zxvf apache-activemq-5.9.0-bin.tar.gz -C      /usr/local

(2)修改名稱(chēng)為activemq

[root@node07192 ~]# cd /usr/local/     

[root@node07192 local]# mv apache-activemq-5.9.0/ activemq

1.2.1.3.第三步:?jiǎn)?dòng)ActiveMQ服務(wù)器

--說(shuō)明:ActiveMQ是免安裝軟件,解壓即可啟動(dòng)服務(wù)。

[root@node07192 local]# cd activemq/bin     

[root@node07192 bin]# ./activemq start

--查看ActiveMQ啟動(dòng)狀態(tài)

[root@node07192 bin]# ./activemq status
image.png

1.2.1.4.第四步:瀏覽器訪問(wèn)ActiveMQ管理界面

1.2.1.4.1.Step1:查看ActiveMQ管理界面的服務(wù)端口。在/conf/jetty.xml中

--訪問(wèn)管理控制臺(tái)的服務(wù)端口,默認(rèn)為:8161

[root@node07192 bin]# cd ../conf     

[root@node07192 conf]# vim jetty.xml
image.png
1.2.1.4.2.Step2:查看ActiveMQ用戶(hù)、密碼。在/conf/users.properties中:

--默認(rèn)的用戶(hù)名、密碼均為amdin

[root@node07192 conf]# vim users.properties
image.png
1.2.1.4.3.Step3:訪問(wèn)ActiveMQ管理控制臺(tái)。地址:http://ip:8161/

--注意:防火墻是沒(méi)有配置該服務(wù)的端口的。

因此,要訪問(wèn)該服務(wù),必須在防火墻中配置。

(1)修改防火墻,開(kāi)放8161端口

[root@node07192 conf]# vim /etc/sysconfig/iptables
image.png

(2)重啟防火墻

[root@node07192 conf]# service iptables restart

(3)登錄管理控制臺(tái)

--登陸,用戶(hù)名、密碼均為admin

image.png

--控制臺(tái)主界面

image.png

--搭建ActiveMQ服務(wù)器成功!!!

1.2.2.第二部分:修改商品添加邏輯

添加商品的時(shí)候,同時(shí)將商品寫(xiě)入消息隊(duì)列中。

步驟說(shuō)明:

(1)導(dǎo)入ActiveMQ依賴(lài)。

(2)Spring整合ActiveMQ。

(3)修改商品添加的業(yè)務(wù)邏輯。

1.2.2.1.第一步:導(dǎo)入jar依賴(lài)

修改ego-manager工程的pom文件,添加如下依賴(lài):

<!-- ActiveMQ客戶(hù)端完整jar包依賴(lài) -->     

<dependency>

    <groupId>org.apache.activemq</groupId>

    <artifactId>activemq-all</artifactId>

    <version>5.9.0</version>

</dependency>

<dependency>

    <groupId>org.apache.activemq</groupId>

    <artifactId>activemq-pool</artifactId>

    <version>5.9.0</version>

</dependency>

<!-- Spring-JMS插件相關(guān)jar包依賴(lài) -->

<dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-jms</artifactId>

    <version>4.3.16.RELEASE</version>

</dependency>

1.2.2.2.第二步:Spring整合ActiveMQ

(1)修改resource.properties文件,添加ActiveMQ服務(wù)器配置信息

#ActiveMQ配置     

MQ_ADDRESS=tcp://192.168.23.12:61616

MQ_USER=admin

MQ_PASSWD=admin

MQ_ITEM_QUEUE_NAME=ego-item-mq

在src目錄下創(chuàng)建spring-jms.xml文件,用來(lái)整合ActiveMQ.

<?xml version="1.0" encoding="UTF-8"?>     

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:jms="http://www.springframework.org/schema/jms"

    xsi:schemaLocation="http://www.springframework.org/schema/jms      http://www.springframework.org/schema/jms/spring-jms-4.3.xsd

       http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">

    <!-- 1、配置activemq連接工程

       使用連接池好處:鏈接只需要初始化一次,每次要使用的時(shí)候,直接從連接池獲取,用完之后還給連接池。省去了每次創(chuàng)建、銷(xiāo)毀連接的時(shí)間。                              

    -->

    <bean name="pooledConnectionFactory"      class="org.apache.activemq.pool.PooledConnectionFactory">

       <property name="connectionFactory">

           <bean      class="org.apache.activemq.ActiveMQConnectionFactory">

              <property name="brokerURL"      value="tcp://192.168.23.12:61616"/>

              <property name="userName" value="admin"/>

              <property name="password" value="admin"/>

           </bean>

       </property>

       <property name="maxConnections" value="20"></property>

    </bean>

    <!-- 2、spring整合activemq鏈接工廠

       可以緩存session。

    -->

    <bean name="cachingConnectionFactory"      class="org.springframework.jms.connection.CachingConnectionFactory">

        <property name="targetConnectionFactory"      ref="pooledConnectionFactory"></property>

       <property name="sessionCacheSize" value="5"></property>

    </bean>

    <!-- 3、spring整合消息操作對(duì)象JmsTemplate

       使用jmsTemplate可以簡(jiǎn)化代碼,不需要自己去創(chuàng)建消息的發(fā)送對(duì)象。

    -->

    <bean name="jmsTemplate"      class="org.springframework.jms.core.JmsTemplate">

       <property name="connectionFactory"      ref="cachingConnectionFactory"></property>

    </bean>

</beans>

1.2.2.3.第三步:修改ItemServiceImpl類(lèi)

(1)注入JmsTemplate對(duì)象、隊(duì)列名稱(chēng)

(2)修改save方法。

package cn.gzsxt.manager.service.impl;     

import java.util.Date;

import java.util.List;

import javax.jms.JMSException;

import javax.jms.MapMessage;

import javax.jms.Message;

import javax.jms.Session;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.jms.core.JmsTemplate;

import org.springframework.jms.core.MessageCreator;

import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;

import com.github.pagehelper.PageInfo;

import cn.gzsxt.common.pojo.EUDataGrid;

import cn.gzsxt.common.pojo.SearchItem;

import cn.gzsxt.common.utils.EgoResult;

import cn.gzsxt.common.utils.IDUtils;

import cn.gzsxt.common.utils.JsonUtils;

import cn.gzsxt.manager.mapper.ItemDescMapper;

import cn.gzsxt.manager.mapper.ItemMapper;

import cn.gzsxt.manager.mapper.ItemParamItemMapper;

import cn.gzsxt.manager.pojo.Item;

import cn.gzsxt.manager.pojo.ItemDesc;

import cn.gzsxt.manager.pojo.ItemExample;

import cn.gzsxt.manager.pojo.ItemExample.Criteria;

import cn.gzsxt.manager.pojo.ItemParamItem;

import cn.gzsxt.manager.service.ItemService;

@Service

public class ItemServiceImpl implements ItemService{

    @Autowired

    private ItemMapper mapper;

    @Autowired

    private ItemParamItemMapper itemParamMapper;

    @Autowired

    private ItemDescMapper descMapper;

    @Autowired

    private JmsTemplate jmsTemplate;

    @Value("${MQ_ITEM_QUEUE_NAME}")

    private String MQ_ITEM_QUEUE_NAME;

    @Override

    public EgoResult save(Item item, String desc, String itemParams)      {

       try {

           //保存商品信息

           long itemId = IDUtils.genItemId();

           item.setId(itemId);

           item.setStatus((byte) 1);

           item.setCreated(new Date());

           item.setUpdated(item.getCreated());

           mapper.insertSelective(item);

           //保存商品詳情

           ItemDesc itemDesc = new ItemDesc();

           itemDesc.setItemId(itemId);

           itemDesc.setItemDesc(desc);

           itemDesc.setCreated(item.getCreated());

           itemDesc.setUpdated(item.getCreated());

           descMapper.insertSelective(itemDesc);

           //保存商品規(guī)格參數(shù)

           ItemParamItem paramItem = new ItemParamItem();

           paramItem.setCreated(item.getCreated());

           paramItem.setUpdated(item.getCreated());

           paramItem.setItemId(itemId);

           paramItem.setParamData(itemParams);

           itemParamMapper.insertSelective(paramItem);

           //將商品寫(xiě)入到消息隊(duì)列

           SearchItem temp = new SearchItem();

           temp.setId(itemId);

           temp.setImage(item.getImage());

           temp.setPrice(item.getPrice());

           temp.setSell_point(item.getSellPoint());

           temp.setTitle(item.getTitle());

           jmsTemplate.send(MQ_ITEM_QUEUE_NAME, new MessageCreator()      {

              @Override

              public Message createMessage(Session session) throws      JMSException {

                  //使用Map類(lèi)型保存消息

                  MapMessage mapMessage =      session.createMapMessage();

                  //key用來(lái)標(biāo)記當(dāng)前是在添加商品

                  //value是存儲(chǔ)的是商品的信息

                  mapMessage.setString("key", "add");

                  mapMessage.setString("value",      JsonUtils.objectToJson(temp));

                  return mapMessage;

              }

           });

           return EgoResult.ok();

       } catch (Exception e) {

           e.printStackTrace();

           return EgoResult.build(400, e.getMessage());

       }

    }

}

1.2.2.4.第四步:測(cè)試

(1)重新啟動(dòng)后臺(tái)管理系統(tǒng)

(2)新增一個(gè)商品。

(3)查看ActiveMQ控制臺(tái)。

image.png

1.2.3.第三部分:同步Solr索引庫(kù)

說(shuō)明:同步索引庫(kù),是在ego-search搜索工程中實(shí)現(xiàn)的。

思路:

(1)導(dǎo)入jar包。

(2)Spring整合ActiveMQ

(3)創(chuàng)建監(jiān)聽(tīng)器

(4)加載監(jiān)聽(tīng)器,監(jiān)聽(tīng)商品這個(gè)隊(duì)列。

1.2.3.1.第一步:導(dǎo)入jar依賴(lài)

<dependency>

    <groupId>org.apache.activemq</groupId>

    <artifactId>activemq-all</artifactId>

    <version>5.9.0</version>

</dependency>

<dependency>

    <groupId>org.apache.activemq</groupId>

    <artifactId>activemq-pool</artifactId>

    <version>5.9.0</version>

</dependency>

<!-- Spring-JMS插件相關(guān)jar包依賴(lài) -->

<dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-jms</artifactId>

    <version>4.3.16.RELEASE</version>

</dependency>

1.2.3.2.第二步:Spring整合ActiveMQ

(1)修改resource.properties文件,添加AcitveMQ配置信息

#ActiveMQ配置     

MQ_ADDRESS=tcp://192.168.23.12:61616

MQ_USER=admin

MQ_PASSWD=admin

MQ_ITEM_QUEUE_NAME=ego-item-mq

(2)創(chuàng)建spring-jms.xml文件,整合框架

<?xml version="1.0" encoding="UTF-8"?>     

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:jms="http://www.springframework.org/schema/jms"

    xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans-4.3.xsd

       http://www.springframework.org/schema/jms      http://www.springframework.org/schema/jms/spring-jms-4.3.xsd">

    <!-- 1、配置activemq連接工廠

       使用連接池好處:鏈接只需要初始化一次,每次要使用的時(shí)候,直接從連接池獲取,用完之后還給連接池。省去了每次創(chuàng)建、銷(xiāo)毀連接的時(shí)間。                              

    -->

    <bean name="pooledConnectionFactory"      class="org.apache.activemq.pool.PooledConnectionFactory">

       <property name="connectionFactory">

           <bean      class="org.apache.activemq.ActiveMQConnectionFactory">

              <property name="brokerURL" value="${MQ_ADDRESS}"/>

              <property name="userName" value="${MQ_USER}"/>

              <property name="password" value="${MQ_PASSWD}"/>

           </bean>

       </property>

       <property name="maxConnections" value="20"></property>

    </bean>

    <!-- 2、spring整合activemq鏈接工廠

       可以緩存session。-->

       <bean name="cachingConnectionFactory"      class="org.springframework.jms.connection.CachingConnectionFactory">

        <property name="targetConnectionFactory"      ref="pooledConnectionFactory"></property>

       <property name="sessionCacheSize" value="5"></property>

    </bean>

</beans>

1.2.3.3.第三步:創(chuàng)建監(jiān)聽(tīng)器

說(shuō)明:監(jiān)聽(tīng)器需要實(shí)現(xiàn)MessageListener這個(gè)接口。

package cn.gzsxt.search.listener;     

import java.io.IOException;

import javax.jms.JMSException;

import javax.jms.MapMessage;

import javax.jms.Message;

import javax.jms.MessageListener;

import org.apache.solr.client.solrj.SolrServerException;

import org.apache.solr.client.solrj.impl.HttpSolrServer;

import org.apache.solr.common.SolrInputDocument;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import cn.gzsxt.common.pojo.SearchItem;

import cn.gzsxt.common.utils.JsonUtils;

@Component

public class ItemListener implements MessageListener{

    @Autowired

    private HttpSolrServer server;

    @Override

    public void onMessage(Message message) {

       if(null!=message){

           MapMessage mapMessage = (MapMessage) message;

           try {

              String key = mapMessage.getString("key");

              if("add".equals(key)){

                  String jsonItem = mapMessage.getString("value");

                  SearchItem item = JsonUtils.jsonToPojo(jsonItem,      SearchItem.class);

                  SolrInputDocument doc = new SolrInputDocument();

                  doc.addField("id", item.getId());

                  doc.addField("item_title", item.getTitle());

                  doc.addField("item_sell_point",      item.getSell_point());

                  doc.addField("item_price", item.getPrice());

                  doc.addField("item_image", item.getImage());

                  doc.addField("item_category_name",      item.getCategory_name());

                  server.add(doc);

                  server.commit();

              }

           } catch (Exception e) {

              e.printStackTrace();

           }

       }

    }

}

1.2.3.4.第四步:加載監(jiān)聽(tīng)器

修改spring-jms.xml文件,配置監(jiān)聽(tīng)器。

<!-- 3、spring加載監(jiān)聽(tīng)器      

       acknowledge="auto"  表示消息獲取之后,自動(dòng)出隊(duì)列

       container-type    表示的容器的類(lèi)型   default|simple

           default:支持session緩存。

    -->

    <jms:listener-container acknowledge="auto"

       container-type="default"

       destination-type="queue"

       connection-factory="cachingConnectionFactory">

       <!-- 指定監(jiān)聽(tīng)器

           destination="spring-order"  指定監(jiān)聽(tīng)的是哪一個(gè)隊(duì)列

           ref="orderListener"         指定監(jiān)聽(tīng)器對(duì)象  使用注解的時(shí)候,對(duì)象的名稱(chēng)是類(lèi)名首字母小寫(xiě)

        -->

       <jms:listener destination="${MQ_ITEM_QUEUE_NAME}"      ref="itemListener"/>

  </jms:listener-container>

1.2.3.5.第五步:測(cè)試

(1)重新啟動(dòng)搜索工程。

image.png

(2)查看ActiveMQ管理控制臺(tái)。消息已經(jīng)被消費(fèi)了。

image.png

(3)在門(mén)戶(hù)系統(tǒng)中,搜索該商品

image.png

能成功收到新添加的商品,索引庫(kù)同步成功?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容