整合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;然后去实现相关的需求。 阅…

Academy Sports + Outdoors EDI:体育零售巨头的供应链“中枢神经”

Academy Sports Outdoors 是美国领先的体育用品及户外装备零售商&#xff0c;拥有250线下门店及电商平台&#xff0c;年营收超60亿美元。作为全渠道零售商&#xff0c;其供应链面临独特挑战&#xff1a; 海量SKU管理&#xff1a;超50万SKU&#xff08;从健身器材到露营装备&a…

爬虫技巧汇总

一、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…

信息学奥赛一本通1003

这道题题目中有一句“按每个整数占8个字符的宽度&#xff0c;右对齐输出它们”&#xff0c;诶&#xff0c;你会不会想到这个呢&#xff1a; #include<bits/stdc.h> using namespace std; int a, b, c; int main(){cin>> a>> b>> c;cout<<a&…

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;比如&…

R语言 文本分析 天龙八部

起因, 目的: 前面有人对 “倚天屠龙记” 进行分析,我这里只是进行模仿而已。 完整的文件, 已经绑定了,反正读者可以找一下。 案例背景 小说《天龙八部》是金庸先生所著的武侠小说,也是“射雕三部曲”的前传。全书共50章,字数超过一百万字。故事发生在北宋末年,以大理…

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 输出当前目录…

Linux 调用可执行程序

Linux 调用可执行程序 1. system() 函数1.1 system() 函数的声明1.2 system() 函数的不同场景返回值1.3 system() 函数的代码示例 2. exec() 函数族2.1 exec() 函数族的声明2.2 exec() 函数族执行失败的情况2.3 exec() 函数族的代码示例 3. exec() 与 system() 的区别以及使用注…

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…

【Vitest】单元测试

文章目录 测试&#xff1a;Vitest一、安装二、断言三、回调测试四、对象方法五、模拟第三库 测试&#xff1a;Vitest 一、安装 npm install vitest创建文件&#xff1a;example.test.ts 运行测试&#xff1a; npx vitest example二、断言 import { expect, test } from vi…

Android 中实现 PDF 预览三种方式

目录 1. 使用第三方库 PdfRenderer&#xff08;适用于 Android 5.0 及以上&#xff09; 步骤&#xff1a;2. 使用第三方库 MuPDF步骤&#xff1a;3. 使用第三方库 PdfiumAndroid步骤&#xff1a; 1. 使用第三方库 PdfRenderer&#xff08;适用于 Android 5.0 及以上&#xff09…