SpringCloud Gateway动态路由配置详解

路由

gateway最主要的作用是,提供统一的入口,路由,鉴权,限流,熔断;这里的路由就是请求的转发,根据设定好的某些条件,比如断言,进行转发。

动态

动态的目的是让程序更加可以在运行的过程中兼容更多的业务场景。

涉及到两个服务,一个是门户服务(作用是提供给运营人员管理入口--包括:管理路由、绑定路由),一个是网关服务(gateway组件,为门户服务提供:查询路由信息、添加路由、删除路由、编辑路由接口)。

路由模型实体类

/**
 * 路由模型
 *
 * @author 苦瓜不苦
 * @date 2022/11/13 23:23
 **/
@Data
public class RouteDefinitionObject {
 /**
 * 路由的Id
 */
 private String id;
 /**
 * 路由断言集合配置
 */
 private List<PredicateDefinition> predicates;
 /**
 * 路由过滤器集合配置
 */
 private List<FilterDefinition> filters;
 /**
 * 路由规则转发的目标uri
 */
 private String uri;
 /**
 * 路由执行的顺序
 */
 private Integer order = 0;
 @Data
 public static class PredicateDefinition {
 /**
 * 断言对应的Name
 */
 private String name;
 /**
 * 配置的断言规则
 */
 private Map<String, String> args;
 }
 @Data
 public static class FilterDefinition {
 /**
 * 断言对应的Name
 */
 private String name;
 /**
 * 配置的断言规则
 */
 private Map<String, String> args;
 }
}

动态路径配置

/**
 * 动态路由配置
 *
 * @author 苦瓜不苦
 * @date 2022/11/13 23:26
 **/
@Slf4j
@RestController
@RequestMapping("/route")
public class GatewayRouteConfig implements ApplicationEventPublisherAware {
 public final Map<String, RouteDefinitionObject> MAP = new ConcurrentHashMap<>();
 private final RouteDefinitionWriter routeDefinitionWriter;
 private ApplicationEventPublisher applicationEventPublisher;
 public GatewayRouteConfig(RouteDefinitionWriter routeDefinitionWriter) {
 this.routeDefinitionWriter = routeDefinitionWriter;
 }
 @Override
 public void setApplicationEventPublisher(@NonNull ApplicationEventPublisher applicationEventPublisher) {
 this.applicationEventPublisher = applicationEventPublisher;
 }
 /**
 * 新增路由
 * {"filters":[{"name":"StripPrefix","args":{"_genkey_0":"2"}}],"id":"item-system","uri":"lb://item-system","order":0,"predicates":[{"name":"Path","args":{"_genkey_0":"/api/system/**"}}]}
 */
 @PostMapping("/save")
 public R<String> save(@RequestBody RouteDefinitionObject routeDefinitionObject) {
 try {
 // 路由模型转换成路由对象
 RouteDefinition definition = BeanUtil.toBean(routeDefinitionObject, RouteDefinition.class);
 URI uri = routeDefinitionObject.getUri().startsWith("http") ? UriComponentsBuilder.fromHttpUrl(routeDefinitionObject.getUri()).build().toUri() : URI.create(routeDefinitionObject.getUri());
 definition.setUri(uri);
 // 新增
 routeDefinitionWriter.save(Mono.just(definition)).subscribe();
 applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
 MAP.put(routeDefinitionObject.getId(), routeDefinitionObject);
 return R.success();
 } catch (Exception e) {
 log.error("\n", e);
 }
 return R.failed();
 }
 /**
 * 删除路由
 */
 @GetMapping("/delete")
 public R<Mono<ResponseEntity<Object>>> delete(@RequestParam("id") String id) {
 try {
 Mono<ResponseEntity<Object>> responseEntityMono = routeDefinitionWriter.delete(Mono.just(id))
 .then(Mono.defer(() ->
 Mono.just(ResponseEntity.ok().build())
 )).onErrorResume((t) ->
 t instanceof NotFoundException
 , (t) ->
 Mono.just(ResponseEntity.notFound().build())
 );
 MAP.remove(id);
 return R.success(responseEntityMono);
 } catch (Exception e) {
 log.error("\n", e);
 }
 return R.failed();
 }
 /**
 * 更新路由
 * {"filters":[{"name":"StripPrefix","args":{"_genkey_0":"2"}}],"id":"item-system","uri":"lb://item-system","order":0,"predicates":[{"name":"Path","args":{"_genkey_0":"/api/system/**"}}]}
 */
 @PostMapping("/update")
 public R<String> update(@RequestBody RouteDefinitionObject routeDefinitionObject) {
 try {
 // 删除
 delete(routeDefinitionObject.getId());
 // 新增
 save(routeDefinitionObject);
 return R.success();
 } catch (Exception e) {
 log.error("\n", e);
 }
 return R.failed();
 }
 /**
 * 查询路由
 */
 @GetMapping("/list")
 public R<Collection<RouteDefinitionObject>> list() {
 return R.success(MAP.values());
 }
}

路由模型JSON数据

{
 "filters":[
 {
 "name":"StripPrefix",
 "args":{
 "_genkey_0":"2"
 }
 }
 ],
 "id":"item-system",
 "uri":"lb://item-system",
 "order":0,
 "predicates":[
 {
 "name":"Path",
 "args":{
 "_genkey_0":"/api/system/**"
 }
 }
 ]
}
作者:苦瓜不苦077

%s 个评论

要回复文章请先登录注册