使用redis 的订阅服务
1.业务使用场景
我们在使用表单动态添加字段,如果新增字段,再保存数据,这个时候就会出错,出错的原因是seata 再本地缓存元数据,修改物理表的时候,这个元数据并没有发生变化,因此需要刷新元数据,因为我们使用的是多服务实例的部署,因此,如果某个表发生变化时,所有的服务实例都需要将元数据进行刷新。
这个我们可以使用 redis 的订阅服务,当某个微服务的元数据发生变化时,我们可以使用redis通知各个微服务实例对数据进行更改。
redis 支持 发布订阅服务。
他有两个端:
- 订阅端
可以有多个订阅端,可以订阅某个频道,当消息发送端发送消息时,订阅端可以接收到消息进行处理 - 消息发送端
可以方某个频道发送消息。
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 的订阅服务的更多相关文章
- RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用
本文版权归博客园和作者本人吴双共同所有,转载请注明本Redis系列分享地址.http://www.cnblogs.com/tdws/tag/NoSql/ Redis Pub/Sub模式 基本介绍 Re ...
- [Redis]发布/订阅
摘要 有这样的一个场景,管理员需要发布一条消息,所有的客户端都要受到通知.然后想到了发布订阅模式.使用redis的发布与订阅实现起来更简单一些,说做就做,这里弄个简单的demo,先模拟下. 核心代码 ...
- 利用redis的订阅和发布来实现实时监控的一个DEMO(Python版本)
redis的list类型有个很好的特性,就是每次添加元素后会返回当前list的长度,利用这个特点,我们可以监控它的长度,比如我们的key是用户注册的IP地址,list中存放的是已经在此IP地址上注册的 ...
- redis发布订阅Java代码实现
Redis除了可以用作缓存数据外,另一个重要用途是它实现了发布订阅(pub/sub)消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 为了实现redis的发布订阅机制,首先要打开re ...
- redis发布/订阅
发布订阅简介 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息,消息之间通过channel传递. 准备工作 两台安装了redis的机器(虚拟 ...
- MariaDB主从复制,redis发布订阅,持久化,以及主从同步
一. MariaDB主从复制 mysql基本操作 1 连接数据库 mysql -u root -p -h 127.0.0.1 mysql -u root -p -h 192.168.12.60 2 ...
- Redis发布订阅机制
1. 什么是Redis Redis是一个开源的内存数据库,它以键值对的形式存储数据.由于数据存储在内存中,因此Redis的速度很快,但是每次重启Redis服务时,其中的数据也会丢失,因此,Redis也 ...
- Linux 安装redis,redis发布订阅,持久化
安装redis 1.安装redis的方式 -yum (删除这个yum安装的redis,我们只用源码编译安装的) -rpm -源码编译 2.删除原本的redis yum remove redis -y ...
- 使用python来搞定redis的订阅功能
好久没写博客了. 最近公司开了新项目,我负责的内容之一是系统的后端.具体项目内容我就不介绍了,但是用到的技术有些还是很有趣的,值得记录一下.今天介绍的就是其中一个:利用redis的pubsub订阅 ...
- Linux(6)- redis发布订阅/持久化/主从复制/redis-sentinel/redis-cluster、nginx入门
一.redis发布订阅 Redis 通过 PUBLISH .SUBSCRIBE 等命令实现了订阅与发布模式. 其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个 ...
随机推荐
- CSS & JS Effect – Virtual Scrolling
前言 我正在写 Angular CDK Scrolling 教程,它里面有一个 Virtual Scrolling 功能.借此机会,我想顺便写一篇纯 Sass & TS 的版本作为学习. Vi ...
- EF Core – ExecuteUpdate and ExecuteDelete (Bulk updates 批量更新和删除)
前言 EF Core 在 SaveChanges 之后会一句一句的去更新和删除数据. 有时候这个效率是很差的. 而 SQL 本来就支持批量更新和删除, 所以是 EF Core 的缺失. 在 EF Co ...
- tailwindcss 3.3.3(完成入门,需要补充每个单独样式)
归纳 修饰符堆叠 <button class="dark:md:hover:bg-fuchsia-600"> 以下为修饰符 伪类伪元素 使用方法: 在实用程序类前添加h ...
- foobar2000 v2.1.5 汉化版(更新日期:2024.09.08)
foobar2000 v2.1.5 汉化版 -----------------------[软件截图]---------------------- -----------------------[软件 ...
- Data Summit 2022 大会资料分享(共23个)
Data Summit (数据峰会)是国际上关于数据管理.分析方面最新战略和技术研讨的顶尖峰会,通过行业领先的企业.专家的分享,共同探讨大数据和数据科学领域的发展现状与最新技术研究. 2022年5月1 ...
- 48 .var声明函数和function声明函数的区别
定义函数的方式: 1. 函数表达式定义函数 function expression 2. 函数式声明 function declaration 区别: var声明的函数,只能在声明之后调用,因为函数表 ...
- git安装使用及连接gitlab集成idea
一.简介 Git是一个开源的分布式版本控制系统,通过git可以对项目进行代码托管,通常配合GitLub.Github使用: 想了解更多请进官网(官网下载较慢):https://www.git-scm. ...
- 想玩Steam游戏,但配置太低?ToDesk云电脑一招搞定!
在游戏爱好者的世界里,汇集了许多游戏大作的Steam平台无疑是一座宝库.但对于许多玩家来说,拥有一颗渴望畅玩游戏的心,却常常被低配置的电脑设备所束缚.尤其是面对硬件要求极高的3A大作时,低配置的电脑往 ...
- dorado动态修改数据验证
view.get("#userDS.dataType").getPropertyDef("unitType").set("required" ...
- 2.11 Linux四种远程管理协议
提到远程管理,通常指的是远程管理服务器,而非个人计算机.个人计算机可以随时拿来用,服务器通常放置在机房中,用户无法直接接触到服务器硬件,只能采用远程管理的方式. 远程管理,实际上就是计算机(服务器)之 ...