1.业务使用场景

我们在使用表单动态添加字段,如果新增字段,再保存数据,这个时候就会出错,出错的原因是seata 再本地缓存元数据,修改物理表的时候,这个元数据并没有发生变化,因此需要刷新元数据,因为我们使用的是多服务实例的部署,因此,如果某个表发生变化时,所有的服务实例都需要将元数据进行刷新。

这个我们可以使用 redis 的订阅服务,当某个微服务的元数据发生变化时,我们可以使用redis通知各个微服务实例对数据进行更改。

redis 支持 发布订阅服务。

他有两个端:

  1. 订阅端

    可以有多个订阅端,可以订阅某个频道,当消息发送端发送消息时,订阅端可以接收到消息进行处理
  2. 消息发送端

    可以方某个频道发送消息。

2. 解决方案

在每一个微服务实例启动的时候,我们启用订阅,当元数据发生变化时,我们发布事件进行通知微服务实例。

相关代码:

public class SubPubUtil {

    /**
* 发布消息。
* @param channel
* @param message
*/
public static void publishMessage(String channel,String message ){
RedisTemplate<String, Object> redisTemplate= SpringUtil.getBean("redisTemplate");
redisTemplate.execute((RedisCallback<Long>) connection -> {
byte[] chanelBytes = channel.getBytes(StandardCharsets.UTF_8);
byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
connection.publish(chanelBytes,messageBytes);
return 1L;
});
} /**
* 订阅消息。
* @param channel
* @param listener
*/
public static void subscribeMessage(String channel,MessageListener listener){
RedisTemplate<String, Object> redisTemplate= SpringUtil.getBean("redisTemplate");
redisTemplate.execute((RedisCallback<Long>) connection -> {
byte[] chanelBytes = channel.getBytes(StandardCharsets.UTF_8);
connection.subscribe(listener,chanelBytes);
return 1L;
});
} }

在微服务实例启动时,启用订阅。

public class DbChangeListener  implements CommandLineRunner, Ordered {

    @Override
public void run(String... args) throws Exception {
SubPubUtil.subscribeMessage("dbChange", new MessageListener() {
@SneakyThrows
@Override
public void onMessage(Message message, byte[] bytes) {
String dataSource =new String(message.getBody(),"utf-8");
clearMedata(dataSource);
}
});
} /**
* 清理数据源的元数据。
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public void clearMedata(String dataSource) throws NoSuchFieldException, IllegalAccessException {
DataSourceProxy dataSourceProxy = (DataSourceProxy) DataSourceUtil.getDataSourcesByAlias(dataSource);
try (Connection connection = dataSourceProxy.getConnection()) {
TableMetaCacheFactory.getTableMetaCache(dataSourceProxy.getDbType()); TableMetaCacheFactory.getTableMetaCache(dataSourceProxy.getDbType())
.refresh(connection, dataSourceProxy.getResourceId());
} catch (Exception ignore) {
} } @Override
public int getOrder() {
return 0;
}
}

当元数据发生变化时,我们可以使用如下代码发布事件,通知各个微服务实例,对元数据进行清理。

public static void clearDbMetaData(String dataSource){
if(StringUtils.isEmpty(dataSource)){
dataSource=DataSourceUtil.LOCAL;
}
SubPubUtil.publishMessage("dbChange",dataSource);
}

使用redis 的订阅服务的更多相关文章

  1. RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用

    本文版权归博客园和作者本人吴双共同所有,转载请注明本Redis系列分享地址.http://www.cnblogs.com/tdws/tag/NoSql/ Redis Pub/Sub模式 基本介绍 Re ...

  2. [Redis]发布/订阅

    摘要 有这样的一个场景,管理员需要发布一条消息,所有的客户端都要受到通知.然后想到了发布订阅模式.使用redis的发布与订阅实现起来更简单一些,说做就做,这里弄个简单的demo,先模拟下. 核心代码 ...

  3. 利用redis的订阅和发布来实现实时监控的一个DEMO(Python版本)

    redis的list类型有个很好的特性,就是每次添加元素后会返回当前list的长度,利用这个特点,我们可以监控它的长度,比如我们的key是用户注册的IP地址,list中存放的是已经在此IP地址上注册的 ...

  4. redis发布订阅Java代码实现

    Redis除了可以用作缓存数据外,另一个重要用途是它实现了发布订阅(pub/sub)消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 为了实现redis的发布订阅机制,首先要打开re ...

  5. redis发布/订阅

    发布订阅简介 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息,消息之间通过channel传递. 准备工作 两台安装了redis的机器(虚拟 ...

  6. MariaDB主从复制,redis发布订阅,持久化,以及主从同步

      一. MariaDB主从复制 mysql基本操作 1 连接数据库 mysql -u root -p -h 127.0.0.1 mysql -u root -p -h 192.168.12.60 2 ...

  7. Redis发布订阅机制

    1. 什么是Redis Redis是一个开源的内存数据库,它以键值对的形式存储数据.由于数据存储在内存中,因此Redis的速度很快,但是每次重启Redis服务时,其中的数据也会丢失,因此,Redis也 ...

  8. Linux 安装redis,redis发布订阅,持久化

    安装redis 1.安装redis的方式 -yum (删除这个yum安装的redis,我们只用源码编译安装的) -rpm -源码编译 2.删除原本的redis yum remove redis -y ...

  9. 使用python来搞定redis的订阅功能

    好久没写博客了.   最近公司开了新项目,我负责的内容之一是系统的后端.具体项目内容我就不介绍了,但是用到的技术有些还是很有趣的,值得记录一下.今天介绍的就是其中一个:利用redis的pubsub订阅 ...

  10. Linux(6)- redis发布订阅/持久化/主从复制/redis-sentinel/redis-cluster、nginx入门

    一.redis发布订阅 Redis 通过 PUBLISH .SUBSCRIBE 等命令实现了订阅与发布模式. 其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个 ...

随机推荐

  1. 从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享

    从数据洞察到智能决策:合合信息&infiniflow RAG技术的实战案例分享 标题取自 LLamaIndex,这个内容最早提出于今年 2 月份 LlamaIndex 官方博客.从 22 年 ...

  2. Docker数据共享与持久化(六)

    接下来介绍如何在 Docker 内部以及容器之间管理数据,在容器中管理数据主要有两种方式: 数据卷(Data Volumes) 挂载主机目录 (Bind mounts) 一.数据卷 数据卷是一个可供一 ...

  3. Docker安装(安装Docker-CE)(三)

    现版本安装Docker已经非常简单了,有很多种方式,而自17年开始,Docker分为Docker-CE(社区版).Docker-EE(企业版),另外Docker-IO是较早的版本,通常用的都是Dock ...

  4. Java远程连接服务器实现文件上传下载及目录操作

    详情请阅读原文 在其基础之上做了进一步的封装 <!-- https://mvnrepository.com/artifact/com.jcraft/jsch --> <depende ...

  5. Android复习(三)清单文件中的元素——>grant-uri-permission、instrumentation、intent-filter、manifest、meta-data

    <grant-uri-permission> 语法: <grant-uri-permission android:path="string" android:pa ...

  6. jenkins + sonar 实现代码检测的配置

    一.首先安装sonar scanner的客户端 我的jenkins版本为2.176.2 安装sonar需要安装客户端和服务端,这里只讲述客户端的相关配置.安装步骤省略 二.然后配置sonar scan ...

  7. C# 并发控制框架:单线程环境下实现每秒百万级调度

    前言 在工业自动化和机器视觉领域,对实时性.可靠性和效率的要求越来越高.为了满足这些需求,我们开发了一款专为工业自动化运动控制和机器视觉流程开发设计的 C# 并发流程控制框架. 该框架不仅适用于各种工 ...

  8. 一文彻底弄清Redis的布隆过滤器

    布隆过滤器(Bloom Filter)是一种空间效率极高的数据结构,用于快速判断一个元素是否在集合中.它能够节省大量内存,但它有一个特点:可能存在误判,即可能会认为某个元素存在于集合中,但实际上不存在 ...

  9. 2024/9/16 CSP-S模拟赛试题

    A 这题是很有意思的一个题,思路就是你考虑kt的位置只可能在四个角,因为这种情况下,他的距离才会最远对吧,所以你就暴力找另一个人fengwu的点的位置,然后计算他们之间的距离然后你求一个\(\max\ ...

  10. Dash 2.18.2版本更新:模式匹配回调性能大提升

    本文示例代码已上传至我的Github仓库:https://github.com/CNFeffery/dash-master Gitee同步仓库地址:https://gitee.com/cnfeffer ...