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

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容