美文网首页电商
如何做一个电商系统(五)

如何做一个电商系统(五)

作者: 唯死撑尔 | 来源:发表于2019-07-29 17:46 被阅读0次

    1.同步Solr索引库

    问题1:我们在后台管理系统中,新添加的商品,为什么在门户系统中搜不到?

    答:因为这个新添加的商品,只保存到了数据库中,没有保存到Solr索引库中。

    所以,我们需要将新添加的商品,同步到索引库中。

    问题2:我们是在后台管理系统中添加的商品,索引库的相关操作是在Search搜索系统中,如何将商品从后台管理系统发送给搜索系统呢?

    答:使用ActiveMQ。

    image.png

    1.1.实现的思路

    (1)搭建ActiveMQ服务器。

    (2)修改添加商品的逻辑,将商品写入队列模型中。

    (3)在搜索系统中开发同步索引库业务。

    1.2.实现步骤

    1.2.1.第一部分:搭建ActiveMQ服务器

    1.2.1.1.第一步:下载、上传至Linux

    --说明:确保已经安装了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)修改名称为activemq

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

    1.2.1.3.第三步:启动ActiveMQ服务器

    --说明:ActiveMQ是免安装软件,解压即可启动服务。

    [root@node07192 local]# cd activemq/bin     
    
    [root@node07192 bin]# ./activemq start
    

    --查看ActiveMQ启动状态

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

    1.2.1.4.第四步:浏览器访问ActiveMQ管理界面

    1.2.1.4.1.Step1:查看ActiveMQ管理界面的服务端口。在/conf/jetty.xml中

    --访问管理控制台的服务端口,默认为:8161

    [root@node07192 bin]# cd ../conf     
    
    [root@node07192 conf]# vim jetty.xml
    
    image.png
    1.2.1.4.2.Step2:查看ActiveMQ用户、密码。在/conf/users.properties中:

    --默认的用户名、密码均为amdin

    [root@node07192 conf]# vim users.properties
    
    image.png
    1.2.1.4.3.Step3:访问ActiveMQ管理控制台。地址:http://ip:8161/

    --注意:防火墙是没有配置该服务的端口的。

    因此,要访问该服务,必须在防火墙中配置。

    (1)修改防火墙,开放8161端口

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

    (2)重启防火墙

    [root@node07192 conf]# service iptables restart
    

    (3)登录管理控制台

    --登陆,用户名、密码均为admin

    image.png

    --控制台主界面

    image.png

    --搭建ActiveMQ服务器成功!!!

    1.2.2.第二部分:修改商品添加逻辑

    添加商品的时候,同时将商品写入消息队列中。

    步骤说明:

    (1)导入ActiveMQ依赖。

    (2)Spring整合ActiveMQ。

    (3)修改商品添加的业务逻辑。

    1.2.2.1.第一步:导入jar依赖

    修改ego-manager工程的pom文件,添加如下依赖:

    <!-- ActiveMQ客户端完整jar包依赖 -->     
    
    <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插件相关jar包依赖 -->
    
    <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服务器配置信息

    #ActiveMQ配置     
    
    MQ_ADDRESS=tcp://192.168.23.12:61616
    
    MQ_USER=admin
    
    MQ_PASSWD=admin
    
    MQ_ITEM_QUEUE_NAME=ego-item-mq
    

    在src目录下创建spring-jms.xml文件,用来整合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连接工程
    
           使用连接池好处:链接只需要初始化一次,每次要使用的时候,直接从连接池获取,用完之后还给连接池。省去了每次创建、销毁连接的时间。                              
    
        -->
    
        <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整合消息操作对象JmsTemplate
    
           使用jmsTemplate可以简化代码,不需要自己去创建消息的发送对象。
    
        -->
    
        <bean name="jmsTemplate"      class="org.springframework.jms.core.JmsTemplate">
    
           <property name="connectionFactory"      ref="cachingConnectionFactory"></property>
    
        </bean>
    
    </beans>
    

    1.2.2.3.第三步:修改ItemServiceImpl类

    (1)注入JmsTemplate对象、队列名称

    (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);
    
               //保存商品规格参数
    
               ItemParamItem paramItem = new ItemParamItem();
    
               paramItem.setCreated(item.getCreated());
    
               paramItem.setUpdated(item.getCreated());
    
               paramItem.setItemId(itemId);
    
               paramItem.setParamData(itemParams);
    
               itemParamMapper.insertSelective(paramItem);
    
               //将商品写入到消息队列
    
               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类型保存消息
    
                      MapMessage mapMessage =      session.createMapMessage();
    
                      //key用来标记当前是在添加商品
    
                      //value是存储的是商品的信息
    
                      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.第四步:测试

    (1)重新启动后台管理系统

    (2)新增一个商品。

    (3)查看ActiveMQ控制台。

    image.png

    1.2.3.第三部分:同步Solr索引库

    说明:同步索引库,是在ego-search搜索工程中实现的。

    思路:

    (1)导入jar包。

    (2)Spring整合ActiveMQ

    (3)创建监听器

    (4)加载监听器,监听商品这个队列。

    1.2.3.1.第一步:导入jar依赖

    <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插件相关jar包依赖 -->
    
    <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)创建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连接工厂
    
           使用连接池好处:链接只需要初始化一次,每次要使用的时候,直接从连接池获取,用完之后还给连接池。省去了每次创建、销毁连接的时间。                              
    
        -->
    
        <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.第三步:创建监听器

    说明:监听器需要实现MessageListener这个接口。

    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.第四步:加载监听器

    修改spring-jms.xml文件,配置监听器。

    <!-- 3、spring加载监听器      
    
           acknowledge="auto"  表示消息获取之后,自动出队列
    
           container-type    表示的容器的类型   default|simple
    
               default:支持session缓存。
    
        -->
    
        <jms:listener-container acknowledge="auto"
    
           container-type="default"
    
           destination-type="queue"
    
           connection-factory="cachingConnectionFactory">
    
           <!-- 指定监听器
    
               destination="spring-order"  指定监听的是哪一个队列
    
               ref="orderListener"         指定监听器对象  使用注解的时候,对象的名称是类名首字母小写
    
            -->
    
           <jms:listener destination="${MQ_ITEM_QUEUE_NAME}"      ref="itemListener"/>
    
      </jms:listener-container>
    

    1.2.3.5.第五步:测试

    (1)重新启动搜索工程。

    image.png

    (2)查看ActiveMQ管理控制台。消息已经被消费了。

    image.png

    (3)在门户系统中,搜索该商品

    image.png

    能成功收到新添加的商品,索引库同步成功!!!

    相关文章

      网友评论

        本文标题:如何做一个电商系统(五)

        本文链接:https://www.haomeiwen.com/subject/hllirctx.html