Spring Cloud Gateway的10个经典问题

Posted BUG指挥官

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud Gateway的10个经典问题相关的知识,希望对你有一定的参考价值。

1、为什么需要网关?

传统的单体架构中只有一个服务开放给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,那么作为客户端如何去调用这些微服务呢?如果没有网关的存在,只能在本地记录每个微服务的调用地址。

无网关的微服务架构往往存在以下问题:

  • 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性。

  • 认证复杂,每个服务都需要独立认证。

  • 存在跨域请求,在一定场景下处理相对复杂。

2、网关的基本功能?

网关是所有微服务的门户,路由转发仅仅是最基本的功能,除此之外还有其他的一些功能,比如:认证、鉴权、熔断、限流、日志监控等等.........

3、为什么选择Spring cloud Gateway?

在1.x版本中都是采用的Zuul网关;但在2.x版本中,zuul的升级一直跳票,Spring Cloud最后自己研发了一个网关替代Zuul,那就是Spring Cloud Gateway。

肯定选择亲儿子Spring Cloud Gateway,它的很多思想都是借鉴zuul,所谓青出于蓝而胜于蓝&

spring cloud gateway 如何工作

spring cloud gateway的包结构(在Idea 2019.3中展示)
技术图片
这个包是spring-cloud-gateway-core.这里是真正的spring-gateway的实现的地方.
为了证明,我们打开spring-cloud-starter-gateway的pom文件

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gateway-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
    </dependencies>

除了cloud-start,starter-webflux就是cloud-gateway-core.所以后面我们就分析
cloud-gateway-core这个jar包.

技术图片

其中actuate中定义了GatewayControllerEndpoint,它提供了对外访问的接口.

    // TODO: Flush out routes without a definition
    @GetMapping("/routes")
    public Flux<Map<String, Object>> routes() {
        return this.routeLocator.getRoutes().map(this::serialize);
    }

    @GetMapping("/routes/{id}")
    public Mono<ResponseEntity<Map<String, Object>>> route(@PathVariable String id) {
        //......
    }
//以下方法是继承于父类,抽象类AbstractGatewayControllerEndpoint
    @PostMapping("/refresh")
    public Mono<Void> refresh() {
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        return Mono.empty();
    }

    @GetMapping("/globalfilters")
    public Mono<HashMap<String, Object>> globalfilters() {
        return getNamesToOrders(this.globalFilters);
    }

    @GetMapping("/routefilters")
    public Mono<HashMap<String, Object>> routefilers() {
        return getNamesToOrders(this.GatewayFilters);
    }

    @GetMapping("/routepredicates")
    public Mono<HashMap<String, Object>> routepredicates() {
        return getNamesToOrders(this.routePredicates);
    }
    @PostMapping("/routes/{id}")
    @SuppressWarnings("unchecked")
    public Mono<ResponseEntity<Object>> save(@PathVariable String id,
            @RequestBody RouteDefinition route) {}
    @DeleteMapping("/routes/{id}")
    public Mono<ResponseEntity<Object>> delete(@PathVariable String id) {
        return this.routeDefinitionWriter.delete(Mono.just(id))
                .then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build())))
                .onErrorResume(t -> t instanceof NotFoundException,
                        t -> Mono.just(ResponseEntity.notFound().build()));
    }

    @GetMapping("/routes/{id}/combinedfilters")
    public Mono<HashMap<String, Object>> combinedfilters(@PathVariable String id) {
        // TODO: missing global filters
    }

config包里定义了一些Autoconfiguration和一些properties.读取配置文件就在这里完成.
技术图片

我们这里看一下GatewayProperties.java

@ConfigurationProperties("spring.cloud.gateway")
@Validated
public class GatewayProperties {

    /**
     * List of Routes.
     */
    @NotNull
    @Valid
    private List<RouteDefinition> routes = new ArrayList<>();

    /**
     * List of filter definitions that are applied to every route.
     */
    private List<FilterDefinition> defaultFilters = new ArrayList<>();

    private List<MediaType> streamingMediaTypes = Arrays
            .asList(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_STREAM_JSON);
    #该类包括三个属性,路由列表,默认过滤器列表和MediaType列表.路由列表中的路由定义RouteDefinition.
        过滤器中定义的FilterDefinition.

discovery定义了注册中心的一些操作.
event定义了一系列事件,都继承自ApplicationEvent.
filter定义了spring gateway实现的一些过滤器,包括gatewayfilter,globalfilter.

以上是关于Spring Cloud Gateway的10个经典问题的主要内容,如果未能解决你的问题,请参考以下文章

设置spring cloud gateway的问题

从spring cloud gateway调用微服务

聊聊spring cloud gateway的NettyConfiguration

尽管设置了承载令牌,但 Spring Cloud Gateway 重定向到 Keycloak 登录页面

使用 Spring Cloud Gateway 实现微服务 API 网关

如何在提交之前修改 Spring Cloud Gateway 中的响应正文