Commit 545e9d2a0fefb95199f4363b88326af495dbad89

Authored by YunaiV
1 parent 7813c401

1. 配置的缓存刷新机制

src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java
@@ -28,6 +28,8 @@ public class DBConfigRepository extends AbstractConfigRepository { @@ -28,6 +28,8 @@ public class DBConfigRepository extends AbstractConfigRepository {
28 28
29 private final static ScheduledExecutorService m_executorService; 29 private final static ScheduledExecutorService m_executorService;
30 30
  31 + private static DBConfigRepository INSTANCE;
  32 +
31 static { 33 static {
32 m_executorService = Executors.newScheduledThreadPool(1, 34 m_executorService = Executors.newScheduledThreadPool(1,
33 ApolloThreadFactory.create(DBConfigRepository.class.getSimpleName(), true)); 35 ApolloThreadFactory.create(DBConfigRepository.class.getSimpleName(), true));
@@ -64,6 +66,19 @@ public class DBConfigRepository extends AbstractConfigRepository { @@ -64,6 +66,19 @@ public class DBConfigRepository extends AbstractConfigRepository {
64 this.trySync(); 66 this.trySync();
65 // 初始化定时任务 67 // 初始化定时任务
66 this.schedulePeriodicRefresh(); 68 this.schedulePeriodicRefresh();
  69 +
  70 + // 设置单例
  71 + INSTANCE = this;
  72 + }
  73 +
  74 + /**
  75 + * 通知同步,
  76 + */
  77 + public static void noticeSync() {
  78 + // 提交到线程池中,避免和 schedulePeriodicRefresh 并发问题
  79 + m_executorService.submit(() -> {
  80 + INSTANCE.trySync();
  81 + });
67 } 82 }
68 83
69 @Override 84 @Override
@@ -127,7 +142,6 @@ public class DBConfigRepository extends AbstractConfigRepository { @@ -127,7 +142,6 @@ public class DBConfigRepository extends AbstractConfigRepository {
127 Tracer.logEvent("Apollo.Client.Version", Apollo.VERSION); 142 Tracer.logEvent("Apollo.Client.Version", Apollo.VERSION);
128 }, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(), 143 }, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(),
129 m_configUtil.getRefreshIntervalTimeUnit()); 144 m_configUtil.getRefreshIntervalTimeUnit());
130 -// TimeUnit.SECONDS);  
131 } 145 }
132 146
133 // ========== 数据库相关操作 ========== 147 // ========== 数据库相关操作 ==========
src/main/java/cn/iocoder/dashboard/framework/redis/core/RedisKeyDefine.java
@@ -19,6 +19,8 @@ public class RedisKeyDefine { @@ -19,6 +19,8 @@ public class RedisKeyDefine {
19 HASH, 19 HASH,
20 SET, 20 SET,
21 ZSET, 21 ZSET,
  22 + STREAM,
  23 + PUBSUB
22 24
23 } 25 }
24 26
src/main/java/cn/iocoder/dashboard/modules/infra/mq/consumer/config/InfConfigRefreshConsumer.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.mq.consumer.config;
  2 +
  3 +import cn.iocoder.dashboard.framework.apollo.internals.DBConfigRepository;
  4 +import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener;
  5 +import cn.iocoder.dashboard.modules.infra.mq.message.config.InfConfigRefreshMessage;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.springframework.stereotype.Component;
  8 +
  9 +/**
  10 + * 针对 {@link InfConfigRefreshMessage} 的消费者
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Component
  15 +@Slf4j
  16 +public class InfConfigRefreshConsumer extends AbstractChannelMessageListener<InfConfigRefreshMessage> {
  17 +
  18 + @Override
  19 + public void onMessage(InfConfigRefreshMessage message) {
  20 + log.info("[onMessage][收到 Config 刷新消息]");
  21 + DBConfigRepository.noticeSync();
  22 + }
  23 +
  24 +}
src/main/java/cn/iocoder/dashboard/modules/infra/mq/consumer/package-info.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.mq.consumer;
src/main/java/cn/iocoder/dashboard/modules/infra/mq/message/config/InfConfigRefreshMessage.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.mq.message.config;
  2 +
  3 +import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage;
  4 +import lombok.Data;
  5 +
  6 +/**
  7 + * 配置数据刷新 Message
  8 + */
  9 +@Data
  10 +public class InfConfigRefreshMessage implements ChannelMessage {
  11 +
  12 + @Override
  13 + public String getChannel() {
  14 + return "infra.config.refresh";
  15 + }
  16 +
  17 +}
src/main/java/cn/iocoder/dashboard/modules/infra/mq/message/package-info.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.mq.message;
src/main/java/cn/iocoder/dashboard/modules/infra/mq/producer/config/InfConfigProducer.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.mq.producer.config;
  2 +
  3 +import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils;
  4 +import cn.iocoder.dashboard.modules.infra.mq.message.config.InfConfigRefreshMessage;
  5 +import org.springframework.data.redis.core.StringRedisTemplate;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +import javax.annotation.Resource;
  9 +
  10 +/**
  11 + * Config 配置相关消息的 Producer
  12 + */
  13 +@Component
  14 +public class InfConfigProducer {
  15 +
  16 + @Resource
  17 + private StringRedisTemplate stringRedisTemplate;
  18 +
  19 + /**
  20 + * 发送 {@link InfConfigRefreshMessage} 消息
  21 + */
  22 + public void sendConfigRefreshMessage() {
  23 + InfConfigRefreshMessage message = new InfConfigRefreshMessage();
  24 + RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message);
  25 + }
  26 +
  27 +}
src/main/java/cn/iocoder/dashboard/modules/infra/mq/producer/package-info.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.infra.mq.producer;
src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java
@@ -10,6 +10,7 @@ import cn.iocoder.dashboard.modules.infra.convert.config.InfConfigConvert; @@ -10,6 +10,7 @@ import cn.iocoder.dashboard.modules.infra.convert.config.InfConfigConvert;
10 import cn.iocoder.dashboard.modules.infra.dal.mysql.dao.config.InfConfigMapper; 10 import cn.iocoder.dashboard.modules.infra.dal.mysql.dao.config.InfConfigMapper;
11 import cn.iocoder.dashboard.modules.infra.dal.mysql.dataobject.config.InfConfigDO; 11 import cn.iocoder.dashboard.modules.infra.dal.mysql.dataobject.config.InfConfigDO;
12 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum; 12 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
  13 +import cn.iocoder.dashboard.modules.infra.mq.producer.config.InfConfigProducer;
13 import cn.iocoder.dashboard.modules.infra.service.config.InfConfigService; 14 import cn.iocoder.dashboard.modules.infra.service.config.InfConfigService;
14 import lombok.extern.slf4j.Slf4j; 15 import lombok.extern.slf4j.Slf4j;
15 import org.springframework.stereotype.Service; 16 import org.springframework.stereotype.Service;
@@ -30,6 +31,9 @@ public class InfConfigServiceImpl implements InfConfigService { @@ -30,6 +31,9 @@ public class InfConfigServiceImpl implements InfConfigService {
30 @Resource 31 @Resource
31 private InfConfigMapper configMapper; 32 private InfConfigMapper configMapper;
32 33
  34 + @Resource
  35 + private InfConfigProducer configProducer;
  36 +
33 @Override 37 @Override
34 public PageResult<InfConfigDO> getConfigPage(InfConfigPageReqVO reqVO) { 38 public PageResult<InfConfigDO> getConfigPage(InfConfigPageReqVO reqVO) {
35 return configMapper.selectPage(reqVO); 39 return configMapper.selectPage(reqVO);
@@ -58,6 +62,8 @@ public class InfConfigServiceImpl implements InfConfigService { @@ -58,6 +62,8 @@ public class InfConfigServiceImpl implements InfConfigService {
58 InfConfigDO config = InfConfigConvert.INSTANCE.convert(reqVO); 62 InfConfigDO config = InfConfigConvert.INSTANCE.convert(reqVO);
59 config.setType(InfConfigTypeEnum.CUSTOM.getType()); 63 config.setType(InfConfigTypeEnum.CUSTOM.getType());
60 configMapper.insert(config); 64 configMapper.insert(config);
  65 + // 发送刷新消息
  66 + configProducer.sendConfigRefreshMessage();
61 return config.getId(); 67 return config.getId();
62 } 68 }
63 69
@@ -68,6 +74,8 @@ public class InfConfigServiceImpl implements InfConfigService { @@ -68,6 +74,8 @@ public class InfConfigServiceImpl implements InfConfigService {
68 // 更新参数配置 74 // 更新参数配置
69 InfConfigDO updateObj = InfConfigConvert.INSTANCE.convert(reqVO); 75 InfConfigDO updateObj = InfConfigConvert.INSTANCE.convert(reqVO);
70 configMapper.updateById(updateObj); 76 configMapper.updateById(updateObj);
  77 + // 发送刷新消息
  78 + configProducer.sendConfigRefreshMessage();
71 } 79 }
72 80
73 @Override 81 @Override
@@ -80,6 +88,8 @@ public class InfConfigServiceImpl implements InfConfigService { @@ -80,6 +88,8 @@ public class InfConfigServiceImpl implements InfConfigService {
80 } 88 }
81 // 删除 89 // 删除
82 configMapper.deleteById(id); 90 configMapper.deleteById(id);
  91 + // 发送刷新消息
  92 + configProducer.sendConfigRefreshMessage();
83 } 93 }
84 94
85 private void checkCreateOrUpdate(Long id, String key) { 95 private void checkCreateOrUpdate(Long id, String key) {
@@ -113,4 +123,5 @@ public class InfConfigServiceImpl implements InfConfigService { @@ -113,4 +123,5 @@ public class InfConfigServiceImpl implements InfConfigService {
113 throw ServiceExceptionUtil.exception(CONFIG_NAME_DUPLICATE); 123 throw ServiceExceptionUtil.exception(CONFIG_NAME_DUPLICATE);
114 } 124 }
115 } 125 }
  126 +
116 } 127 }
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dept/SysDeptProducer.java
@@ -19,7 +19,7 @@ public class SysDeptProducer { @@ -19,7 +19,7 @@ public class SysDeptProducer {
19 /** 19 /**
20 * 发送 {@link SysDeptRefreshMessage} 消息 20 * 发送 {@link SysDeptRefreshMessage} 消息
21 */ 21 */
22 - public void sendMenuRefreshMessage() { 22 + public void sendDeptRefreshMessage() {
23 SysDeptRefreshMessage message = new SysDeptRefreshMessage(); 23 SysDeptRefreshMessage message = new SysDeptRefreshMessage();
24 RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message); 24 RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message);
25 } 25 }
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dict/SysDictDataProducer.java
@@ -19,7 +19,7 @@ public class SysDictDataProducer { @@ -19,7 +19,7 @@ public class SysDictDataProducer {
19 /** 19 /**
20 * 发送 {@link SysDictDataRefreshMessage} 消息 20 * 发送 {@link SysDictDataRefreshMessage} 消息
21 */ 21 */
22 - public void sendMenuRefreshMessage() { 22 + public void sendDictDataRefreshMessage() {
23 SysDictDataRefreshMessage message = new SysDictDataRefreshMessage(); 23 SysDictDataRefreshMessage message = new SysDictDataRefreshMessage();
24 RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message); 24 RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message);
25 } 25 }
src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java
@@ -174,8 +174,8 @@ public class SysDeptServiceImpl implements SysDeptService { @@ -174,8 +174,8 @@ public class SysDeptServiceImpl implements SysDeptService {
174 // 插入部门 174 // 插入部门
175 SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO); 175 SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO);
176 deptMapper.insert(dept); 176 deptMapper.insert(dept);
177 - // 发送消息  
178 - deptProducer.sendMenuRefreshMessage(); 177 + // 发送刷新消息
  178 + deptProducer.sendDeptRefreshMessage();
179 return dept.getId(); 179 return dept.getId();
180 } 180 }
181 181
@@ -186,8 +186,8 @@ public class SysDeptServiceImpl implements SysDeptService { @@ -186,8 +186,8 @@ public class SysDeptServiceImpl implements SysDeptService {
186 // 更新部门 186 // 更新部门
187 SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO); 187 SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO);
188 deptMapper.updateById(updateObj); 188 deptMapper.updateById(updateObj);
189 - // 发送消息  
190 - deptProducer.sendMenuRefreshMessage(); 189 + // 发送刷新消息
  190 + deptProducer.sendDeptRefreshMessage();
191 } 191 }
192 192
193 @Override 193 @Override
@@ -200,8 +200,10 @@ public class SysDeptServiceImpl implements SysDeptService { @@ -200,8 +200,10 @@ public class SysDeptServiceImpl implements SysDeptService {
200 } 200 }
201 // 删除部门 201 // 删除部门
202 deptMapper.deleteById(id); 202 deptMapper.deleteById(id);
203 - // 发送消息  
204 - deptProducer.sendMenuRefreshMessage(); 203 + // TODO 需要处理下与角色的数据权限关联,等做数据权限一起处理下
  204 +
  205 + // 发送刷新消息
  206 + deptProducer.sendDeptRefreshMessage();
205 } 207 }
206 208
207 private void checkCreateOrUpdate(Long id, Long parentId, String name) { 209 private void checkCreateOrUpdate(Long id, Long parentId, String name) {
src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
@@ -160,8 +160,8 @@ public class SysDictDataServiceImpl implements SysDictDataService { @@ -160,8 +160,8 @@ public class SysDictDataServiceImpl implements SysDictDataService {
160 // 插入字典类型 160 // 插入字典类型
161 SysDictDataDO dictData = SysDictDataConvert.INSTANCE.convert(reqVO); 161 SysDictDataDO dictData = SysDictDataConvert.INSTANCE.convert(reqVO);
162 dictDataMapper.insert(dictData); 162 dictDataMapper.insert(dictData);
163 - // 发送消息  
164 - dictDataProducer.sendMenuRefreshMessage(); 163 + // 发送刷新消息
  164 + dictDataProducer.sendDictDataRefreshMessage();
165 return dictData.getId(); 165 return dictData.getId();
166 } 166 }
167 167
@@ -172,8 +172,8 @@ public class SysDictDataServiceImpl implements SysDictDataService { @@ -172,8 +172,8 @@ public class SysDictDataServiceImpl implements SysDictDataService {
172 // 更新字典类型 172 // 更新字典类型
173 SysDictDataDO updateObj = SysDictDataConvert.INSTANCE.convert(reqVO); 173 SysDictDataDO updateObj = SysDictDataConvert.INSTANCE.convert(reqVO);
174 dictDataMapper.updateById(updateObj); 174 dictDataMapper.updateById(updateObj);
175 - // 发送消息  
176 - dictDataProducer.sendMenuRefreshMessage(); 175 + // 发送刷新消息
  176 + dictDataProducer.sendDictDataRefreshMessage();
177 } 177 }
178 178
179 @Override 179 @Override
@@ -182,8 +182,8 @@ public class SysDictDataServiceImpl implements SysDictDataService { @@ -182,8 +182,8 @@ public class SysDictDataServiceImpl implements SysDictDataService {
182 this.checkDictDataExists(id); 182 this.checkDictDataExists(id);
183 // 删除字典数据 183 // 删除字典数据
184 dictDataMapper.deleteById(id); 184 dictDataMapper.deleteById(id);
185 - // 发送消息  
186 - dictDataProducer.sendMenuRefreshMessage(); 185 + // 发送刷新消息
  186 + dictDataProducer.sendDictDataRefreshMessage();
187 } 187 }
188 188
189 @Override 189 @Override
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java
@@ -219,7 +219,7 @@ public class SysMenuServiceImpl implements SysMenuService { @@ -219,7 +219,7 @@ public class SysMenuServiceImpl implements SysMenuService {
219 menuMapper.deleteById(menuId); 219 menuMapper.deleteById(menuId);
220 // 删除授予给角色的权限 220 // 删除授予给角色的权限
221 permissionService.processMenuDeleted(menuId); 221 permissionService.processMenuDeleted(menuId);
222 - // 发送刷新消息. 注意,需要事务提交后,在进行发送消息。不然 db 还未提交,结果缓存先刷新了 222 + // 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
223 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { 223 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
224 224
225 @Override 225 @Override