前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >商城项目-队列改造项目

商城项目-队列改造项目

作者头像
cwl_java
发布2020-02-11 14:01:10
4180
发布2020-02-11 14:01:10
举报
文章被收录于专栏:cwl_Javacwl_Java

3.项目改造

接下来,我们就改造项目,实现搜索服务、商品静态页的数据同步。

3.1.思路分析

发送方:商品微服务

  • 什么时候发? 当商品服务对商品进行写操作:增、删、改的时候,需要发送一条消息,通知其它服务。
  • 发送什么内容? 对商品的增删改时其它服务可能需要新的商品数据,但是如果消息内容中包含全部商品信息,数据量太大,而且并不是每个服务都需要全部的信息。因此我们只发送商品id,其它服务可以根据id查询自己需要的信息。

接收方:搜索微服务、静态页微服务

接收消息后如何处理?

  • 搜索微服务:
    • 增/改:添加新的数据到索引库
    • 删:删除索引库数据
  • 静态页微服务:
    • 增:创建新的静态页
    • 删:删除原来的静态页
    • 改:创建新的静态页并删除原来的

3.2.商品服务发送消息

我们先在商品微服务leyou-item-service中实现发送消息。

3.2.1.引入依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

3.2.2.配置文件

我们在application.yml中添加一些有关RabbitMQ的配置:

代码语言:javascript
复制
spring:
  rabbitmq:
    host: 192.168.56.101
    username: leyou
    password: leyou
    virtual-host: /leyou
    template:
      exchange: leyou.item.exchange
    publisher-confirms: true
  • template:有关AmqpTemplate的配置
    • retry:失败重试
      • enabled:开启失败重试
      • initial-interval:第一次重试的间隔时长
      • max-interval:最长重试间隔,超过这个间隔将不再重试
      • multiplier:下次重试间隔的倍数,此处是2即下次重试间隔是上次的2倍
    • exchange:缺省的交换机名称,此处配置后,发送消息如果不指定交换机就会使用这个
  • publisher-confirms:生产者确认机制,确保消息会正确发送,如果发送失败会有错误回执,从而触发重试

3.2.3.改造GoodsService

在GoodsService中封装一个发送消息到mq的方法:

代码语言:javascript
复制
private void sendMessage(Long id, String type){
    // 发送消息
    try {
        this.amqpTemplate.convertAndSend("item." + type, id);
    } catch (Exception e) {
        logger.error("{}商品消息发送异常,商品id:{}", type, id, e);
    }
}

这里没有指定交换机,因此默认发送到了配置中的:leyou.item.exchange

注意:这里要把所有异常都try起来,不能让消息的发送影响到正常的业务逻辑

然后在新增的时候调用:

在这里插入图片描述
在这里插入图片描述

修改的时候调用:

在这里插入图片描述
在这里插入图片描述

3.3.搜索服务接收消息

搜索服务接收到消息后要做的事情:

  • 增:添加新的数据到索引库
  • 删:删除索引库数据
  • 改:修改索引库数据

因为索引库的新增和修改方法是合二为一的,因此我们可以将这两类消息一同处理,删除另外处理。

3.3.1.引入依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

3.3.2.添加配置

代码语言:javascript
复制
spring:
  rabbitmq:
    host: 192.168.56.101
    username: leyou
    password: leyou
    virtual-host: /leyou

这里只是接收消息而不发送,所以不用配置template相关内容。

3.3.3.编写监听器

在这里插入图片描述
在这里插入图片描述

代码:

代码语言:javascript
复制
@Component
public class GoodsListener {

    @Autowired
    private SearchService searchService;

    /**
     * 处理insert和update的消息
     *
     * @param id
     * @throws Exception
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "leyou.create.index.queue", durable = "true"),
            exchange = @Exchange(
                    value = "leyou.item.exchange",
                    ignoreDeclarationExceptions = "true",
                    type = ExchangeTypes.TOPIC),
            key = {"item.insert", "item.update"}))
    public void listenCreate(Long id) throws Exception {
        if (id == null) {
            return;
        }
        // 创建或更新索引
        this.searchService.createIndex(id);
    }

    /**
     * 处理delete的消息
     *
     * @param id
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "leyou.delete.index.queue", durable = "true"),
            exchange = @Exchange(
                    value = "leyou.item.exchange",
                    ignoreDeclarationExceptions = "true",
                    type = ExchangeTypes.TOPIC),
            key = "item.delete"))
    public void listenDelete(Long id) {
        if (id == null) {
            return;
        }
        // 删除索引
        this.searchService.deleteIndex(id);
    }
}

3.3.4.编写创建和删除索引方法

这里因为要创建和删除索引,我们需要在SearchService中拓展两个方法,创建和删除索引:

代码语言:javascript
复制
public void createIndex(Long id) throws IOException {

    Spu spu = this.goodsClient.querySpuById(id);
    // 构建商品
    Goods goods = this.buildGoods(spu);

    // 保存数据到索引库
    this.goodsRepository.save(goods);
}

public void deleteIndex(Long id) {
    this.goodsRepository.deleteById(id);
}

创建索引的方法可以从之前导入数据的测试类中拷贝和改造。

3.4.静态页服务接收消息

商品静态页服务接收到消息后的处理:

  • 增:创建新的静态页
  • 删:删除原来的静态页
  • 改:创建新的静态页并删除原来的

不过,我们编写的创建静态页的方法也具备覆盖以前页面的功能,因此:增和改的消息可以放在一个方法中处理,删除消息放在另一个方法处理。

3.4.1.引入依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

3.4.2.添加配置

代码语言:javascript
复制
spring:
  rabbitmq:
    host: 192.168.56.101
    username: leyou
    password: leyou
    virtual-host: /leyou

这里只是接收消息而不发送,所以不用配置template相关内容。

3.4.3.编写监听器

在这里插入图片描述
在这里插入图片描述

代码:

代码语言:javascript
复制
@Component
public class GoodsListener {

    @Autowired
    private GoodsHtmlService goodsHtmlService;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "leyou.create.web.queue", durable = "true"),
            exchange = @Exchange(
                    value = "leyou.item.exchange",
                    ignoreDeclarationExceptions = "true",
                    type = ExchangeTypes.TOPIC),
            key = {"item.insert", "item.update"}))
    public void listenCreate(Long id) throws Exception {
        if (id == null) {
            return;
        }
        // 创建页面
        goodsHtmlService.createHtml(id);
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "leyou.delete.web.queue", durable = "true"),
            exchange = @Exchange(
                    value = "leyou.item.exchange",
                    ignoreDeclarationExceptions = "true",
                    type = ExchangeTypes.TOPIC),
            key = "item.delete"))
    public void listenDelete(Long id) {
        if (id == null) {
            return;
        }
        // 创建页面
        goodsHtmlService.deleteHtml(id);
    }
}

3.4.4.添加删除页面方法

代码语言:javascript
复制
public void deleteHtml(Long id) {
    File file = new File("C:\\project\\nginx-1.14.0\\html\\item\\", id + ".html");
    file.deleteOnExit();
}

3.5.测试

3.5.1.查看RabbitMQ控制台

重新启动项目,并且登录RabbitMQ管理界面:http://192.168.56.101:15672

可以看到,交换机已经创建出来了:

在这里插入图片描述
在这里插入图片描述

队列也已经创建完毕:

在这里插入图片描述
在这里插入图片描述

并且队列都已经绑定到交换机:

在这里插入图片描述
在这里插入图片描述

3.5.2.修改数据试一试

在后台修改商品数据的价格,分别在搜索及商品详情页查看是否统一。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3.项目改造
    • 3.1.思路分析
      • 3.2.商品服务发送消息
        • 3.2.1.引入依赖
        • 3.2.2.配置文件
        • 3.2.3.改造GoodsService
      • 3.3.搜索服务接收消息
        • 3.3.1.引入依赖
        • 3.3.2.添加配置
        • 3.3.3.编写监听器
        • 3.3.4.编写创建和删除索引方法
      • 3.4.静态页服务接收消息
        • 3.4.1.引入依赖
        • 3.4.2.添加配置
        • 3.4.3.编写监听器
        • 3.4.4.添加删除页面方法
      • 3.5.测试
        • 3.5.1.查看RabbitMQ控制台
        • 3.5.2.修改数据试一试
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档