SpringCloud Gateway使用redis實(shí)現(xiàn)動(dòng)態(tài)路由的方法
1. 將 actuator 端點(diǎn)暴露出來(lái)
management:
endpoints:
web:
exposure:
include: "*"
2. redis 配置
http://www.dbjr.com.cn/article/203766.htm
3. 將原內(nèi)存路由持久化到 redis
@Component public class RedisRouteDefinitionRepository implements RouteDefinitionRepository { /** * hash存儲(chǔ)的key */ public static final String GATEWAY_ROUTES = "gateway_dynamic_route"; @Resource private StringRedisTemplate redisTemplate; /** * 獲取路由信息 * @return */ @Override public Flux<RouteDefinition> getRouteDefinitions() { List<RouteDefinition> routeDefinitions = new ArrayList<>(); redisTemplate.opsForHash().values(GATEWAY_ROUTES).stream() .forEach(routeDefinition -> routeDefinitions.add(JSON.parseObject(routeDefinition.toString(), RouteDefinition.class))); return Flux.fromIterable(routeDefinitions); } @Override public Mono<Void> save(Mono<RouteDefinition> route) { return route.flatMap(routeDefinition -> { redisTemplate.opsForHash().put(GATEWAY_ROUTES, routeDefinition.getId(), JSONObject.toJSONString(routeDefinition)); return Mono.empty(); }); } @Override public Mono<Void> delete(Mono<String> routeId) { return routeId.flatMap(id -> { if (redisTemplate.opsForHash().hasKey(GATEWAY_ROUTES, id)) { redisTemplate.opsForHash().delete(GATEWAY_ROUTES, id); return Mono.empty(); } return Mono.defer(() -> Mono.error(new NotFoundException("route definition is not found, routeId:" + routeId))); }); } }
4. 重寫動(dòng)態(tài)路由服務(wù)
@Service public class GatewayDynamicRouteService implements ApplicationEventPublisherAware { @Resource private RedisRouteDefinitionRepository redisRouteDefinitionRepository; private ApplicationEventPublisher applicationEventPublisher; /** * 增加路由 * @param routeDefinition * @return */ public int add(RouteDefinition routeDefinition) { redisRouteDefinitionRepository.save(Mono.just(routeDefinition)).subscribe(); applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this)); return 1; } /** * 更新 * @param routeDefinition * @return */ public int update(RouteDefinition routeDefinition) { redisRouteDefinitionRepository.delete(Mono.just(routeDefinition.getId())); redisRouteDefinitionRepository.save(Mono.just(routeDefinition)).subscribe(); applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this)); return 1; } /** * 刪除 * @param id * @return */ public Mono<ResponseEntity<Object>> delete(String id) { return redisRouteDefinitionRepository.delete(Mono.just(id)).then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build()))) .onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build())); } @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } }
5. 對(duì)外暴露接口
@RestController @RequestMapping("/gateway") public class GatewayDynamicRouteController { @Resource private GatewayDynamicRouteService gatewayDynamicRouteService; @PostMapping("/add") public String create(@RequestBody RouteDefinition entity) { int result = gatewayDynamicRouteService.add(entity); return String.valueOf(result); } @PostMapping("/update") public String update(@RequestBody RouteDefinition entity) { int result = gatewayDynamicRouteService.update(entity); return String.valueOf(result); } @DeleteMapping("/delete/{id}") public Mono<ResponseEntity<Object>> delete(@PathVariable String id) { return gatewayDynamicRouteService.delete(id); } }
測(cè)試
測(cè)試前刪除我們配置的靜態(tài)路由,因?yàn)殪o態(tài)路由和 redis 動(dòng)態(tài)路由同時(shí)存在時(shí)取并集。
訪問(wèn) http://localhost:2000/actuator/gateway/routes , 可以看到只有默認(rèn)路由。
[ { "route_id": "CompositeDiscoveryClient_consul", "route_definition": { "id": "CompositeDiscoveryClient_consul", "predicates": [ { "name": "Path", "args": { "pattern": "/consul/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/consul/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://consul", "order": 0 }, "order": 0 }, { "route_id": "CompositeDiscoveryClient_idc-gateway", "route_definition": { "id": "CompositeDiscoveryClient_idc-gateway", "predicates": [ { "name": "Path", "args": { "pattern": "/idc-gateway/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/idc-gateway/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://idc-gateway", "order": 0 }, "order": 0 }, { "route_id": "CompositeDiscoveryClient_idc-provider1", "route_definition": { "id": "CompositeDiscoveryClient_idc-provider1", "predicates": [ { "name": "Path", "args": { "pattern": "/idc-provider1/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/idc-provider1/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://idc-provider1", "order": 0 }, "order": 0 }, { "route_id": "CompositeDiscoveryClient_idc-provider2", "route_definition": { "id": "CompositeDiscoveryClient_idc-provider2", "predicates": [ { "name": "Path", "args": { "pattern": "/idc-provider2/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/idc-provider2/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://idc-provider2", "order": 0 }, "order": 0 } ]
這個(gè)時(shí)候訪問(wèn) http://192.168.124.5:2000/idc-provider1/provider1/1 根據(jù)結(jié)果可以推測(cè)能正確路由到 provider1, 測(cè)試結(jié)果一致。
創(chuàng)建 provider1 路由,將路徑設(shè)置為 /p1/**,測(cè)試是否生效。
POST 請(qǐng)求 http://localhost:2000/gateway/add
{ "id":"provider1", "predicates":[ { "name":"Path", "args":{ "_genkey_0":"/p1/**" } }, { "name":"RemoteAddr", "args":{ "_genkey_0":"192.168.124.5/16" } } ], "filters":[ { "name":"StripPrefix", "args":{ "_genkey_0":"1" } } ], "uri":"lb://idc-provider1", "order":0 }
查看 redis 存儲(chǔ),或者請(qǐng)求 http://localhost:2000/actuator/gateway/routes , 都可以看到配置成功。
到此這篇關(guān)于SpringCloud Gateway使用redis實(shí)現(xiàn)動(dòng)態(tài)路由的文章就介紹到這了,更多相關(guān)SpringCloud Gateway動(dòng)態(tài)路由內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之線上水果超市商城的實(shí)現(xiàn)
這是一個(gè)使用了java+SSM+springboot+redis開發(fā)的網(wǎng)上水果超市商城,是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有水果超市商城該有的所有功能,感興趣的朋友快來(lái)看看吧2022-01-01java實(shí)現(xiàn)滑動(dòng)驗(yàn)證解鎖
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)滑動(dòng)驗(yàn)證解鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07Javaweb使用cors完成跨域ajax數(shù)據(jù)交互
本文由跨域、cors的概念開始,進(jìn)而向大家介紹了Javaweb使用cors完成跨域ajax數(shù)據(jù)交互的相關(guān)內(nèi)容,需要的朋友可以了解下。2017-09-09java語(yǔ)言自行實(shí)現(xiàn)ULID過(guò)程底層原理詳解
這篇文章主要為大家介紹了java語(yǔ)言自行實(shí)現(xiàn)ULID過(guò)程底層原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Java數(shù)據(jù)結(jié)構(gòu)超詳細(xì)分析二叉搜索樹
二叉搜索樹是以一棵二叉樹來(lái)組織的。每個(gè)節(jié)點(diǎn)是一個(gè)對(duì)象,包含的屬性有l(wèi)eft,right,p和key,其中,left指向該節(jié)點(diǎn)的左孩子,right指向該節(jié)點(diǎn)的右孩子,p指向該節(jié)點(diǎn)的父節(jié)點(diǎn),key是它的值2022-03-03