详解实现黑马旅游网的ES和Mysql数据同步

news2025/1/12 12:27:33

1、需求分析

我们知道es中的数据来自于mysql数据库,因此mysql数据发生改变时,es也必须跟着改变,否则会导致数据不一致问题,这个就是elasticsearch与mysql之间的数据同步

如何实现数据同步:

方案一:同步调用

缺点:

得按顺序实行图中的三步,依次执行,容易引起数据耦合;

原来只是hotel-admin的业务只是写数据库写完就结束,现在还得在写数据库代码的后面加上调用hotel-demo的代码,hotel-admin和hotel-demo下的两个业务发生业务耦合;

影响性能,而且一个业务出错整个流程都会收到影响。

方案二:

利用消息队列MQ实现 hotel-admin和hotel-demo的业务解耦,但是会依赖MQ的可靠性,而且复杂度会相应的上升一点。

在hotel-admin和hotel-demo中都得声明交换机和监听队列:

public class MqConstants {
    /**
     * 声明交换机名称
     */
    public final static String HOTEL_EXCHANGE = "hotel.topic";
    /**
     * 监听新增和修改的队列
     */
    public final static String HOTEL_INSERT_QUEUE = "hotel.insert.queue";
    /**
     * 监听删除的队列
     */
    public final static String HOTEL_DELETE_QUEUE = "hotel.delete.queue";
    /**
     * 新增或修改的RoutingKey
     */
    public final static String HOTEL_INSERT_KEY = "hotel.insert";
    /**
     * 删除的RoutingKey
     */
    public final static String HOTEL_DELETE_KEY = "hotel.delete";
}

2、利用MQ实现数据同步:hotel-admin发布消息

在上面的示意图可以看出hotel-admin负责发出消息,所以hotel-admin是作为publicer的角色,

hotel-demo负责监听hotel-admin发出的消息,所以hotel-demo是作为consumer的角色。

因为新增和修改的逻辑差不多,所以将他们两个放入同一个消费者中,delete放在另外一个消费者中,代码如下:

@PostMapping
    public void saveHotel(@RequestBody Hotel hotel){
        hotelService.save(hotel);

        rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE,MqConstants.HOTEL_INSERT_KEY,hotel.getId());
    }

    @PutMapping()
    public void updateById(@RequestBody Hotel hotel){
        if (hotel.getId() == null) {
            throw new InvalidParameterException("id不能为空");
        }
        hotelService.updateById(hotel);

        rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE,MqConstants.HOTEL_INSERT_KEY,hotel.getId());
    }

    @DeleteMapping("/{id}")
    public void deleteById(@PathVariable("id") Long id) {
        hotelService.removeById(id);

        rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE,MqConstants.HOTEL_DELETE_KEY,id);
    }

在方法体内部,首先调用了 hotelService.save(hotel),这将酒店信息保存到数据库的业务逻辑。接着调用了 rabbitTemplate.convertAndSend() 方法,它用于向RabbitMQ消息队列发送消息。具体来说,它将 hotel.getId() 作为消息发送到了名为 MqConstants.HOTEL_EXCHANGE 的交换机,并使用 MqConstants.HOTEL_INSERT_KEY 作为路由键。

 

3、利用MQ实现数据同步:hotel-demo实现consumer对消息监听

因为新增和修改的逻辑差不多,所以将他们两个放入同一个消费者中,delete放在另外一个消费者中,代码如下:

/**
     * 监听酒店新增或修改的业务
     * @param id 酒店id
     */
    @RabbitListener(queues = MqConstants.HOTEL_INSERT_QUEUE)
    public void listenHotelInsertOrUpdate(Long id){
        hotelService.insertById(id);
    }

    /**
     * 监听酒店删除的业务
     * @param id 酒店id
     */
    @RabbitListener(queues = MqConstants.HOTEL_DELETE_QUEUE)
    public void listenHotelDelete(Long id){
        hotelService.deleteById(id);
    }

在监听到酒店数据在Mysql发生修改后,对应的也要将ES索引库中的数据进行更新,代码如下:

@Override
    public void insertById(Long id) {
        try {
            // 0.根据id查询酒店数据
            Hotel hotel = getById(id);
            // 转换为文档类型
            HotelDoc hotelDoc = new HotelDoc(hotel);

            // 1.准备Request对象
            IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
            // 2.准备Json文档
            request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
            // 3.发送请求
            client.index(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

这段代码是一个方法,用于向Elasticsearch索引中插入酒店数据。以下是该方法的主要步骤:

  1. 首先,通过调用 getById(id) 方法,根据提供的ID从数据库中获取相应的酒店数据,并将其转换为 HotelDoc 类型的对象,可能是为了适配Elasticsearch的文档格式。

  2. 接下来,创建一个 IndexRequest 对象,该对象用于表示将要插入到索引中的文档。指定索引名称为 "hotel",文档ID为酒店的ID(转换为字符串形式)。

  3. 然后,准备要插入的JSON文档,使用 JSON.toJSONString(hotelDoc)hotelDoc 对象转换为JSON格式的字符串,并使用 XContentType.JSON 指定内容类型。

  4. 最后,通过调用 client.index(request, RequestOptions.DEFAULT) 方法向Elasticsearch发送插入请求。其中,client 是一个Elasticsearch的客户端对象,request 是表示插入请求的 IndexRequest 对象。

总之,这段代码通过将酒店数据转换为JSON格式,并使用Elasticsearch的Java客户端将其插入到指定的索引中。

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

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

相关文章

html骨架以及常见标签

推荐一个网站mdn。 html语法 双标签&#xff1a;<标签 属性"属性值">内容</标签> 属性&#xff1a;给标签提供附加信息。大多数属性以键值对的形式存在。如果属性名和属性值一样&#xff0c;可以致谢属性值。 单标签&#xff1a;<标签 属性"属…

备考分享丨云计算HCIE实验考试需要注意什么

去年九月底我在朋友的推荐下报考了誉天的云计算方向&#xff0c;在此期间我非常感谢田sir、苗苗老师和凡凡老师&#xff0c;每次我遇见问题找他们都能给我完完全全的解决&#xff0c;给我这个非科班出身的学员很大的鼓励与帮助。 我是经济学专业&#xff0c;毕业之后没有考研&…

识典百科词条创建技巧,教你如何轻松创建热门识典百科词条!

网络已经成为人们获取知识和信息的主要途径。在这样一个背景下&#xff0c;识典百科作为一个综合性的网络百科全书&#xff0c;在为读者们提供各种知识的同时&#xff0c;也给广大用户提供了一个创建、编辑和分享知识的平台。如何在识典百科上创建一个高质量的词条&#xff0c;…

你的PCB地线走的对吗?为什么要有主地?

原文来自微信公众号&#xff1a;工程师看海&#xff0c;与我联系&#xff1a;chunhou0820 看海原创视频教程&#xff1a;《运放秘籍》 大家好&#xff0c;我是工程师看海&#xff0c;原创文章欢迎点赞分享&#xff01; PCB layout需要丰富的经验和扎实的理论基础支持&#xff…

基于SpringBoot+vue的在线商城系统+论文+免费远程调试

基于SpringBootvue的在线商城系统034(含源码 数据库文档免费送&#xff09; 开发系统:Windows10 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springb…

天锐绿盾 || 透明加密保护公司电脑文件资料,防止外泄

#天锐绿盾防泄密软件# 天锐绿盾作为一款专业的透明加密保护软件&#xff0c;专为防止公司电脑文件资料外泄而设计&#xff0c;其主要通过以下几方面实现对文件资料的透明加密保护&#xff1a; 德人合科技 || 天锐绿盾透明加密系统 PC地址&#xff1a; https://isite.baidu.c…

helm与k8基础

文章目录 一、helm二、K8S/K3S1.K8S基本组件1.1 资源对象1.2 核心组件1.3典型的创建 Pod 的流程1.4 Kubernetes 多组件之间的通信原理 三、容器运行时 Containerd1.查看当前k3s使用的容器运行时CRI2.K3S修改docker为运行环境3. Containerd 参考 一、helm Helm是Kubernetes的包…

2月珍珠饰品电商数据分析:价格翻倍,销售额暴增140%!

珍珠饰品这两年受到国内消费者的追捧&#xff0c;这股热潮随着电商直播的快速发展延续至今。与此同时&#xff0c;年轻人群体正成为珍珠消费的主力军&#xff0c;他们在各大直播间频繁亮相&#xff0c;以实际购买力展现了对珍珠饰品的热爱与追捧。 今年2月份&#xff0c;珍珠饰…

Swift 异步序列 AsyncStream 新“玩法”以及内存泄漏、死循环那些事儿(上)

概览 异步序列&#xff08;Async Sequence&#xff09;是 Swift 5.5 新并发模型中的一员“悍将”&#xff0c;系统标准库中很多类都做了重构以支持异步序列。我们还可以用 AsyncStream 辅助结构非常方便的创建自己的异步序列。 这里我们就来一起聊聊 AsyncStream 结构&#xf…

海盾特种阀门诚邀您到场参观2024第13届生物发酵展

参展企业介绍 浙江海盾特种阀门有限公司是位于“中国泵阀之都”浙江温州&#xff0c;是一家集研发、生产、销售、服务于一体的专业流体控制阀生产企业&#xff0c;公司创立于1999年&#xff0c;公司一直秉承“创新是企业的发展之本&#xff0c;质量是企业的生存之本”的经营理…

数字图像处理项目——基于BCNN和迁移学习的鸟类图像细粒度分类(论文/代码)

完整的论文代码见文章末尾 以下为核心内容 摘要 本文采用了ResNet50、VGG19、InceptionV3和Xception等四种不同的深度神经网络模型&#xff0c;并应用于鸟类图像的细粒度分类问题中&#xff0c;以探究其在该任务上的性能表现。 其中&#xff0c;本文使用了BCNN&#xff08;B…

分布式锁的原子性问题

4.6 分布式锁的原子性问题 更为极端的误删逻辑说明&#xff1a; 线程1现在持有锁之后&#xff0c;在执行业务逻辑过程中&#xff0c;他正准备删除锁&#xff0c;而且已经走到了条件判断的过程中&#xff0c;比如他已经拿到了当前这把锁确实是属于他自己的&#xff0c;正准备删…

SysTick滴答定时器 - 延时函数

SysTick定时器 Systick定时器&#xff0c;是一个简单的定时器&#xff0c;对于CM3,CM4内核芯片&#xff0c;都有Systick定时器。Systick定时器常用来做延时&#xff0c;或者实时系统的心跳时钟。这样可以节省MCU资源&#xff0c;不用浪费一个定时器。比如UCOS中&#xff0c;分…

【PPT技巧】如何取消PPT的密码保护?

PPT文件有两种密码&#xff0c;一种是打开密码、一种是修改权限。今天分享这两种密码如何取消。 首先需要告知大家的是&#xff0c;密码的取消需要输入正确的密码。 打开密码的取消&#xff0c;我们需要先输入密码&#xff0c;打开文件&#xff0c;然后点击文件 – 信息 – 保…

贪心算法|135.分发糖果

力扣题目链接 class Solution { public:int candy(vector<int>& ratings) {vector<int> candyVec(ratings.size(), 1);// 从前向后for (int i 1; i < ratings.size(); i) {if (ratings[i] > ratings[i - 1]) candyVec[i] candyVec[i - 1] 1;}// 从后…

c++的学习之路:17、stack、queue与priority_queue

摘要 本文主要是介绍一下stack、queue、priority_queue的使用以及模拟实现&#xff0c;文章末附上代码以及思维导图。 目录 摘要 一、stack的介绍和使用 1、stack的介绍 2、stack的使用 3、stack的模拟实现 二、queue的介绍和使用 1、queue的介绍 2、queue的使用 3、…

Vue-B站学习笔记

1. 路由配置 B站视频之Vue route文件下的index.js app.vue

Nginx服务 重写功能与反向代理

六、重写功能 rewrite Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求&#xff0c;此功能依靠 PCRE(perl compatible regular expression)&#xff0c;因此编译之前要安装PCRE库&#xff0c;rewrite是nginx服务器的重要功能之一&#xff0c;用于实现URL的…

土耳其航空2023年共运送旅客8340万人次,境内境外航线运力稳步增长

2023年,尽管面对持续紧张的国际局势和摇摆不定的宏观经济,土耳其航空仍实现了里程碑式的业绩表现,共计运输旅客8340万人次。土耳其境内航线运力比2022年增长了23.5%,运送旅客突破3000万人次;国际航线运力增长16%,运送旅客达5300万人次,并实现了14%的同比增长。其中,来自欧洲国家…

【Leetcode】2009. 使数组连续的最少操作数

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个整数数组 n u m s nums nums 。每一次操作中&#xff0c;你可以将 n u m s nums nums 中 任意 一个元素替换成 任意 整数。 如果 n u m s nums nums 满足以下条件&…