背景 现在很多服务都要求不下线发布,这就要求我们在开发微服务的时候,新增一个接口或者服务中心,必须做到线上发布。新增中心 新增一个服务中心,gateway有几种方法,最常见的就是在配置文件里面新增routes路由。现在我们把这个配置文件改成读取redis。先上redis数据结构。 所有中心 用户中心redis路由结构 用的map结构存储,这里面有几个重要参数,filters:在路由前面加上api,id:名称,predicates:匹配user的路径,uri:发送的服务(appetiteuser对应用户中心),当然我们还可以自定义一些其他的,自己探索吧。有了这些后,我们就能访问到对应的服务,比如我前端访问userab,到了网关就会将这个路径转化成apiuserab,去访问用户中心对应的服务。代码importcom。alibaba。fastjson2。JSON;importjava。util。ArrayList;importjava。util。List;importjavax。annotation。Resource;importlombok。extern。slf4j。Slf4j;importorg。springframework。cloud。gateway。route。RouteDefinition;importorg。springframework。cloud。gateway。route。RouteDefinitionRepository;importorg。springframework。data。redis。core。RedisTemplate;importorg。springframework。stereotype。Component;importreactor。core。publisher。Flux;importreactor。core。publisher。Mono;program:appetiteworkdescription:redis作为网关路由存储author:plcreate:2022080815:35Slf4jComponentpublicclassRedisRouteDefinitionRepositoryimplementsRouteDefinitionRepository{hash存储的keypublicstaticfinalStringGATEWAYROUTESappetitegatewaydynamicroute;ResourceprivateRedisTemplateredisTemplate;获取路由信息returnOverridepublicFluxRouteDefinitiongetRouteDefinitions(){ListRouteDefinitionrouteDefinitionsnewArrayList();redisTemplate。opsForHash()。values(GATEWAYROUTES)。stream()。forEach(routeDefinitionrouteDefinitions。add(JSON。parseObject(routeDefinition。toString(),RouteDefinition。class)));returnFlux。fromIterable(routeDefinitions);}publicListRouteDefinitiongetRoutes(){ListRouteDefinitionrouteDefinitionsnewArrayList();redisTemplate。opsForHash()。values(GATEWAYROUTES)。stream()。forEach(routeDefinitionrouteDefinitions。add(JSON。parseObject(routeDefinition。toString(),RouteDefinition。class)));returnrouteDefinitions;}OverridepublicMonoVoidsave(MonoRouteDefinitionroute){returnroute。flatMap(routeDefinition{redisTemplate。opsForHash()。put(GATEWAYROUTES,routeDefinition。getId(),JSON。toJSONString(routeDefinition));returnMono。empty();});}OverridepublicMonoVoiddelete(MonoStringrouteId){returnrouteId。flatMap(id{redisTemplate。opsForHash()。delete(GATEWAYROUTES,id);returnMono。empty();});}} 这个是在springCloudGateway的代码,既然只要redis有这些数据,那么我就能在其他中心对redis进行操作,从而达到动态加载,我放在了认证中心,如下:importcom。alibaba。fastjson2。JSON;importcom。pl。appetite。constants。CakeConstants;importorg。springframework。data。redis。core。RedisTemplate;importorg。springframework。stereotype。Service;importjava。util。;program:appetite20221020description:网关新增中心到redisauthor:plcreate:2022111920:01ServicepublicclassGatewayRedisService{publicRedisTemplateredisTemplate;publicGatewayRedisService(RedisTemplateredisTemplate){this。redisTemplateredisTemplate;}新增网关中心路由paramcenterCodeappetiteuserpublicvoidaddCenter(StringcenterCode){String〔〕codecenterCode。split();MapfilMapnewLinkedHashMap();ListMapfiltersListMapnewArrayList();MapfiltersMapnewLinkedHashMap();filtersMap。put(name,PrefixPath);MapfiltersArgsMapnewHashMap();filtersArgsMap。put(genkey0,api);filtersMap。put(args,filtersArgsMap);filtersListMap。add(filtersMap);filMap。put(filters,filtersListMap);filMap。put(id,code〔1〕);filMap。put(order,0);ListMappredicateListMapnewArrayList();MappredicateMapnewLinkedHashMap();predicateMap。put(name,Path);MappredicateArgsMapnewHashMap();predicateArgsMap。put(genkey0,code〔1〕);predicateMap。put(args,predicateArgsMap);predicateListMap。add(predicateMap);filMap。put(predicates,predicateListMap);filMap。put(uri,lb:centerCode);redisTemplate。opsForHash()。put(CakeConstants。GATEWAYROUTES,code〔1〕,JSON。toJSONString(filMap));}删除网关中心路由paramiduserpublicvoiddeleteCenter(Stringid){redisTemplate。opsForHash()。delete(CakeConstants。GATEWAYROUTES,id);}获取网关中心redis所有keyreturnpublicSetStringgetCenterKeys(){returnredisTemplate。opsForHash()。keys(CakeConstants。GATEWAYROUTES);} 到这里,网关动态加载中心就可以实现了。当然了这只是动态加载中心,还有动态加载具体的交易,比如我要新上线一个交易abc,我们也可以用这种方式,但是在我这个脚手架里面不是用的这种方式,因为我还要对交易进行一些其他的操作,比如登录验证,安全验证等等,所有我将渠道交易路径作为key,交易信息作为value的形式存到了redis里面,每次交易进来,我都会查询相应的redis数据,获取到交易验证列表,从而去做对应的验证。格式如图: 交易信息 以上就是我这个脚手架里面动态加载交易的操作,其实也不好,每次都要查redis,我是有做本地缓存替代redis的,因为现在一个服务都是好几台服务器部署的集群,所以发布的时候要同步集群数据。这个就自己研究吧。欢迎提供更好的建议。