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. CSS – Media Query

    前言 Media Query 是用来做 RWD 的, 类似 JS 的 if else. 写的多有伤管理, 所以要谨慎使用哦. 参考: Learn CSS Media Query In 7 Minute ...

  2. CSS – Dimension min-content, max-content, fit-content

    前言 无意间在 practice 的时候看到视频使用, 以前没有听过. 它有点像 Figma 的 hug content, 据说 CSS 2.1 也是有类似的概念, 只是没有被正式纳入 CSS 里. ...

  3. 自定义指令 v-imgerror 当图片的 src 资源 无效 就替换 默认的 src 显示图片

    // 回顾自定义指令 // 作用 : 自定义一些对dom操作的快捷指令 // 前提:指令就是用来操作 dom (v-if /v-show/v-for ....) // 语法:Vue.directive ...

  4. apisix~kafka-logger插件

    作用 将http请求与响应的内容发到kafka的topic,以json的形式发送存储 配置相关 log_format为自定义配置字段,添加后,默认的请求响应消息将被覆盖 { "_meta&q ...

  5. 云原生周刊:HashiCorp Vault 1.14 发布 | 2023.6.26

    开源项目推荐 Helmfile Helmfile 是一个开源工具,使用 Helm charts 简化复杂应用程序的部署.它提供了一种声明性的方式来定义 Kubernetes 资源的期望状态,并管理 H ...

  6. 防火墙NAT+DHCP+ACL+ACAP

    任务要求: SwitchA作为有线终端网关与DHCP Server,为无线终端与有线终端分配IP地址,并配置ACL访问控制列表控制不同用户的访问权限,客户机只能跟DMZ区域服务器互访,无线访客禁止访问 ...

  7. 经典排序算法(C语言、Java版)

    排序 比较 分类 比较排序的时间复杂度的下界O(nlogn) 对于n个待排序元素,在未比较时,可能的正确结果有n!种.在经过一次比较后,其中两个元素的顺序被确定,所以可能的正确结果剩余n!/2种(确定 ...

  8. ToDesk云电脑性能如何?价格划算吗?

    云电脑是最近兴起的一种新型计算机形态.当用户面临电脑配置太低,无法顺畅打开大型软件,满足不了日常玩游戏或者高性能渲染,这时候你只需要租借一个高配置的云电脑. 不需要额外购入任何设备,在原来的电脑上下载 ...

  9. 手写MSMQ微软消息队列收发工具类

    一.MSMQ介绍 MSMQ(Microsoft Message Queuing)是微软开发的消息队列技术,支持事务,支持异步发送和接收消息. 两个重要的概念:队列和消息.队列是存放消息的容器和传输消息 ...

  10. .NET 9 中没有 wasi 实验性支持

    2023年10月份写个一篇<本计划在 .NET 8 中推出的 WASI 推迟到 .NET 9>[1],根据此问题,在 .NET 9 RTM 中似乎不会有wasi-experimental, ...