♻️ Refactoring code. 优化动态路由避免更新数据影响范围过大

This commit is contained in:
lbw committed 2023-10-23 22:19:48 +08:00
1 parent cb4f51facc
commit 90f31d178f
4 files changed
+75 -95

No files matched your search

+1
View File
@@ -511,6 +511,7 @@ INSERT INTO `sys_menu` VALUES (2905, '导入导出', 'sys_i18n_export', NULL, 29
INSERT INTO `sys_menu` VALUES (2906, '文件管理', NULL, '/admin/file/index', 2000, 'ele-Files', '1', 6, '0', NULL, '0', '', '2019-06-25 12:44:46', 'admin', '2023-02-16 15:24:42', '0', 1);
INSERT INTO `sys_menu` VALUES (2907, '删除文件', 'sys_file_del', NULL, 2906, NULL, '1', 1, '0', NULL, '1', ' ', '2019-06-25 13:41:41', ' ', '2020-03-24 08:58:42', '0', 1);
INSERT INTO `sys_menu` VALUES (2908, '路由管理', NULL, '/ext/route', 2000, 'iconfont icon-diqiu1', '1', 12, '0', NULL, '0', '', '2019-06-25 12:44:46', 'admin', '2023-02-16 15:24:42', '0', 1);
INSERT INTO `sys_menu` VALUES (2909, '路由配置', 'sys_route_manage', NULL, 2908, NULL, '1', 1, '0', NULL, '1', ' ', '2019-06-25 13:41:41', ' ', '2020-03-24 08:58:42', '0', 1);
INSERT INTO `sys_menu` VALUES (3000, '公众号平台', NULL, '/mp', -1, 'iconfont icon-zhongyingzhuanhuan', '1', 10, '0', '0', '0', 'admin', '2023-02-24 10:40:44', 'admin', '2023-03-06 10:05:21', '0', 1);
INSERT INTO `sys_menu` VALUES (3001, '账号管理', NULL, '/mp/wx-account/index', 3000, 'iconfont icon-putong', '1', 0, '0', '0', '0', 'admin', '2023-02-24 10:43:03', ' ', NULL, '0', 1);
INSERT INTO `sys_menu` VALUES (3002, '菜单设置', NULL, '/mp/wx-menu/index', 3000, 'iconfont icon--chaifenlie', '1', 1, '0', '0', '0', 'admin', '2023-02-24 11:16:32', 'admin', '2023-03-11 16:28:56', '0', 1);
@@ -17,7 +17,10 @@
package com.pig4cloud.pigx.admin.controller;
import cn.hutool.json.JSONArray;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
import com.pig4cloud.pigx.admin.service.SysRouteConfService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
@@ -47,19 +50,26 @@ public class SysRouteConfController {
* @return
*/
@GetMapping
public R listRoutes() {
return R.ok(sysRouteConfService.list());
public R listRoutes(@RequestParam(required = false) String routeId) {
return R.ok(sysRouteConfService.list(Wrappers.<SysRouteConf>lambdaQuery()
.eq(StrUtil.isNotBlank(routeId), SysRouteConf::getRouteId, routeId)));
}
@DeleteMapping("/{routeId}")
public R deleteRoute(@PathVariable String routeId) {
return R
.ok(sysRouteConfService.remove(Wrappers.<SysRouteConf>lambdaQuery().eq(SysRouteConf::getRouteId, routeId)));
}
/**
* 修改路由
* @param routes 路由定义
* @return
* 新增修改路由
* @param route 路由定义
* @return success
*/
@SysLog("修改路由")
@PutMapping
public R updateRoutes(@RequestBody JSONArray routes) {
return R.ok(sysRouteConfService.updateRoutes(routes));
@SysLog("新增修改路由")
@PostMapping
public R addOrUpdateRoute(@RequestBody JSONObject route) {
return R.ok(sysRouteConfService.addOrUpdateRoute(route));
}
}
@@ -17,7 +17,7 @@
package com.pig4cloud.pigx.admin.service;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
import reactor.core.publisher.Mono;
@@ -32,9 +32,9 @@ public interface SysRouteConfService extends IService<SysRouteConf> {
/**
* 更新路由信息
* @param routes 路由信息
* @param route 路由信息
* @return
*/
Mono<Void> updateRoutes(JSONArray routes);
Mono<Void> addOrUpdateRoute(JSONObject route);
}
@@ -17,15 +17,15 @@
package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
import com.pig4cloud.pigx.admin.mapper.SysRouteConfMapper;
import com.pig4cloud.pigx.admin.service.SysRouteConfService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.gateway.support.DynamicRouteInitEvent;
import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo;
import lombok.AllArgsConstructor;
@@ -33,17 +33,13 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author lengleng
@@ -57,107 +53,80 @@ import java.util.stream.Collectors;
public class SysRouteConfServiceImpl extends ServiceImpl<SysRouteConfMapper, SysRouteConf>
implements SysRouteConfService {
private final RedisTemplate redisTemplate;
private final ApplicationEventPublisher applicationEventPublisher;
/**
* 更新路由信息
* @param routes 路由信息
* @param route 路由信息
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Mono<Void> updateRoutes(JSONArray routes) {
// 清空Redis 缓存
Boolean result = redisTemplate.delete(CacheConstants.ROUTE_KEY);
log.info("清空网关路由 {} ", result);
// 遍历修改的routes,保存到Redis
List<RouteDefinitionVo> routeDefinitionVoList = new ArrayList<>();
public Mono<Void> addOrUpdateRoute(JSONObject route) {
try {
routes.forEach(value -> {
log.info("更新路由 ->{}", value);
RouteDefinitionVo vo = new RouteDefinitionVo();
Map<String, Object> map = (Map) value;
log.info("更新路由 ->{}", route);
RouteDefinitionVo vo = new RouteDefinitionVo();
Object id = map.get("routeId");
if (id != null) {
vo.setId(String.valueOf(id));
}
String id = route.getStr("routeId");
if (StrUtil.isNotBlank(id)) {
vo.setId(id);
}
Object routeName = map.get("routeName");
if (routeName != null) {
vo.setRouteName(String.valueOf(routeName));
}
String routeName = route.getStr("routeName");
if (StrUtil.isNotBlank(routeName)) {
vo.setRouteName(routeName);
}
Object predicates = map.get("predicates");
if (predicates != null) {
JSONArray predicatesArray = (JSONArray) predicates;
List<PredicateDefinition> predicateDefinitionList = predicatesArray
.toList(PredicateDefinition.class);
vo.setPredicates(predicateDefinitionList);
}
JSONArray predicates = route.getJSONArray("predicates");
if (predicates != null) {
List<PredicateDefinition> predicateDefinitionList = predicates.toList(PredicateDefinition.class);
vo.setPredicates(predicateDefinitionList);
}
Object filters = map.get("filters");
if (filters != null) {
JSONArray filtersArray = (JSONArray) filters;
List<FilterDefinition> filterDefinitionList = filtersArray.toList(FilterDefinition.class);
vo.setFilters(filterDefinitionList);
}
JSONArray filters = route.getJSONArray("filters");
if (filters != null) {
List<FilterDefinition> filterDefinitionList = filters.toList(FilterDefinition.class);
vo.setFilters(filterDefinitionList);
}
Object uri = map.get("uri");
if (uri != null) {
vo.setUri(URI.create(String.valueOf(uri)));
}
Object uri = route.getStr("uri");
if (uri != null) {
vo.setUri(URI.create(String.valueOf(uri)));
}
Object order = map.get("order");
if (order != null) {
vo.setOrder(Integer.parseInt(String.valueOf(order)));
}
Integer order = route.getInt("order");
if (order != null) {
vo.setOrder(order);
}
Object metadata = map.get("metadata");
if (metadata != null) {
Map<String, Object> metadataMap = JSONUtil.toBean(String.valueOf(metadata), Map.class);
vo.setMetadata(metadataMap);
}
Map<String, Object> metadataMap = route.getBean("metadata", Map.class);
if (metadataMap != null) {
vo.setMetadata(metadataMap);
}
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(RouteDefinitionVo.class));
redisTemplate.opsForHash().put(CacheConstants.ROUTE_KEY, vo.getId(), vo);
routeDefinitionVoList.add(vo);
});
// 逻辑删除全部
SysRouteConf condition = new SysRouteConf();
condition.setDelFlag(CommonConstants.STATUS_NORMAL);
this.remove(new UpdateWrapper<>(condition));
// 逻辑删除 ,不直接更新避免危险!
this.remove(Wrappers.<SysRouteConf>lambdaQuery().eq(SysRouteConf::getRouteId, id));
// 插入生效路由
List<SysRouteConf> routeConfList = routeDefinitionVoList.stream().map(vo -> {
SysRouteConf routeConf = new SysRouteConf();
routeConf.setRouteId(vo.getId());
routeConf.setRouteName(vo.getRouteName());
routeConf.setFilters(JSONUtil.toJsonStr(vo.getFilters()));
routeConf.setPredicates(JSONUtil.toJsonStr(vo.getPredicates()));
routeConf.setSortOrder(vo.getOrder());
routeConf.setUri(vo.getUri().toString());
routeConf.setMetadata(JSONUtil.toJsonStr(vo.getMetadata()));
return routeConf;
}).collect(Collectors.toList());
this.saveBatch(routeConfList);
SysRouteConf routeConf = new SysRouteConf();
routeConf.setRouteId(vo.getId());
routeConf.setRouteName(vo.getRouteName());
routeConf.setFilters(JSONUtil.toJsonStr(vo.getFilters()));
routeConf.setPredicates(JSONUtil.toJsonStr(vo.getPredicates()));
routeConf.setSortOrder(vo.getOrder());
routeConf.setUri(vo.getUri().toString());
routeConf.setMetadata(JSONUtil.toJsonStr(vo.getMetadata()));
this.save(routeConf);
log.debug("更新网关路由结束 ");
// 通知网关重置路由
redisTemplate.convertAndSend(CacheConstants.ROUTE_JVM_RELOAD_TOPIC, "路由信息,网关缓存更新");
}
catch (Exception e) {
log.error("路由配置解析失败", e);
// 回滚路由,重新加载即可
this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this));
// 抛出异常
throw new RuntimeException(e);
}
finally {
this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this));
}
return Mono.empty();
}