内容简介:功能:希望外部訪問並且將路由資訊儲存至 Redis 下次重啟 or 增加新的 gateway 不用重新配置路由資訊.
功能:
希望外部訪問 http://domain/acc/v1/endpoint 時, 可以轉發到 springcloud 中 ACC-V1 的實例,
並且將路由資訊儲存至 Redis 下次重啟 or 增加新的 gateway 不用重新配置路由資訊.
配置部分
application.yml
spring: application: name: gateway cloud: gateway: discovery: locator: enabled: false redis: host: 127.0.0.1 port: 6379 password: server: port: ${port:9000} eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: prefer-ip-address: true management: endpoints: web: exposure: include: '*'
關閉由服務發現來建立路由
spring.cloud.gateway.discovery.locator.enabled = false
開放 gateway 的 endpoint
management.endpoints.web.exposure.include = "*"
程式部分
準備兩支
Redis 配置
RedisConfig.java
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
需要配置使用 Json 儲存到 Redis, 因為 org.springframework.cloud.gateway.route.RouteDefinition 並沒有 implements Serializable,
所以不轉成 Json 會出錯.
實作 RouteDefinitionRepository
RedisRouteDefinitionRepository.java
@Slf4j @Component public class RedisRouteDefinitionRepository implements RouteDefinitionRepository { public static final String GATEWAY_ROUTES = "geteway_routes"; @Autowired private RedisTemplate redisTemplate; @Override public Flux<RouteDefinition> getRouteDefinitions() { List<RouteDefinition> routeDefinitions = new ArrayList<>(); redisTemplate.opsForHash().values(GATEWAY_ROUTES).stream().forEach(routeDefinition -> { try { routeDefinitions.add((RouteDefinition) routeDefinition); } catch (Exception e) { e.printStackTrace(); } }); return Flux.fromIterable(routeDefinitions); } @Override public Mono<Void> save(Mono<RouteDefinition> route) { return route .flatMap(routeDefinition -> { redisTemplate.opsForHash().put(GATEWAY_ROUTES, routeDefinition.getId(), 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("RouteDefinition not found: " + routeId))); }); } }
gateway 預設是將路由放在記憶體中管理, 但當發現有額外提供 RouteDefinitionRepository 時則會採用你提供的,
這邊實作則是將路由寫到 Redis 做存放.
看一下 Eureka 上有哪些服務
跟 gateway 要路由表資訊看看
curl -X GET http://localhost:9000/actuator/gateway/routes
ResponseBody
[]
可以看到路由表是空的
新增路由
curl -X POST \ http://localhost:9000/actuator/gateway/routes/acc_v1 \ -H 'Content-Type: application/json' \ -d '{ "predicates": [ { "name": "Path", "args": { "pattern": "/ACC/V1/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/ACC/V1/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://ACC-V1", "order": 0 }'
再次做查詢
curl -X GET http://localhost:9000/actuator/gateway/routes
ResponseBody
[ { "route_id": "acc_v1", "route_definition": { "id": "acc_v1", "predicates": [ { "name": "Path", "args": { "pattern": "/ACC/V1/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/ACC/V1/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://ACC-V1", "order": 0 }, "order": 0 } ]
此時可以發現已經有路由表了, 也去 Redis 查一下
接下來去請求 ACC-V1 的資料
curl -X GET http://localhost:9000/ACC/V1/version
ResponseBody
{ "appName": "acc-v1" }
可以正確拿到v1的資料
此時啟動新的服務版本是 v2
這時候去拿 v2 資料是拿不到
curl -X GET http://localhost:9000/ACC/V2/version
ResponseBody
{ "timestamp": "2018-11-07T09:11:10.323+0000", "path": "/ACC/V2/version", "status": 404, "error": "Not Found", "message": null }
增加新服務路由 v2
curl -X POST \ http://localhost:9000/actuator/gateway/routes/acc_v2 \ -H 'Content-Type: application/json' -d '{ "predicates": [ { "name": "Path", "args": { "pattern": "/ACC/V2/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/ACC/V2/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://ACC-V2", "order": 0 }'
這時候去拿 v2 的資料就可以正確取得
curl -X GET http://localhost:9000/ACC/V2/version
ResponseBody
{ "appName": "acc-v2" }
但服務 acc-v1 還是可以訪問到, v1 v2 服務同時提供服務, 並且透過 url 來指定就完成了
curl -X GET http://localhost:9000/ACC/V1/version
ResponseBody
{ "appName": "acc-v1" }
當 v1 要廢棄的時候, 可以先透過 management.endpoints 來刪除
curl -X DELETE \ http://localhost:9000/actuator/gateway/routes/acc_v1
刪除之後確定沒問題就可以真正的把服務關掉囉
curl -X GET \ http://localhost:9000/actuator/gateway/routes
ResponseBody
[ { "route_id": "acc_v2", "route_definition": { "id": "acc_v2", "predicates": [ { "name": "Path", "args": { "pattern": "/ACC/V2/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/ACC/V2/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://ACC-V2", "order": 0 }, "order": 0 } ]
當 gateway 重啟或是增加新的時候, 都會去 Redis 取得路由資訊, 這樣就不用一個一個去配置啦
如果手動增加或刪除 Redis 內的路由資訊, 其實也是可以同步到所有 Gateway 上, 這樣也不一定需要開 management.endpoints gateway.
以上所述就是小编给大家介绍的《客製 Spring Cloud Gateway 路由表 並儲存至 Redis》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- vue路由篇(动态路由、路由嵌套)
- 小程序封装路由文件和路由方法,5种路由方法全解析
- Vue的路由及路由钩子函数
- gin 源码阅读(二)-- 路由和路由组
- vue router 路由鉴权(非动态路由)
- Flutter进阶:路由、路由栈详解及案例分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
生物信息学算法导论
N.C.琼斯 / 第1版 (2007年7月1日) / 2007-7 / 45.0
这是一本关于生物信息学算法和计算思想的导论性教科书,原著由国际上的权威学者撰写,经国内知名专家精心翻译为中文,系统介绍推动生物信息学不断进步的算法原理。全书强调的是算法中思想的运用,而不是对表面上并不相关的各类问题进行简单的堆砌。 体现了以下特色: 阐述生物学中的相关问题,涉及对问题的模型化处理并提供一种或多种解决方案: 简要介绍生物信息学领域领军人物; 饶有趣味的小插图使得概念更加具体和形象,方......一起来看看 《生物信息学算法导论》 这本书的介绍吧!