实现elasticsearch和数据库的数据同步
1. 数据同步
elasticsearch中的酒店数据来自于mysql数据库,因此mysql数据发生改变时,elasticsearch也必须跟着改变,这个就是elasticsearch与mysql之间的数据同步。

1.1. 思路分析
常见的数据同步方案有三种:
-
同步调用
-
异步通知
-
监听binlog
1.2. 同步调用
方案一:同步调用:

基本步骤如下:
-
hotel-demo对外提供接口,用来修改elasticsearch中的数据
-
酒店管理服务在完成数据库操作后,直接调用hotel-demo提供的接口
优缺点:
-
优点:实现简单,粗暴
-
缺点:业务耦合度高
1.3. 异步通知
方案二:异步通知:

流程如下:
-
hotel-admin对mysql数据库数据完成增、删、改后,发送MQ消息
-
hotel-demo监听MQ,接收到消息后完成elasticsearch数据修改
优缺点:
-
优点:低耦合,实现难度一般
-
缺点:依赖mq的可靠性
1.4. 监听binlog
方案三:监听binlog:

流程如下:
-
给mysql开启binlog功能 (平时默认关闭)
-
mysql完成增、删、改操作都会记录在binlog中
-
hotel-demo基于canal监听binlog变化,实时更新elasticsearch中的内容
1.5. 总结
实现elasticsearch和数据库数据同步一般有以下三种方法:
方式一:同步调用
-
优点:实现简单,粗暴
-
缺点:业务耦合度高
方式二:异步通知
-
优点:低耦合,实现难度一般
-
缺点:依赖mq的可靠性
方式三:监听binlog
-
优点:完全解除服务间耦合
-
缺点:开启binlog增加数据库负担、实现复杂度高
2. 实现数据同步
2.1. 思路
利用hotel-admin项目作为酒店管理的微服务。当酒店数据发生增、删、改时,要求对elasticsearch中数据也要完成相同操作。
步骤:
-
声明exchange、queue、RoutingKey
-
在hotel-admin中的增、删、改业务中完成消息发送
-
在hotel-demo中完成消息监听,并更新elasticsearch中数据
-
启动并测试数据同步功能
2.2. hotel-admin
其中包含了酒店的CRUD功能:

2.3. 声明交换机和队列
MQ结构如图:

2.3.1. 引入依赖
在hotel-admin、hotel-demo中引入rabbitmq的依赖:
<!--amqp-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.3.2. 声明交换机名称
在hotel-admin和hotel-demo中的cn.itcast.hotel.constatnts包下新建一个类MqConstants:

代码如下:
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";//新增或修改的RoutingKeypublic final static String HOTEL_INSERT_KEY = "hotel.insert";//删除的RoutingKeypublic final static String HOTEL_DELETE_KEY = "hotel.delete";}
2.3.3. 声明队列交换机
在hotel-demo中建一个config包,包下建一个配置类MqConfig,声明队列、交换机:
package cn.itcast.hotel.config;import cn.itcast.hotel.constants.MqConstants;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 基于Bean的形式生成交换机和队列* 以及将他们绑定*/
@Configuration
public class MqConfig {//生成topic交换机@Beanpublic TopicExchange topicExchange(){return new TopicExchange(MqConstants.HOTEL_EXCHANGE,true,false);}//insert队列@Beanpublic Queue insertQueue(){return new Queue(MqConstants.HOTEL_INSERT_QUEUE,true);}//delete队列@Beanpublic Queue deleteQueue(){return new Queue(MqConstants.HOTEL_DELETE_QUEUE,true);}//绑定insert队列和交换机@Beanpublic Binding insertQueueBinding(){return BindingBuilder.bind(insertQueue()).to(topicExchange()).with(MqConstants.HOTEL_INSERT_KEY);}//绑定delete队列和交换机@Beanpublic Binding deleteQueueBinding(){return BindingBuilder.bind(deleteQueue()).to(topicExchange()).with(MqConstants.HOTEL_DELETE_KEY);}}
2.4. 发送MQ消息
在hotel-admin中的增、删、改业务中分别发送MQ消息: 
2.5. 接受MQ消息
hotel-demo接收到MQ消息要做的事情包括:
-
新增消息:根据传递的hotel的id查询hotel信息,然后新增一条数据到索引库
-
删除消息:根据传递的hotel的id删除索引库中的一条数据
2.5.1. 添加新增、删除业务
首先在hotel-demo的cn.itcast.hotel.service包下的IHotelService中新增新增、删除业务
void deleteById(Long id);void insertById(Long id);
2.5.2. 实现业务
@Override
public void deleteById(Long id) {try {// 1.准备RequestDeleteRequest request = new DeleteRequest("hotel", id.toString());// 2.发送请求client.delete(request, RequestOptions.DEFAULT);} catch (IOException e) {throw new RuntimeException(e);}
}@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);}
}
2.5.3. 编写监听器
在hotel-demo中的cn.itcast.hotel.mq包新增一个类:
package cn.itcast.hotel.mq;import cn.itcast.hotel.constants.MqConstants;
import cn.itcast.hotel.service.IHotelService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class HotelListener {@Autowiredprivate IHotelService hotelService;/*** 监听酒店新增或修改的业务* @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);}
}
这样,就可以实现elasticsearch和Mysql数据库的数据同步了!
3. 测试
tips:记得开启RabbitMQ
我们来测试一下:
3.1 启动hotel-demo和hotel-admin服务:
访问浏览器:


我们看到“上海虹口三至喜来登酒店” 的价格是 1899
我们去酒店管理端修改一下:
3.2. 修改操作
打开酒店管理端,然后找到该酒店,进行修改:
我们将价格改为1898:

![]()
3.3.查看结果
此时可以先打开RabbitMQ的控制台,可以看见确实有消息发送了:

我们再打开前端页面,刷新查看:

“上海虹口三至喜来登酒店” 价格确实变成了1898
在此期间,我们并未对elasticsearch进行手动修改数据,说明我们确实完成了基于MQ的elasticsearch和mysql数据库之间数据的消息同步!
相关文章:
实现elasticsearch和数据库的数据同步
1. 数据同步 elasticsearch中的酒店数据来自于mysql数据库,因此mysql数据发生改变时,elasticsearch也必须跟着改变,这个就是elasticsearch与mysql之间的数据同步。 1.1. 思路分析 常见的数据同步方案有三种: 同步调用 异步通知…...
SwiftUI的Alert使用方式
SwiftUI的Alert使用方式 记录一下SwiftUI的Alert使用方式,比较简单直接上代码 import SwiftUIstruct AlertBootCamp: View {State var showAlert falsevar body: some View {Button {showAlert.toggle()} label: {Text("alert show")}/// 单按钮 // …...
FPGA高端项目:FPGA基于GS2971的SDI视频接收+GTX 8b/10b编解码SFP光口传输,提供2套工程源码和技术支持
目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收转HDMI输出应用本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放Video Mixer多路视频拼接应用本方案的SDI接收OSD动态字符叠加…...
【源码编译】Apache SeaTunnel-Web 适配最新2.3.4版本教程
Apache SeaTunnel新版本已经发布,感兴趣的小伙伴可以看之前版本发布的文章 本文主要给大家介绍为使用2.3.4版本的新特性,需要对Apache SeaTunnel-Web依赖的版本进行升级,而SeaTunnel2.3.4版本部分API跟之前版本不兼容,所以需要对 …...
数据集下载
一、数据集下载——谷歌Open images 谷歌Open-image-v6是由谷歌出资标注的一个超大型数据集,数据大小达到600多G,类别达到600多种分类,对于普通研究者而言,根本没办法全部下载下来做测试,也没必要。只需要下载与自己任…...
3、设计模式之工厂模式2(Factory)
一、什么是工厂模式 工厂模式属于创建型设计模式,它用于解耦对象的创建和使用。通常情况下,我们创建对象时需要使用new操作符,但是使用new操作符创建对象会使代码具有耦合性。工厂模式通过提供一个公共的接口,使得我们可以在不暴露…...
npm、nodejs和vue之间关系和区别介绍
本文讲解npm、Node.js和Vue.js这三者之间的关系和区别,以及它们各自的特点。 首先,让我们来了解一下Node.js。 **Node.js** 是一个开源的服务器端运行环境,它允许开发者使用JavaScript来编写服务器端的代码。在传统的Web开发中&#…...
DM数据库安装(Windows)
先解压安装包 点击setup安装 下一步 勾选接受然后下一步 下一步 选择典型安装下一步 下一步 搜索DM数据库配置助手然后一直下一步 然后搜索DM管理工具 登录 登录成功 widows版本安装成功...
Python的asyncio 多线程
-- 多线程、进程、协程是什么就不讲了,(就是你理解的一边呼吸,一边看文章) 仅解决问题的话,下边两篇不用看, Python 中的 async await 概念-CSDN博客 再深一点的看这个 Python中的多线程、进程、协程、…...
【分类讨论】【解析几何】【 数学】【推荐】1330. 翻转子数组得到最大的数组值
作者推荐 视频算法专题 本文涉及知识点 分类讨论 解析几何 LeetCode1330. 翻转子数组得到最大的数组值 给你一个整数数组 nums 。「数组值」定义为所有满足 0 < i < nums.length-1 的 |nums[i]-nums[i1]| 的和。 你可以选择给定数组的任意子数组,并将该子…...
一文了解Spring的SPI机制
文章目录 一文了解Spring的SPI机制Java SPIServiceLoader Spring SPISpringboot利用Spring SPI开发starter 一文了解Spring的SPI机制 Java SPI SPI 全称 Service Provider Interface ,是 Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用…...
django根据时间(年月日)动态修改表名--方法一
方法一: 第一步:在models创建一个类,里边存放数据表中需要的字段,如下 class TemplateModel(models.Model):NowTime models.CharField(max_length5)name models.CharFiedld(max_length5)class Meta:abstract True # 基础类设…...
实现基本的登录功能
一、登录功能的前端处理过程 1、导入项目所需的图片和CSS等静态文件 参考代码存放client节点的/opt/code目录下 执行如下命令: [rootclient ~]# cp -r /opt/code/kongguan_web/src/assets/* /root/kongguan_web/src/assets/ 将参考代码中的css、icon、images等文…...
Java线程池实现原理及其在美团业务中的实践
随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。 J.U.C提供的线程池:ThreadPoolExecutor类,帮助开发人员管理线程并方便地执行并行任务。了解并合理…...
让AI给你写代码(四)—— 初步利用LangChain Agent根据输入生成,保存,执行
要进一步提升智能编码助手的效率,我觉得需要做到两点 1) 进一步让主人聚焦于设计输入以及结果验证的循环 2) 进一步让智能编码助手聚焦于代码实现和程序流程(保存、打开,修订、执行、合并…) 正好接触到LLM…...
Flutter does not exist
Flutter does not exist 原因:Generated.config 配置文件内路径缺失 原因:Flutter SDK缺失 通过配置文件查到Flutter SDK在本地的存放位置FLUTTER_FRAMEWORK_DIR/Users/haijunyan/Documents/flutter/bin/cache/artifacts/engine/ios 真机所需…...
AIX上安装gcc和g++
AIX的iso镜像中没有gcc的软件包,需要我们自己下载,我们可以在 Index of /download/rpmdb/deplists/aix72 下载对应gcc和g版本的依赖文件deps 我们使用的是4.9.4版本的软件包 我们首先安装gcc,在http://www.oss4aix.org/download/everythi…...
js实现扫描线填色算法使用canvas展示
算法原理 扫描线填色算法的基本思想是:用水平扫描线从上到下扫描由点线段构成的多段构成的多边形。每根扫描线与多边形各边产生一系列交点。将这些交点按照x坐标进行分类,将分类后的交点成对取出,作为两个端点,以所填的色彩画水平…...
考研模拟面试-题目【攻略】
考研模拟面试-题目【攻略】 前言版权推荐考研模拟面试-题目前面的问题通用问题专业题数据结构计算机网络操作系统数据库网络安全 手写题数据结构操作系统计算机网络 代码题基础代码题其他代码题 后面的问题补充题目 最后 前言 2023-10-19 12:00:57 以下内容源自《考研模拟面试…...
Frostmourne - Elasticsearch源日志告警配置
简介 配置Frostmourne 接入Elasticsearch源进行日志匹配告警,并静默规则,告警消息发送到企业微信,告警信息使用Markdown。 部署安装教程查看: https://songxwn.com/frostmourne_install ELK 安装教程:https://songx…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
