当前位置: 首页 > news >正文

ElasticSearch - 在 微服务项目 中基于 RabbitMQ 实现 ES 和 MySQL 数据异步同步(考点)

目录

一、数据同步

1.1、什么是数据同步

1.2、解决数据同步面临的问题

1.3、解决办法

1.3.1、同步调用

1.3.2、异步通知(推荐)

1.3.3、监听 binlog

1.3、基于 RabbitMQ 实现数据同步

1.3.1、需求

1.3.2、在“酒店搜索服务”中 声明 exchange、queue、routingKey,同时开启监听

1.3.3、在“酒店管理服务”中发布消息

1.3.4、启动微服务并测试


一、数据同步


1.1、什么是数据同步

我们知道 elasticsearch 的数据是来源于 数据库(比如 mysql).  当我们在写了代码将 mysql 中的数据导入 es 中,那么这次导入之后 mysql 的数据并不会一成不变,将来我们的业务中会有 crud,数据库中的数据就和有新增、修改、删除,那么 mysql 数据一定那发生变化, es 如果不跟着变化,就会出现问题.

比如在一个商城系统中,到了 双11 ,数据库中的商品的价格下降,而 es 还是老价格,那么用户搜索时看到的商品的价格还是没有变化,用户可能就得考虑换软件了~  

因此,我们要保证 mysql 数据变化的时候 es 也能跟着同步变化,这就是数据同步.

Ps:实际上不光是 es 存在数据同步问题,凡是涉及到数据库双写的情况,比如 redis 和 mysql,都会存在数据同步问题.

1.2、解决数据同步面临的问题

如果你现在是一个单体式的项目,所有业务都写在一个项目中,那就比较好办,无非就是在及逆行新增、修改、删除业务的时候,同时把 es 也一起更新就  ok.

但是如果我们是一个 微服务 架构的项目上,不同的业务往往会在不同的微服务上,比如 “商品数据管理业务” 和 “商品数据搜索业务” 肯定会在两个不同的微服务上,那么跨微服务的项目就没办法直接操作了.

1.3、解决办法

1.3.1、同步调用

假设我们现在有两个微服务,一个是 酒店数据管理服务,另一个是酒店数据搜索服务. 假设这两个服务之间互相不能访问对方的数据库,也就是说,酒店管理服务只能访问 mysql,而 酒店搜索服务 只能访问 es,这也符合 微服务 里的标准和规范.

这里有一种办法是同步调用,步骤如下:

1.比如用户做新增操作时,首先把数据写到数据库里.

2. 数据库写完了以后紧接着调用 酒店搜索服务中的 “更新索引库” 的接口.

3. 更新 es.

最后更新完了 es 就把响应反馈给搜索服务,然后搜索服务才会把把响应反馈给  管理服务,然后再反馈给用户.  这整个过程依次执行,因此也叫同步调用.

缺陷:

1. 数据耦合,业务耦合:原本只是写数据库,写完就结束了,然后现在还需要再写完数据库的代码后面再加上 调用 “更新索引库” 接口的代码,而且这调用 这个接口的业务跟我新增业务显然没有关系啊,现在业务耦合在一起,将来必然也会影响性能.

2. 影响性能(耦合带来的问题):原本数据库写完了,比如耗时 50ms,但是现在写完数据库,你还得等待后台调用这个接口返回的响应,而这个接口又要等待 es 这里的响应,假如这里也耗时 50ms,那么总的耗时不就是这个三个步骤相加的,达到 100 ms.

3. 牵一发而动全身(耦合带来的问题):如果 步骤 2 和 步骤 3 任意一个位置出现了异常,就会导致整个业务也出现崩溃.

同步调用这么多问题,那么就需要考虑别的方案了.

1.3.2、异步通知(推荐)

这里就需要使用到 mq 来实现了,步骤如下:

1. 当有人做新增操作时,先去写数据库.

2. 写完之后,不调用任何服务的接口,而是向 mq 发送一个消息,通知一下 其他服务:“我这里数据新增了啊~”,整个步骤到这里结束.

那么至于谁来监听这个消息,监听了以后做什么,跟我有关系吗?没关系,这样一来,业务的耦合就解除了;  至于其他服务耗时多少秒,跟我也没关系,我写完数据库,发完消息就结束了,因此性能也提升了;再者,就算其他服务出现异常了,跟我这里也没关系.

缺陷:

1. 这样一来,比较依赖 mq 消息的可靠性.

2. 引入新的中间件,实现的复杂度也会有一定的上升.

不过这些缺陷,跟同步调用比起来,算不了什么,因此这也是比较推荐的方案.

1.3.3、监听 binlog

mysql 默认情况下 binlog 时关闭的,一旦开启,那么每次 mysql 在做增删改的时候,都会记录相应的操作到 binlog 中.

那么可以使用类似于 canal 这样的中间件来监听 binlog,一旦发现变化,立马通知对应的微服务,这个时候就知道数据发生变更,就可以进行更新了.

优势:

这种方案他既不给任何中间件发消息,也不去调用任何接口,因此耦合度是最低的.

劣势:

1.开启 binlog,对 mysql 的压力就增加了.

2.引入新的中间件.

1.3、基于 RabbitMQ 实现数据同步

1.3.1、需求

现在有两个微服务:“酒店管理服务” 和 "酒店搜索服务"

用户操作 “酒店管理服务” 进行增删改数据、要求对 "酒店搜索服务" 中的 es 的数据也要完成相同的数据更改操作.

这里使用 MQ 的异步方式实现数据同步.

1.3.2、在“酒店搜索服务”中 声明 exchange、queue、routingKey,同时开启监听

在 “酒店搜索服务” 中去声明一个 exchange,用来接收 增删改 的消息,接着声明两个队列即可,一个队列用来增改(这两用一个队列是因为在 es 中,增改可以使用同一个 DSL 语句实现),另一个用来删除(这里我是以 Bean 的方式注入到容器中了).

public class MqConstants {//主题交换机public static final String EXCHANGE_TOPIC = "hotel.topic";//增加 or 修改酒店 队列public static final String INSERT_QUEUE = "hotel.insert.queue";//删除酒店 队列public static final String DELETE_QUEUE = "hotel.delete.queue";//增加 or 修改酒店 routingKeypublic static final String INSERT_KEY = "hotel.insert.key";//删除酒店 routingKeypublic static final String DELETE_KEY = "hotel.delete.key";}
@Configuration
public class MqConfig {@Beanpublic TopicExchange hotelTopicExchange() {return new TopicExchange(MqConstants.EXCHANGE_TOPIC, true, false);}@Beanpublic Queue hotelInsertQueue() {return new Queue(MqConstants.INSERT_QUEUE, true);}@Beanpublic Queue hotelDeleteQueue() {return new Queue(MqConstants.DELETE_QUEUE, true);}@Beanpublic Binding hotelInsertBinding() {return BindingBuilder.bind(hotelInsertQueue()).to(hotelTopicExchange()).with(MqConstants.INSERT_KEY);}@Beanpublic Binding hotelDeleteBinding() {return BindingBuilder.bind(hotelDeleteQueue()).to(hotelTopicExchange()).with(MqConstants.DELETE_KEY);}}

Ps:此类(MqConfig)的包必须与启动类同级,否则声明交换机和队列失败.

最后就可以使用 @RabbitListener 监听 队列 了.

@Component
public class MqListener {@Autowiredprivate IHotelService hotelService;@RabbitListener(queues = MqConstants.INSERT_QUEUE)public void HotelInsertOrUpdateListener(Long id) {hotelService.insertHotelById(id);}@RabbitListener(queues = MqConstants.DELETE_QUEUE)public void HotelDeleteListener(Long id) {hotelService.deleteHotelById(id);}}

Ps:此类(MyListener,监听者类)上必须要有 @Component 注解(交由给 Spring 来管理),否则声明的交换机和队列无效.

1.3.3、在“酒店管理服务”中发布消息

酒店管理服务中,一旦用户进行酒店的 增删改,就会对数据库信息进行修改,然后将增删改的消息发布到 MQ 中.

Ps:这里不要发送 hotel 整体数据,太大可能会导致占满队列(Mq 是基于内存存储的,因此会设定队列上限),因此这里发送 id 即可.  es 这边拿到 id,就可进行相应的增删改.

    @PostMappingpublic void saveHotel(@RequestBody Hotel hotel){// 新增酒店hotelService.save(hotel);rabbitTemplate.convertAndSend(MqConstants.EXCHANGE_TOPIC, MqConstants.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.EXCHANGE_TOPIC, MqConstants.INSERT_KEY, hotel.getId());}@DeleteMapping("/{id}")public void deleteById(@PathVariable("id") Long id) {//删除酒店信息hotelService.removeById(id);rabbitTemplate.convertAndSend(MqConstants.EXCHANGE_TOPIC, MqConstants.DELETE_KEY, id);}

1.3.4、启动微服务并测试

a)在酒店管理页面中,修改 “7天连锁酒店(上海莘庄地铁站店)” 为 “7天连锁酒店(此处正在施工,请谨慎前往)”,如下.

b)在酒店搜索页面中,搜索 “施工” 关键词,就可以看到在 “酒店管理服务” 中更新的信息,已经同步到了 “酒店搜索服务” 中.

相关文章:

ElasticSearch - 在 微服务项目 中基于 RabbitMQ 实现 ES 和 MySQL 数据异步同步(考点)

目录 一、数据同步 1.1、什么是数据同步 1.2、解决数据同步面临的问题 1.3、解决办法 1.3.1、同步调用 1.3.2、异步通知(推荐) 1.3.3、监听 binlog 1.3、基于 RabbitMQ 实现数据同步 1.3.1、需求 1.3.2、在“酒店搜索服务”中 声明 exchange、…...

Springboot+vue的企业人事管理系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频: Springbootvue的企业人事管理系统(有报告),Javaee项目,springboot vue前后端分离项目。 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的企业人事管理系统,采用M(model&am…...

初识Java 11-1 函数式编程

目录 旧方式与新方式 lambda表达式 方法引用 Runnable 未绑定方法引用 构造器方法引用 函数式接口 带有更多参数的函数式接口 解决缺乏基本类型函数式接口的问题 本笔记参考自: 《On Java 中文版》 函数式编程语言的一个特点就是其处理代码片段的简易性&am…...

【Ambari】银河麒麟V10 ARM64架构_安装Ambari2.7.6HDP3.3.1问题总结

🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁 🦄 个人主页——🎐开着拖拉机回家_大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的帮助🌸文…...

李宏毅机器学习第一课(结尾附作业模型详细分析)

机器学习就是让机器找一个函数f,这个函数f是通过计算机找出来的 如果参数少的话,我们可以使用暴搜,但是如果参数特别多的话,我们就要使用Gradient Descent Regression (输出的是一个scalar数值) Classification (在…...

对日项目工作总结

从18年8月到23年中秋节,目前已经入职主营对日车载项目的公司满5年了,一般来说,在一家公司工作工作超过3年,如果是在比较大型以及流程规范的公司,那么该公司的工作流程,工作思维会深深地烙印在该员工的脑海中…...

设计模式探索:从理论到实践的编码示例 (软件设计师笔记)

😀前言 设计模式,作为软件工程领域的核心概念之一,向我们展示了开发过程中面对的典型问题的经典解决方案。这些模式不仅帮助开发者创建更加结构化、模块化和可维护的代码,而且也促进了代码的复用性。通过这篇文章,我们…...

【内网穿透】在Ubuntu搭建Web小游戏网站,并将其发布到公网访问

目录 前言 1. 本地环境服务搭建 2. 局域网测试访问 3. 内网穿透 3.1 ubuntu本地安装cpolar 3.2 创建隧道 3.3 测试公网访问 4. 配置固定二级子域名 4.1 保留一个二级子域名 4.2 配置二级子域名 4.3 测试访问公网固定二级子域名 前言 网:我们通常说的是互…...

在cesuim上展示二维模型

前提问题:在cesuim上展示二维模型 解决过程: 1.获取或定义所需变量 2.通过window.cesium.viewer.imageryLayers.addImageryProvider和new Cesium.UrlTemplateImageryProvider进行建模 3.传入url路径后拼接{z}/{x}/{y}.png 4.聚焦到此模型window.ces…...

c/c++中如何输入pi

标准的 C/C 语言中没有π这个符号及常量,一般在开发过程中是通过开发人员自己定义这个常量的,最常见的方式是使用宏定义: 方法1:#define pi 3.1415926 方法2:使用反三角函数const double pi acos(-1.0);...

python爬虫:JavaScript 混淆、逆向技术

Python爬虫在面对JavaScript混淆和逆向技术时可能会遇到一些挑战,因为JavaScript混淆技术和逆向技术可以有效地阻止爬虫对网站内容的正常抓取。以下是一些应对这些挑战的方法: 分析网页源代码:首先,尝试分析网页的源代码&#xf…...

Vue error:0308010C:digital envelope routines::unsupported

vue项目,npm run dev的时候出现:Error: error:0308010C:digital envelope routines::unsupported vue项目,npm run dev的时候出现:Error: error:0308010C:digital envelope routines::unsupported 这个是node的版本问题。我的nod…...

gitee 远程仓库操作基础(一)

git remote add <远程仓库名> <仓库远程地址> :给远程仓库取个别名,简化一大堆字符串操作 git remote add origin xxx.git :取个Origin名字 git remote -v :查看本地存在的远程仓库 git pull <远程仓库名><远程分支名>:<本地分支名> 相同可取消…...

DRM全解析 —— ADD_FB2(0)

本文参考以下博文&#xff1a; DRM驱动&#xff08;四&#xff09;之ADD_FB 特此致谢&#xff01; 在笔者之前的libdrm全解析系列文章中&#xff0c;讲到了drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &f)以及其封装函数drmModeAddFB。对应的文章链接为&#xff1a; libdrm全解…...

01Redis的安装和开机自启的配置

安装Redis 单机安装Redis 大多数企业都是基于Linux服务器来部署项目&#xff0c;而且Redis官方也没有提供Windows版本的安装包(此处选择的Linux版本的CentOS 7) Windows版直接下载对应版本的.zip压缩包解压即可使用 第一步: Redis是基于C语言编写的&#xff0c;因此首先需要…...

进入IT行业:选择前端开发还是后端开发?

一、前言 开发做前端好还是后端好&#xff1f;这是一个常见的问题&#xff0c;特别是对于初学者来说。在编程世界中&#xff0c;前端开发和后端开发分别代表着用户界面和数据逻辑&#xff0c;就像城市的两个不同街区一样。但是&#xff0c;究竟哪个街区更适合我们作为开发者呢…...

Java集成Onlyoffice以及安装和使用示例,轻松实现word、ppt、excel在线编辑功能协同操作,Docker安装Onlyoffice

安装Onlyoffice 拉取onlyoffice镜像 docker pull onlyoffice/documentserver 查看镜像是否下载完成 docker images 启动onlyoffice 以下是将本机的9001端口映射到docker的80端口上&#xff0c;访问时通过服务器ip&#xff1a;9001访问&#xff0c;并且用 -v 将本机机/data/a…...

编程面试_动态规划

题目1 最大连续乘积子串 题目描述给一个浮点数序列&#xff0c;取最大乘积连续子串的值&#xff0c;例如 -2.5&#xff0c;4&#xff0c;0&#xff0c;3&#xff0c;0.5&#xff0c;8&#xff0c;-1&#xff0c;则取出的最大乘积连续子串为3&#xff0c;0.5&#xff0c;8。也就…...

ip地址可以精确定位吗

在互联网时代&#xff0c;IP地址的重要性不言而喻。作为网络通信的基础&#xff0c;IP地址用于标识每一台连接到互联网的设备。然而&#xff0c;传统的IP地址定位方式仅能粗略地确定设备的大致位置&#xff0c;无法实现精确定位。那么&#xff0c;IP地址能否实现精确定位呢&…...

Xamarin体验:使用C#开发iOS/Android应用

http://www.cnblogs.com/lwme/p/use-xamarin-develop-Android-iOS-app.html Xamarin是Mono创始人Miguel de Icaza创建的公司,旨在让开发者可以用C#编写iOS, Android, Mac应用程序,也就是跨平台移动开发。 简介 Xamarin是基于Mono的平台,目前主要有以下产品(更具体请见:h…...

聊聊druid连接池的监控

序 本文主要研究一下druid连接池的监控 init com/alibaba/druid/pool/DruidDataSource.java public void init() throws SQLException {//......registerMbean();//...... }DruidDataSource的init方法会执行registerMbean registerMbean com/alibaba/druid/pool/DruidData…...

CentOS 7 安装 Docker 的详细步骤

文章目录 Docker简介1.更新2.安装必要的软件包3.添加Docker仓库4.安装5.安装后的一些常规设置及常用的命令5.1 启动 Docker5.2 Docker 在系统启动时自动运行5.3 运行一个 Hello World 镜像5.4 查看docker运行状态5.5 docker ps5.6 查看docker版本 6.安装种常见的错误错误1:yum-…...

竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…...

数据结构之【泛型】

泛型&#xff1a;定义阶段不明确具体类型&#xff0c;产生对象时明确具体类型。 //Object是Java中的最高参数统一化&#xff0c;能够接受所有的引用类型&#xff1b; //有了包装类的自动拆装箱之后&#xff0c;Object还能够接收基本类型数值&#xff08;自动装箱&#xff09; …...

华为ac无线侧命令行配置思路和步骤

无线侧配置思路&#xff1a; Ap和ac在同一个广播域内&#xff0c;不用配置 option 43 source 源ip回包哪个模式都得配置 Cli配置业务模版流程&#xff1a; 1、 AC控制器上全局配置capwap回包接口地址 1、配置ssid&#xff1a;wifi名称 2、配置安全模版&#xff1a;用户连接密码…...

十六)Stable Diffusion教程:出图流程化

今天说一个流程化出图的案例&#xff0c;适用很多方面。 1、得到线稿&#xff0c;自己画或者图生图加线稿lora出线稿&#xff1b;如果想sd出图调整参数不那么频繁细致&#xff0c;则线稿的素描关系、层次、精深要表现出来&#xff0c;表现清楚。 2、文生图&#xff0c;seed随机…...

SpringBoot全局异常处理源码

SpringBoot全局异常处理源码 一、SpringMVC执行流程二、SpringBoot源码跟踪三、自定义优雅的全局异常处理脚手架starter自定义异常国际化引入封装基础异常封装基础异常扫描器&#xff0c;并注册到ExceptionHandler中项目分享以及改进点 一、SpringMVC执行流程 今天这里叙述的全…...

设计模式——7. 装饰者模式

1. 说明 装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许你在不改变对象接口的前提下,动态地将新行为附加到对象上。这种模式是通过创建一个包装(或装饰)对象,将要被装饰的对象包裹起来,从而实现对原有对象功能的增强和扩展。 装饰者模式的主要特点包括:…...

安卓玩机-----反编译apk 修改apk 去广告 去弹窗等操作中的一些常识

安卓机型app的编译与反编译 apk文件的简单说明与解析 -安卓修改apk apk的组成和编译 一 电脑端几种反编译apk工具操作步骤解析 前面几个博文有说明关于反编译apk和apk架构等有些常识.今天对以上做个补充。初学者记住一点。对于一个apk文件使用压缩软件7zip打开可以查看到文件…...

Hoeffing不等式

在李航老师的统计学习方法&#xff08;第一版中&#xff09; H o e f f i n g 不等式 Hoeffing不等式 Hoeffing不等式是这样子给出的 设 X 1 , X 2 , . . . , X N X_1,X_2,...,X_N X1​,X2​,...,XN​是独立随机变量&#xff0c;且 X i ∈ [ a i , b i ] , i 1 , 2 , . . . ,…...

好多网站没排名了/个人网页制作

linux目录的大小4k怎么来的&#xff1f;发布时间:2010-08-05 13:54:37来源:红联作者:xfox如下命令&#xff1a;lufenglufeng-desktop:~$ ls -lh /总用量 93Kdrwxr-xr-x 2 root root 4.0K 2010-08-03 13:18 bindrwxr-xr-x 4 root root 1.0K 2010-08-03 13:28 bootdrwxr-xr-x 2 r…...

大连精美网站制作/百度代发排名

北京时间 2019 年 10 月 9 日&#xff0c;微软发布了全新的 VS Code Python 插件&#xff0c;带来了众多更新&#xff01;其中&#xff0c;最大的更新就要属万众期待的 Jupyter Notebook 原生支持了&#xff01;我们来看看这次 Jupyter Notebook 的原生支持带来了哪些好用的功能…...

网站管理工作一般包括/成都网络营销

点击上方“Java基基”&#xff0c;选择“设为星标”做积极的人&#xff0c;而不是积极废人&#xff01;每天 14:00 更新文章&#xff0c;每天掉亿点点头发...源码精品专栏 原创 | Java 2021 超神之路&#xff0c;很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框…...

做网站电信运营许可证/营销推广方案ppt案例

zabbix官方的一句话描述zabbix&#xff1a; 监视任何事情适用于任何IT基础架构&#xff0c;服务&#xff0c;应用程序和资源的解决方案 Monitor anythingSolutions for any kind of IT infrastructure, services, applications, resources ---------------------------------…...

wordpress 清理媒体库/网站制作方案

2019独角兽企业重金招聘Python工程师标准>>> Java 垃圾回收调优不同于任何其它性能优化活动。 首先你要确保自己足够了解整个应用的情况以及调优预期的结果&#xff0c;而不是单单满足于应用的某一部分调优。一般情况下&#xff0c;遵循以下过程比较容易&#xff1a…...

做设计的地图网站/网站怎样优化文章关键词

ZMQ (以下 ZeroMQ 简称 ZMQ)是一个简单好用的传输层&#xff0c;像框架一样的一个 socket library&#xff0c;他使得 Socket 编程更加简单、简洁和性能更高。是一个消息处理队列库&#xff0c;可在多个线程、内核和主机盒之间弹性伸缩。ZMQ 的明确目标是“成为标准网络协议栈的…...