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 28  
29 29 private final static ScheduledExecutorService m_executorService;
30 30  
  31 + private static DBConfigRepository INSTANCE;
  32 +
31 33 static {
32 34 m_executorService = Executors.newScheduledThreadPool(1,
33 35 ApolloThreadFactory.create(DBConfigRepository.class.getSimpleName(), true));
... ... @@ -64,6 +66,19 @@ public class DBConfigRepository extends AbstractConfigRepository {
64 66 this.trySync();
65 67 // 初始化定时任务
66 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 84 @Override
... ... @@ -127,7 +142,6 @@ public class DBConfigRepository extends AbstractConfigRepository {
127 142 Tracer.logEvent("Apollo.Client.Version", Apollo.VERSION);
128 143 }, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(),
129 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 19 HASH,
20 20 SET,
21 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 10 import cn.iocoder.dashboard.modules.infra.dal.mysql.dao.config.InfConfigMapper;
11 11 import cn.iocoder.dashboard.modules.infra.dal.mysql.dataobject.config.InfConfigDO;
12 12 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
  13 +import cn.iocoder.dashboard.modules.infra.mq.producer.config.InfConfigProducer;
13 14 import cn.iocoder.dashboard.modules.infra.service.config.InfConfigService;
14 15 import lombok.extern.slf4j.Slf4j;
15 16 import org.springframework.stereotype.Service;
... ... @@ -30,6 +31,9 @@ public class InfConfigServiceImpl implements InfConfigService {
30 31 @Resource
31 32 private InfConfigMapper configMapper;
32 33  
  34 + @Resource
  35 + private InfConfigProducer configProducer;
  36 +
33 37 @Override
34 38 public PageResult<InfConfigDO> getConfigPage(InfConfigPageReqVO reqVO) {
35 39 return configMapper.selectPage(reqVO);
... ... @@ -58,6 +62,8 @@ public class InfConfigServiceImpl implements InfConfigService {
58 62 InfConfigDO config = InfConfigConvert.INSTANCE.convert(reqVO);
59 63 config.setType(InfConfigTypeEnum.CUSTOM.getType());
60 64 configMapper.insert(config);
  65 + // 发送刷新消息
  66 + configProducer.sendConfigRefreshMessage();
61 67 return config.getId();
62 68 }
63 69  
... ... @@ -68,6 +74,8 @@ public class InfConfigServiceImpl implements InfConfigService {
68 74 // 更新参数配置
69 75 InfConfigDO updateObj = InfConfigConvert.INSTANCE.convert(reqVO);
70 76 configMapper.updateById(updateObj);
  77 + // 发送刷新消息
  78 + configProducer.sendConfigRefreshMessage();
71 79 }
72 80  
73 81 @Override
... ... @@ -80,6 +88,8 @@ public class InfConfigServiceImpl implements InfConfigService {
80 88 }
81 89 // 删除
82 90 configMapper.deleteById(id);
  91 + // 发送刷新消息
  92 + configProducer.sendConfigRefreshMessage();
83 93 }
84 94  
85 95 private void checkCreateOrUpdate(Long id, String key) {
... ... @@ -113,4 +123,5 @@ public class InfConfigServiceImpl implements InfConfigService {
113 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 19 /**
20 20 * 发送 {@link SysDeptRefreshMessage} 消息
21 21 */
22   - public void sendMenuRefreshMessage() {
  22 + public void sendDeptRefreshMessage() {
23 23 SysDeptRefreshMessage message = new SysDeptRefreshMessage();
24 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 19 /**
20 20 * 发送 {@link SysDictDataRefreshMessage} 消息
21 21 */
22   - public void sendMenuRefreshMessage() {
  22 + public void sendDictDataRefreshMessage() {
23 23 SysDictDataRefreshMessage message = new SysDictDataRefreshMessage();
24 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 174 // 插入部门
175 175 SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO);
176 176 deptMapper.insert(dept);
177   - // 发送消息
178   - deptProducer.sendMenuRefreshMessage();
  177 + // 发送刷新消息
  178 + deptProducer.sendDeptRefreshMessage();
179 179 return dept.getId();
180 180 }
181 181  
... ... @@ -186,8 +186,8 @@ public class SysDeptServiceImpl implements SysDeptService {
186 186 // 更新部门
187 187 SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO);
188 188 deptMapper.updateById(updateObj);
189   - // 发送消息
190   - deptProducer.sendMenuRefreshMessage();
  189 + // 发送刷新消息
  190 + deptProducer.sendDeptRefreshMessage();
191 191 }
192 192  
193 193 @Override
... ... @@ -200,8 +200,10 @@ public class SysDeptServiceImpl implements SysDeptService {
200 200 }
201 201 // 删除部门
202 202 deptMapper.deleteById(id);
203   - // 发送消息
204   - deptProducer.sendMenuRefreshMessage();
  203 + // TODO 需要处理下与角色的数据权限关联,等做数据权限一起处理下
  204 +
  205 + // 发送刷新消息
  206 + deptProducer.sendDeptRefreshMessage();
205 207 }
206 208  
207 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 160 // 插入字典类型
161 161 SysDictDataDO dictData = SysDictDataConvert.INSTANCE.convert(reqVO);
162 162 dictDataMapper.insert(dictData);
163   - // 发送消息
164   - dictDataProducer.sendMenuRefreshMessage();
  163 + // 发送刷新消息
  164 + dictDataProducer.sendDictDataRefreshMessage();
165 165 return dictData.getId();
166 166 }
167 167  
... ... @@ -172,8 +172,8 @@ public class SysDictDataServiceImpl implements SysDictDataService {
172 172 // 更新字典类型
173 173 SysDictDataDO updateObj = SysDictDataConvert.INSTANCE.convert(reqVO);
174 174 dictDataMapper.updateById(updateObj);
175   - // 发送消息
176   - dictDataProducer.sendMenuRefreshMessage();
  175 + // 发送刷新消息
  176 + dictDataProducer.sendDictDataRefreshMessage();
177 177 }
178 178  
179 179 @Override
... ... @@ -182,8 +182,8 @@ public class SysDictDataServiceImpl implements SysDictDataService {
182 182 this.checkDictDataExists(id);
183 183 // 删除字典数据
184 184 dictDataMapper.deleteById(id);
185   - // 发送消息
186   - dictDataProducer.sendMenuRefreshMessage();
  185 + // 发送刷新消息
  186 + dictDataProducer.sendDictDataRefreshMessage();
187 187 }
188 188  
189 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 219 menuMapper.deleteById(menuId);
220 220 // 删除授予给角色的权限
221 221 permissionService.processMenuDeleted(menuId);
222   - // 发送刷新消息. 注意,需要事务提交后,在进行发送消息。不然 db 还未提交,结果缓存先刷新了
  222 + // 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
223 223 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
224 224  
225 225 @Override
... ...