微服务—ES数据同步

news2024/11/26 12:51:35

目录

数据同步

问题分析

方案1. 同步调用

方案2. 异步通知

方案3. 监听binlog​编辑 

各方案对比

案例——利用MQ实现数据同步

步骤1. 导入hotel-admin项目

步骤2. 声明交换机、队列

步骤3. 发送MQ消息

步骤4. 接收MQ消息

步骤5. 测试同步功能


数据同步

        elasticsearch中的数据是由我们通过mysql数据进行导入的,因此mysql数据发生改变时,elasticsearch中的数据也必须跟着改变,这就是elasticsearch与mysql之间的数据同步


问题分析

        在微服务中,负责酒店管理(操作mysql)的业务与负责酒店搜索(操作elasticsearch)的业务可能在两个不同的微服务上,那么数据同步该如何实现呢?

方案1. 同步调用

基本步骤:
hotel-demo对外提供接口,用来修改elasticsearch中的数据,酒店管理服务在完成数据库操作后,直接调用hotel-demo提供的接口。  


方案2. 异步通知

 

基本步骤:
hotel-admin对mysql数据库数据完成增、删、改后,发送MQ消息,hotel-demo监听MQ,接收到消息后完成elasticsearch数据修改。


方案3. 监听binlog

基本步骤:
给mysql开启binlog功能,mysql完成增、删、改操作都会记录在binlog中,hotel-demo基于canal监听binlog变化,实时更新elasticsearch中的内容。


各方案对比

方案一:同步调用
优点:实现简单,粗暴
缺点:业务耦合度高

方案二:异步通知
优点:低耦合,实现难度一般
缺点:依赖mq的可靠性

方案三:监听binlog
优点:完全解除服务间耦合
缺点:开启binlog增加数据库负担、实现复杂度高


案例——利用MQ实现数据同步

        利用课前资料提供的hotel-admin项目作为酒店管理的微服务。当酒店数据发生增、删、改时,要求对elasticsearch中的数据也要完成相同操作。


步骤1. 导入hotel-admin项目

导入课前资料提供的hotel-admin项目,注意修改数据库配置为本地数据库,运行并访问http://localhost:8099进入管理界面。

项目中包含了酒店的CRUD功能: 


步骤2. 声明交换机、队列

MQ结构如图:

在hotel-admin、hotel-demo项目中做以下4步

1. 引入rabbitmq的依赖:  

<!--amqp-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2. 设置rabbitmq配置:

3. 设置队列与交换机名称常量:

package cn.itcast.hotel.constants;

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";
}

4. 声明队列与交换机名称:
队列与交换机的声明可以采用注解或者bean的方式,这里采用bean的方式进行声明。

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.TopicExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MqConfig {
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange(MqConstants.HOTEL_EXCHANGE, true, false);
    }

    @Bean
    public Queue insertQueue(){
        return new Queue(MqConstants.HOTEL_INSERT_QUEUE, true);
    }

    @Bean
    public Queue deleteQueue(){
        return new Queue(MqConstants.HOTEL_DELETE_QUEUE, true);
    }

    @Bean
    public Binding insertQueueBinding(){
        return BindingBuilder.bind(insertQueue()).to(topicExchange()).with(MqConstants.HOTEL_INSERT_KEY);
    }

    @Bean
    public Binding deleteQueueBinding(){
        return BindingBuilder.bind(deleteQueue()).to(topicExchange()).with(MqConstants.HOTEL_DELETE_KEY);
    }
}

步骤3. 发送MQ消息

在hotel-admin中的增、删、改业务中分别设置MQ消息发送


步骤4. 接收MQ消息

hotel-demo接收到MQ消息要做的事情包括:
新增消息:根据传递的hotel的id查询hotel信息,然后新增一条数据到索引库
删除消息:根据传递的hotel的id删除索引库中的一条数据

1. 首先在hotel-demo的cn.itcast.hotel.service包下的IHotelService中新增新增、删除业务

void deleteById(Long id);

void insertById(Long id);

2. 给hotel-demo中的cn.itcast.hotel.service.impl包下的HotelService中实现业务

@Override
public void deleteById(Long id) {
    try {
        // 1.准备Request
        DeleteRequest 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);
    }
}

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 {

    @Autowired
    private 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);
    }
}

步骤5. 测试同步功能

1. 重启消息接收方和消息发送方

(记录一个小bug:在mq消息监听类上忘记添加注解@Component,导致一开始没有监听到消息)

2.在旅游页面可以发现上海希尔顿酒店价格为2680

3.在酒店管理页面将该酒店的价格重新设置为3000

4.重新回到旅游页面搜索该酒店,可以发现价格发生变化,证明数据同步成功。(删除功能同理)

 

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

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

相关文章

小白学Halcon100例:如何获取物品中心坐标并展示

文章目录 *读入彩色图片*分解彩色图片为三通道*阈值分割*链接*选择特征*提取目标中心*绘制目标中心--*设置线宽为1*创建十字轮廓*清空窗体*设置绘制模式为绘制边缘*显示目标*显示目标中心*读入彩色图片

算法学习——LeetCode力扣回溯篇4

算法学习——LeetCode力扣回溯篇4 332. 重新安排行程 332. 重新安排行程 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票…

python 基础知识点(蓝桥杯python科目个人复习计划41)

今日复习内容&#xff1a;动态规划&#xff08;基础&#xff09; 动态规划是一种解决多阶段决策过程中最优化问题的数学方法和算法思想。它通常用于解决具有重叠子问题和最优子结构性质的问题&#xff0c;通常将问题划分为相互重叠的子问题&#xff0c;利用子问题的解来求解原…

机器学习3----决策树

这是前期准备 import numpy as np import pandas as pd import matplotlib.pyplot as plt #ID3算法 #每个特征的信息熵 # target : 账号是否真实&#xff0c;共2种情况 # yes 7个 p0.7 # no 3个 p0.3 info_D-(0.7*np.log2(0.7)0.3*np.log2(0.3)) info_D #日志密度…

一周学会Django5 Python Web开发-Django5 Hello World编写

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计14条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

Cocos2dx-lua ScrollView[一]基础篇

一.ScrollView概述 cocos游戏中ScrollView控件大量使用,95%以上的项目都会使用ScrollView,个别游戏可能全部使用翻页的滑动效果。如果想要精通Cocos的UI开发,精通ScrollView控件非常关键,因此对ScrollView的使用进行总结很有必要。 下文缩写说明:sv = ScrollView, item代…

Python Matplotlib 的学习笔记

Python Matplotlib 的学习笔记 0. Python Matplotlib 简介1. 为什么要用 Matplotlib&#xff1f;2. Matplotlib 基础类详解2-1. Line&#xff08;线&#xff09;2-2. Marker&#xff08;标记&#xff09;2-3. Text&#xff08;文本&#xff09;2-4. Legend&#xff08;图例&…

数据结构实验三 图的深度优先搜索(包含求连通分量)

全屏浏览作者 王群芳 单位 合肥师范学院 以邻接矩阵作存储结构&#xff0c;编写程序对给定的无向图&#xff08;图中包含n个顶点&#xff0c;编号为0至n-1&#xff09;进行深度优先遍历&#xff0c;并在遍历的过程中计算图G的连通分量个数及边的数目。 本题限定在遍历过程中…

车载软件架构 —— Adaptive AUTOSAR软件架构

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师&#xff08;Wechat&#xff1a;gongkenan2013&#xff09;。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 本就是小人物&#xff0c;输了就是输了&#…

蓝桥杯:C++排序

排序 排序和排列是算法题目常见的基本算法。几乎每次蓝桥杯软件类大赛都有题目会用到排序或排列。常见的排序算法如下。 第(3)种排序算法不是基于比较的&#xff0c;而是对数值按位划分&#xff0c;按照以空间换取时间的思路来排序。看起来它们的复杂度更好&#xff0c;但实际…

数模.传染病模型plus

一、SIS模型 二、SIR模型 三、SIRS模型 四、SEIR模型

Python第十六章(面向对象)

类&#xff1a;是对一系列相同特征和行为的事物的统称&#xff0c;是一个抽象的概念&#xff0c;不是真实存在的事物 特征&#xff1a;属性/变量 行为&#xff1a;方法/函数 对象&#xff1a;类创建出来的真实事物 类和对象的关系&#xff1a;先构造一个类&#xff0…

GitHub项目推荐-InstantID

项目地址 https://github.com/InstantID/InstantID 项目简述 InstantID是一个图生图项目&#xff0c;仅仅通过一张正脸的图片&#xff0c;就能生成各种风格的人像。该项目的文档描述比较齐备&#xff0c;所以复现起来成本比较小。 项目截图 这是项目介绍中的一张截图&…

二叉树基础总结

目录 树的定义&#xff1a; 深度和高度&#xff1a; 二叉树 由来 二叉树种类&#xff1a; 满二叉树&#xff1a; 完全二叉树&#xff1a; 严格二叉树&#xff08;Strict Binary Tree&#xff09;&#xff1a; 平衡二叉树&#xff08;Balanced Binary Tree&#xff09;&…

【阅读笔记】空域保边降噪《Side Window Filtering》

1、保边滤波背景 保边滤波器的代表包括双边滤波、引导滤波&#xff0c;但是这类滤波器有一个问题&#xff0c;它们均将待处理的像素点放在了方形滤波窗口的中心。但如果待处理的像素位于图像纹理或者边缘&#xff0c;方形滤波核卷积的处理结果会导致这个边缘变模糊。 基于这个…

算法刷题:有效三角形个数

有效三角形个数 .题目链接题目详情算法原理补充知识点双指针:对撞指针 我的答案 . 题目链接 有效三角形个数 题目详情 算法原理 补充知识点 有效三角形需要满足的条件: ab>cac>bbc>a 其实在满足1的时候,c是最大的,那么2和3是显然成立的,因此我们可以这样解题: 对…

【北邮鲁鹏老师计算机视觉课程笔记】10 Classification 分类

【北邮鲁鹏老师计算机视觉课程笔记】10 Classification 分类 1 图像识别的基本范式 检测问题&#xff1a;不仅要知道有没有&#xff0c;还要知道在哪里 分类是整图级标签&#xff0c;检测是区域级标签&#xff0c;分割是像素级标签 2 检测任务的应用 3 单实例识别与类别识别…

九、OpenCV自带colormap

项目功能实现&#xff1a;每隔1500ms轮流自动播放不同风格图像显示&#xff0c;按下Esc键退出 按照之前的博文结构来&#xff0c;这里就不在赘述了 一、头文件 colormap.h #pragma once #include<opencv2/opencv.hpp> using namespace cv;class ColorMap { public:vo…

Rust 数据结构与算法:1算法分析之乱序字符串检查

Rust 数据结构与算法 一、算法分析 算法是通用的旨在解决某种问题的指令列表。 算法分析是基于算法使用的资源量来进行比较的。之所以说一个算法比另一个算法好,原因就在于前者在使用资源方面更有效率,或者说前者使用了更少的资源。 ●算法使用的空间指的是内存消耗。算法…

浅谈业务场景中缓存的使用

业务场景中缓存的使用 一、背景二、缓存分类1.本地缓存2.分布式缓存 三、缓存读写模式1.读请求2.写请求 四、缓存穿透1.缓存空对象2.请求校验3.请求来源限制4.布隆过滤器 五、缓存击穿1.改变过期时间2.串行访问数据库 六、缓存雪崩1.避免集中过期2.提前更新缓存 七、缓存与数据…