整合ES(Elasticsearch)+MQ(RabbitMQ)实现商品上下架/跨模块远程调用

商品上下架过程中,修改数据库表上下架状态,之后通过RabbitMQ发送消息,最终实现ES中数据同步

  • nacos服务发现和注册
  • ES面向文档型数据库
  • RabbitMQ

在这里插入图片描述

ES

  1. 用户将数据提交到Elasticsearch数据库中
  2. 通过分词控制器将对应的语句分词
  3. 将其权重和分词结果一并存入数据
  4. 当用户搜索数据,在根据权重将结果排名、打分,并将结果呈现给用户

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

①、下载对应的ES
在这里插入图片描述
在这里插入图片描述

②、下载并安装分词器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

③、启动ES(前提是系统配置好了JDK环境变量)

通过浏览器验证是否启动成功
在这里插入图片描述

④、官方推荐的客户端kibana
在这里插入图片描述
在这里插入图片描述

通过浏览器进行访问,通过DevTools工具
在这里插入图片描述
在这里插入图片描述

RabbitMQ

#拉取镜像
docker pull rabbitmq:3.8-management#三个端口号:通信端口号,后台访问端口号,集群端口号
docker run -d --restart=always -p5672:5672 -p 12572:15672 --name rabbitmq rabbitmq:3.8-management

管理后台:http://ip:15672

在这里插入图片描述

业务模块

一、service-search模块消费者

①、依赖spring-boot-starter-ata-elasticsearch
远程调用spring-cloud-starter-openfeign
引入三定义service-client模块坐标
引入rabbit模块rabbit_util

②、配置文件

server:port: 8204
feign:sentinel: # 熔断机制enabled: trueclient:	config:default: #配置全局的feign的调用超时时间 如果有指定的服务配置,则默认的配置不会生效connectTimeout: 30000 #指定消费者连接服务提供者超时时间readTimeout: 50000 #调用服务提供者的服务超时时间
spring:main:allow-bean-definition-overriding: true#当遇到同样名字,是否允许覆盖注册elasticsearch:rest:uris: http://localhost:9200rabbitmq:host: 192.168.197.128port: 5672username: guestpassword: guestpublisher-confirm-type: CORRELATED #发布确认模式,消息是否被成功发送到交换机publisher-returns: truelistener:simple:prefetch: 1concurrency: 3acknowledge-mode: manual #消费端手动确认redis:host: localhostport: 6379database: 0timeout: 1800000password:lettuce:pool:max-active: 20#最大连接数max-wait: -1max-idle: 5#最大则色等待时间(负数表示没限制)min-idle: 0#最小空闲

③、启动类(当前模块不需要连接数据库,所以排除。否则需要在application.yml中配置数据库连接)

@SpringBootApplication(exclude=DatasourceAutoConfiguration.class)//取消数据源自动配置
@EnableDiscoveryClient
@EnableFeignClients //远程调用
public class ServiceSearchApplication{}

④、业务接口、服务

@RestController
@RequestMapping("api/search/sku")
public class SkuApiController{@Autowiredprivate SkuService skuService;//上架,将数据加入ES中@GetMapping("inner/upperSku/{skuId}")public Result upperSku(@PathVariable Long skuId){skuService.upperSku(skuId);return Result.ok(null);}//下架,将数据从ES中删除@GetMapping("inner/lowerSku/{skuId}")public Result lowerSku(@PathVariable Long skuId){skuService.lowerSku(skuId);return Result.ok(null);}
}

service接口忽略,只创建其是实现类

@Service
public class SkuServiceImpl implements SkuService{@Autowiredprivate SkuRepository skuRepository;//注入远程调用的接口@Autowiredprivate ProductFeignClient productFeignClient;Overridepublic void upperSku(Long skuId){//远程调用获取数据SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);if(skuInfo == null){return;}Category category = productFeignClient.getCategory(skuInfo.getCategoryId());SkuEs skuEs = new SkuEs();if(category != null){skuEs.setCategoryId(category.getId());skuEs.setCategoryName(category.getName());}//封装SKU信息skuEs.setId(skuId.getId());skuEs.setKeyWord(skuInfogetSkuName()+","+skuEs.getCategoryName());skuEs.setWareId(skuInfo.getWareId());skuEs.setIsNewPerson(skuInfo.getInsNewPerson());skuEs.setImgUrl(skuInfo.getImgUrl());skuEs.setTitle(skuInfo.getSkuName());if(skuInfo.getSkuTyoe()==SkuType.COMMON.getCode()){skuEs.setSkyType(0);skuEs.setPrice(skuInfo.getPrice().doubleValue());skuEs.setStock(skuInfo.getStock());skuEs.setSale(skuInfo.getSale());skuEs.setPerLimit(skuInfo.getPerLimit());}//调用方法添加到ESskuRepository.save(skuEs);}@Overridepublic void lowerSku(Long skuId){skuRepository.deleteById(skuId);}
}

依赖中SpringData的模块,通过Spring提供的ElasticsearchRepository操作ES
泛型是操作的实体类和其主键

public interface SkuRepository extends ElasticsearchRepository<SkuEs,Long>{}

⑤、创建接收rabbitMQ消息的类

@Component
public class SkuReceiver{@Autowiredprivate SkuService skuService;//durable=true  表示对消息进行持久化@RabbitListener(bindings = @QueueBinding(value=@Queue(value=MqConst.QUEUE_GOODS_UPPER,durable="true"),exchange=@Exchange(value=MqConst.EXCHANGE_GOODS_DIRECT),key={MqConst.ROUTING_GOODS_UPPER}))public void upperSku(Long skuId,Message message,Channel channel){if(skuId != null){//调用方法商品上架skuService.upperSku(skuId);}//配置文件中的acknowledge-mode: manual #消费端手动确认   true表示多个消息channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);}//商品下架@RabbitListener(bindings = @QueueBinding(value=@Queue(value=MqConst.QUEUE_GOODS_LOWER,durable="true"),exchange=@Exchange(value=MqConst.EXCHANGE_GOODS_DIRECT),key={MqConst.ROUTING_GOODS_LOWER}))public void lowerSku(Long skuId,Message message,Channel channel){if(skuId != null){skuService.lowerSku(skuId);}channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);}
}

二、service-product模块,生产者

依赖导入rabbit-util模块坐标
配置文件application.yml中添加rabbit的连接信息

①、上架下架,发送消息给rabbitMQ

@ApiOperation("商品上下架")
@GetMapping("/publish/{skuId}/{status}")
public Result publish(@PathVariable Long skuId,@PathVariable Integer status){skuInfoService.publish(skuId,status);//发送消息给rabbitMQreturn Result.ok(null);
}
//注入MQ
@Autowired
private RabbitService rabbitService;@Override
public void publish(Long skuId,Integer status){if(status == 1){//上架SkuInfo skuInfo = baseMapper.selectById(skuId);skuInfo.setPublishStatus(status);baseMapper.updateById(skuIdFo);//上架时,整合mq把数据同步到es中rabbitService.sendMessage(MqConst.EXCHANGE_GOODS_DIRECT,MqConst.ROUTING_GOODS_UPPER,skuId);}else{//下架SkuInfo skuInfo = baseMapper.selectById(skuId);skuInfo.setPublishStatus(status);baseMapper.updateById(skuInfo);//下架,整合mq把数据同步到es中rabbitService.sendMessage(MqConst.EXCHANGE_GOODS_DIRECT,MqConst.ROUTING_GOODS_LOWER,skuId);}
}

②、为远程调用提供数据

@RestController
@RequestMapping("/api/product")
public class PruductInnerController{@Autowiredprivate CategoryService categoryService;@Autowiredprivate SkuInfoService skuInfoService;//根据SKUID获取分类信息@GetMapping("inner/getCategory/{categoryId}")public Category getCategory(@PathVariable Long categoryId){Category category = categoryService.getById(categoryId);return category;}//根据SKUID获取SKU信息@GetMapping("inner/getSkuInfo/{skuId}")public SkuInfo getSkuInfo(@PathVariable Long skuId){return skuInfoService.getById(skuId);}
}

三、service-client模块

定义生产者的接口

@FeignClient(value="service-product") 
pubic interface ProductFeignClient{@GetMapping("/api/product/inner/getCategory/{categoryId}")public Category getCategory(@PathVariable("categoryId") Long categoryId);@GetMapping("/api/product/inner/getSkuInfo/{skuId}")public SkuInfo getSkuInfo(@PathVariable("skuId") Long skuId);
}

三、common工程下创建rabbit-util模块

①、依赖

spring-cloud-starter-bus-amqp

②、封装发送消息的方法

@Service
public class RabbitService{@Autowiredprivate RabbitTemplate rebbitTemplate;//发送那个消息的方法public boolean sendMessage(String exchange,String routingKey,Object message){rabbitTemplate.convertAndSend(exchage,routingKey,message); return true;}
}

由于默认只能发送字符串,因此需要拓展配置类,发送对象转换为json

@Configuration
public class MQConfig{@Beanpublic MessageConverter messageConverter(){return new Jackson2JsonMessageConverter();}
}

消息确认

在这里插入图片描述

@Component
public class MQProducerAckConfig implements RabbitTemplate.ReturnCallback,RabbitTemplate.ConfirmCallback{@Autowiredprivate RabbitTemplate rabbitTemplates;@PostConstructpublic void init(){rabbitTemplate.setReturnCallback(this);rabbitTemplate.setConfirmCallback(this);}public void confirm(CorrelationData correlationData){if(ack){System.out.println("消息发送成功!");}else{System.out.println("消息发送失败!" + cause);}}@Overridepublic void returnedMessage(Message message,int replyCode,String replayText,String exchange,String routingKey){System.out.println("消息主题: " + new String(message.getBody()));System.out.println("应答码: " + replayCode);System.out.println("描述: " + replayText);System.out.println("消息使用的交换器 exchange: " + exchange);System.out.println("消息使用的路由键 routing: " + routingKey);}
}

常量(交换机、路由ke、队列的等名称)

public class MqConst{//消息补偿public static final String MQ_KEY_PREFIX = "ssyx.mq:list";public static final int RETRY_COUNT = 3;//商品上下架public static final String EXCHANGE_GOODS_DIRECT= "ssyx.goods.direct";public static final String ROUTING_GOODS_UPPER = "ssyx.goods.upper";public static final String ROUTING_GOODS_LOWER = "ssyx.goods.lower";//队列public static final String QUEUE_GOODS_UPPER = "ssyx.goods.upper";public static final String QUEUE_GOODS_LOWER = "ssyx.goods.lower";
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/69487.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件模拟I2C案例(寄存器实现)

引言 在经过前面对I2C基础知识的理解&#xff0c;对支持I2C通讯的EEPROM芯片M24C02的简单介绍以及涉及到的时序操作做了整理。接下来&#xff0c;我们就正式进入该案例的实现环节了。本次案例是基于寄存器开发方式通过软件模拟I2C通讯协议&#xff0c;然后去实现相关的需求。 阅…

爬虫技巧汇总

一、UA大列表 USER_AGENT_LIST 是一个包含多个用户代理字符串的列表&#xff0c;用于模拟不同浏览器和设备的请求。以下是一些常见的用户代理字符串&#xff1a; USER_AGENT_LIST [Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; Hot Lingo 2.0),Mozilla…

35~37.ppt

目录 35.张秘书-《会计行业中长期人才发展规划》 题目​ 解析 36.颐和园公园&#xff08;25张PPT) 题目​ 解析 37.颐和园公园&#xff08;22张PPT) 题目 解析 35.张秘书-《会计行业中长期人才发展规划》 题目 解析 插入自定义的幻灯片&#xff1a;新建幻灯片→重用…

【Android开发AI实战】基于CNN混合YOLOV实现多车牌颜色区分且针对车牌进行矫正识别(含源码)

文章目录 引言单层卷积神经网络&#xff08;Single-layer CNN&#xff09;&#x1f4cc; 单层 CNN 的基本结构&#x1f4cc; 单层 CNN 计算流程图像 透视变换矫正车牌c实现&#x1fa84;关键代码实现&#xff1a;&#x1fa84;crnn结构图 使用jni实现高级Android开发&#x1f3…

DeepSeek Window本地私有化部署

前言 最近大火的国产AI大模型Deepseek大家应该都不陌生。除了在手机上安装APP或通过官网在线体验&#xff0c;其实我们完全可以在Windows电脑上进行本地部署&#xff0c;从而带来更加便捷的使用体验。 之前也提到过&#xff0c;本地部署AI模型有很多好处&#xff0c;比如&…

STM32G474--Whetstone程序移植(单精度)笔记

1 准备基本工程代码 参考这篇笔记从我的仓库中选择合适的基本工程&#xff0c;进行程序移植。这里我用的是stm32g474的基本工程。 使用git clone一个指定文件或者目录 2 移植程序 2.1 修改Whetstone.c 主要修改原本变量定义的类型&#xff0c;以及函数接口全部更换为单精度…

【专题】2024-2025人工智能代理深度剖析:GenAI 前沿、LangChain 现状及演进影响与发展趋势报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p39630 在科技飞速发展的当下&#xff0c;人工智能代理正经历着深刻的变革&#xff0c;其能力演变已然成为重塑各行业格局的关键力量。从早期简单的规则执行&#xff0c;到如今复杂的自主决策与多智能体协作&#xff0c;人工智能代理…

QT修仙之路1-1--遇见QT

文章目录 遇见QT二、QT概述2.1 定义与功能2.2 跨平台特性2.3 优点汇总 三、软件安装四、QT工具介绍(重要)4.1 Assistant4.2 Designer4.3 uic.exe4.4 moc.exe4.5 rcc.exe4.6 qmake4.7 QTcreater 五、QT工程项目解析(作业)5.1 配置文件&#xff08;.pro&#xff09;5.2 头文件&am…

Linux——基础命令1

$&#xff1a;普通用户 #&#xff1a;超级用户 cd 切换目录 cd 目录 &#xff08;进入目录&#xff09; cd ../ &#xff08;返回上一级目录&#xff09; cd ~ &#xff08;切换到当前用户的家目录&#xff09; cd - &#xff08;返回上次目录&#xff09; pwd 输出当前目录…

Office/WPS接入DeepSeek等多个AI工具,开启办公新模式!

在现代职场中&#xff0c;Office办公套件已成为工作和学习的必备工具&#xff0c;其功能强大但复杂&#xff0c;熟练掌握需要系统的学习。为了简化操作&#xff0c;使每个人都能轻松使用各种功能&#xff0c;市场上涌现出各类办公插件。这些插件不仅提升了用户体验&#xff0c;…

【提示词工程】探索大语言模型的参数设置:优化提示词交互的技巧

在与大语言模型(Large Language Model, LLM)进行交互时,提示词的设计和参数设置直接影响生成内容的质量和效果。无论是通过 API 调用还是直接使用模型,掌握模型的参数配置方法都至关重要。本文将为您详细解析常见的参数设置及其应用场景,帮助您更高效地利用大语言模型。 …

Ollama + AnythingLLM + Deepseek r1 实现本地知识库

1、Ollama&#xff1a;‌是一个开源的大型语言模型 (LLM)服务工具&#xff0c;旨在简化在本地运行大语言模型的过程&#xff0c;降低使用大语言模型的门槛‌。 2、AnythingLLM&#xff1a;是由Mintplex Labs Inc. 开发的一款全栈应用程序&#xff0c;旨在构建一个高效、可定制、…

伪分布式Spark3.4.4安装

参考&#xff1a;Spark2.1.0入门&#xff1a;Spark的安装和使用_厦大数据库实验室博客 我的版本&#xff1a; hadoop 3.1.3 hbase 2.2.2 java openjdk version "1.8.0_432" 问了chatgpt,建议下载Spark3.4.4&#xff0c;不适合下载Spark 2.1.0: step1 Spark下载…

从运输到植保:DeepSeek大模型探索无人机智能作业技术详解

DeepSeek&#xff0c;作为一家专注于深度学习与人工智能技术研究的企业&#xff0c;近年来在AI领域取得了显著成果&#xff0c;尤其在无人机智能作业技术方面展现了其大模型的强大能力。以下是从运输到植保领域&#xff0c;DeepSeek大模型探索无人机智能作业技术的详解&#xf…

免费windows pdf编辑工具Epdf

Epdf&#xff08;完全免费&#xff09; 作者&#xff1a;不染心 时间&#xff1a;2025/2/6 Github: https://github.com/dog-tired/Epdf Epdf Epdf 是一款使用 Rust 编写的 PDF 编辑器&#xff0c;目前仍在开发中。它提供了一系列实用的命令行选项&#xff0c;方便用户对 PDF …

基于深度学习的人工智能量化衰老模型构建与全流程应用研究

一、引言 1.1 研究背景与意义 1.1.1 人口老龄化现状与挑战 人口老龄化是当今全球面临的重要社会趋势之一,其发展态势迅猛且影响深远。根据联合国的相关数据,1980 年,全球 65 岁及以上人口数量仅为 2.6 亿,到 2021 年,这一数字已翻番,达到 7.61 亿,而预计到 2050 年,…

UnityShader学习笔记——深度与法线纹理

——内容源自唐老狮的shader课程 目录 1.概述 1.1.分别指什么 1.2.如何获取 1.2.1.对摄像机赋值 1.2.2.在Shader中声明 1.2.3.获取深度值 1.2.4.获取法线纹理 1.3.背后的原理 1.3.1.深度纹理中存储的是什么信息 1.3.2.法线纹理中存储的是什么信息 1.3.3.unity是如何…

基于STM32的智能鱼缸水质净化系统设计

&#x1f91e;&#x1f91e;大家好&#xff0c;这里是5132单片机毕设设计项目分享&#xff0c;今天给大家分享的是智能鱼缸水质净化系统。 目录 1、设计要求 2、系统功能 3、演示视频和实物 4、系统设计框图 5、软件设计流程图 6、原理图 7、主程序 8、总结 1、设计要求…

如何打造一个更友好的网站结构?

在SEO优化中&#xff0c;网站的结构往往被忽略&#xff0c;但它其实是决定谷歌爬虫抓取效率的关键因素之一。一个清晰、逻辑合理的网站结构&#xff0c;不仅能让用户更方便地找到他们需要的信息&#xff0c;还能提升搜索引擎的抓取效率 理想的网站结构应该像一棵树&#xff0c;…

尝试在Excel里调用硅基流动上的免费大语言模型

我个人觉得通过api而不是直接浏览器客户端聊天调用大语言模型是使用人工智能大模型的一个相对进阶的阶段。 于是就尝试了一下。我用的是老师木 袁进辉博士新创的硅基流动云上的免费的大模型。——虽然自己获赠了不少免费token&#xff0c;但测试阶段用不上。 具体步骤如下&am…