「微服务网关实战五」做网关系统, 99% 会被问到这个功能

又来给大家更文了。

微服务网关实战系列不知不觉已经第五篇了,该讲的基础知识已经讲过了,今天要来点进阶内容了:网关路由动态刷新

我们知道,在 SCG 中,路由的配置有两种方式:代码配置和配置文件配置。

代码配置的是通过一个 bean 写入自定义的路由配置,就像这样:

@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route((r) -> r.path("/user/**").uri("lb://user-api"))
            .route((r) -> r.path("/order/**").uri("lb://order-api"))
            .build();
}
复制代码

配置文件配置则是直接通过配置文件加载的方式读取配置内容,就像这样:

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: https://example.org
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20
            redis-rate-limiter.requestedTokens: 1
复制代码

当然,如果你引入了 spring-boot-starter-actuator 包你还可以拥有通过 OpenApi 方式修改路由的能力:

虽然以上三种方式都可以修改路由,但是在实际的工作中,前两种方式往往都是极不方便的,因为当我们想要修改某个路由的时候需要经过修改代码、重新打包、测试、部署、上线这一系列流程,随随便便可能半天的时间就去了,效率极低。

而第三种方式需要打开可观测点,这在线上环境中大概率不会一直打开,所以可以直接忽略。

所以对于以上这种需求,我们必然要提出一个解决方案进行路由的动态处理,这就是今天的正文内容了,我们开始吧!

1. 怎么修改路由?

我们在开头提到了三种修改路由的方式,前两种都是启动时加载,只有第三种是真正的动态加载,所以我们为了完成路由动态刷新的功能,可以很容易的想到是参考第三种的方式去进行路由动态修改,这个时候就需要我们阅读源码了。

我们先看查看修改路由接口的源码,在 IDEA 中你只需要在接口右键点击编辑就可以直接触达到代码位置:

此接口源码如下:

    @PostMapping("/routes/{id}")
    @SuppressWarnings("unchecked")
    public Mono<ResponseEntity<Object>> save(@PathVariable String id, @RequestBody RouteDefinition route) {
​
        return Mono.just(route).doOnNext(this::validateRouteDefinition)
                .flatMap(routeDefinition -> this.routeDefinitionWriter.save(Mono.just(routeDefinition).map(r -> {
                    r.setId(id);
                    log.debug("Saving route: " + route);
                    return r;
                })).then(Mono.defer(() -> Mono.just(ResponseEntity.created(URI.create("/routes/" + id)).build()))))
                .switchIfEmpty(Mono.defer(() -> Mono.just(ResponseEntity.badRequest().build())));
    }
复制代码

通过这段源码可以看到一个有一个专门的 Bean 去处理路由的修改:routeDefinitionWriter,而我们只需要建造对应的 RouteDefinition 进行插入操作就可以了。

此时通过查看 RouteDefinition 的类定义可以看到它是这样的数据结构:

public class RouteDefinition {
​
    private String id;
​
    @NotEmpty
    @Valid
    private List<PredicateDefinition> predicates = new ArrayList<>();
​
    @Valid
    private List<FilterDefinition> filters = new ArrayList<>();
​
    @NotNull
    private URI uri;
​
    private Map<String, Object> metadata = new HashMap<>();
​
    private int order = 0;
}
复制代码

这个数据结构在网关系列讲解路由的那篇文章中我也提到过,很明显这是一个路由的数据结构,每个路由都有一个唯一的路由标识,可以很简单的联想

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值