SpringCloudGateway搭建和常见使用方法

**Spring Cloud Gateway:**提供一种简单而有效的方式来对API进行路由,并为他们提供切面,例如:安全性,监控/指标 和弹性等。html

舒适提示:在学习新技术以前建议先看看 官方文档java

在这里插入图片描述

1.如何在工程中引用Spring Cloud Gateway

  • 引入jar包web

    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
    
            <!-- SpringCloud Ailibaba Nacos -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
    
            <!-- SpringCloud Ailibaba Nacos Config -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            </dependency>
    
            <!-- SpringBoot Actuator -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
  • 配置注册中心地址spring

    spring:
      application:
        name: dyzh-gateway
      cloud:
        nacos:
          discovery:
            enabled: true
            register-enabled: true
            server-addr: 127.0.0.1:8848
  • 配置路由json

    • Route 路由:gateway的基本构建模块。它由ID、目标URI、断言集合和过滤器集合组成。若是聚合断言结果为真,则匹配到该路由。
    • Predicate 断言:这是一个Java 8 Function Predicate。输入类型是 Spring Framework ServerWebExchange。这容许开发人员能够匹配来自HTTP请求的任何内容,例如Header或参数。
    • Filter 过滤器:这些是使用特定工厂构建的 Spring FrameworkGatewayFilter实例。 。Spring cloud gateway中的filter分为两种类型的Filter,分别是Gateway Filter和Global Filter(全局)。过滤器Filter将会对请求和响应进行修改处理 因此能够在返回请求以前或以后修改请求和响应的内容。
    spring:
      cloud:
        gateway:
          discovery:
            locator:
              # 注册中心自动发现 默认为 false
              enabled: false
              #手动配置路由
          routes:
             #路由id,能够自定义设置
            - id: dyzh-demo-service
            #目标URI, URI上的'lb`前缀,使用Spring Cloud Netflix Ribbon 客户端负载均衡。
              uri: lb://dyzh-demo-service
              predicates:
              - Path=/sys/**

2.Actuator API

/gateway的actuator端点容许监视Spring Cloud Gateway应用程序并与之交互。要进行远程访问,必须在应用程序属性中暴露HTTP或JMX 端口。api

  • 开启actuator跨域

    management:
      endpoint:
        gateway:
        # 默认为false
          enabled: true
      endpoints:
        web:
          exposure:
            include: gateway
  • 下表列出了Spring Cloud Gateway执行器端点(请注意,每一个端点都/actuator/gateway做为基本路径):缓存

ID HTTP Method Description
globalfilters GET Displays the list of global filters applied to the routes.
routefilters GET Displays the list of GatewayFilter factories applied to a particular route.
refresh POST Clears the routes cache.
routes GET Displays the list of routes defined in the gateway.
routes/{id} GET Displays information about a particular route.
routes/{id} POST Adds a new route to the gateway.
routes/{id} DELETE Removes an existing route from the gateway.
1.检索全部的路由【 global filters 】

curl -X GET http://localhost:your-port/actuator/gateway/globalfilters安全

​ 返回结果以下:服务器

{
    "org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@195113de": -1,
    "org.springframework.cloud.gateway.filter.NettyRoutingFilter@1f15e689": 2147483647,
    "org.springframework.cloud.gateway.filter.GatewayMetricsFilter@58feb6b0": 0,
    "org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@3e900e1a": -2147482648,
    "org.springframework.cloud.gateway.filter.ForwardPathFilter@6bcae9": 0,
    "org.springframework.cloud.gateway.filter.RemoveCachedBodyFilter@3ebc955b": -2147483648,
    "org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@5aa781f2": 2147483646,
    "org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@25974207": 10100,
    "org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@21a46ff1": 10000,
    "org.springframework.cloud.gateway.filter.ForwardRoutingFilter@11b5f4e2": 2147483647
}

返回结果包含已就绪的global filters的详细信息(如 org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@25974207。对于每一个global filters,返回结果字符串对应过滤器链中的相应顺序。

2.检索全部的路由【 global filters 】

curl -X GET http://localhost:9001/actuator/gateway/routefilters

返回结果以下:

{
    "[RequestSizeGatewayFilterFactory@43ecfeb5 configClass = RequestSizeGatewayFilterFactory.RequestSizeConfig]": null,
    "[SetRequestHeaderGatewayFilterFactory@5a058be5 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[RedirectToGatewayFilterFactory@3becc950 configClass = RedirectToGatewayFilterFactory.Config]": null,
    "[RewritePathGatewayFilterFactory@f557c37 configClass = RewritePathGatewayFilterFactory.Config]": null,
    "[RetryGatewayFilterFactory@1a01d7f0 configClass = RetryGatewayFilterFactory.RetryConfig]": null,
    "[RemoveResponseHeaderGatewayFilterFactory@52ae997b configClass = AbstractGatewayFilterFactory.NameConfig]": null,
    "[StripPrefixGatewayFilterFactory@52ea0269 configClass = StripPrefixGatewayFilterFactory.Config]": null,
    "[RequestHeaderSizeGatewayFilterFactory@51efb731 configClass = RequestHeaderSizeGatewayFilterFactory.Config]": null,
    "[SetResponseHeaderGatewayFilterFactory@4eaf7902 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[RemoveRequestParameterGatewayFilterFactory@79476a4e configClass = AbstractGatewayFilterFactory.NameConfig]": null,
    "[SetStatusGatewayFilterFactory@7061622 configClass = SetStatusGatewayFilterFactory.Config]": null,
    "[ModifyRequestBodyGatewayFilterFactory@60f21960 configClass = ModifyRequestBodyGatewayFilterFactory.Config]": null,
    "[AddResponseHeaderGatewayFilterFactory@9b23822 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[AddRequestParameterGatewayFilterFactory@25c2a9e3 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[RewriteLocationResponseHeaderGatewayFilterFactory@71aaf151 configClass = RewriteLocationResponseHeaderGatewayFilterFactory.Config]": null,
    "[DedupeResponseHeaderGatewayFilterFactory@6a6c7f42 configClass = DedupeResponseHeaderGatewayFilterFactory.Config]": null,
    "[SecureHeadersGatewayFilterFactory@7e15f4d4 configClass = Object]": null,
    "[RemoveRequestHeaderGatewayFilterFactory@6b9fdbc6 configClass = AbstractGatewayFilterFactory.NameConfig]": null,
    "[SaveSessionGatewayFilterFactory@32d418a9 configClass = Object]": null,
    "[AddRequestHeaderGatewayFilterFactory@5e26f1ed configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[SetPathGatewayFilterFactory@5856dbe4 configClass = SetPathGatewayFilterFactory.Config]": null,
    "[RequestHeaderToRequestUriGatewayFilterFactory@746c411c configClass = AbstractGatewayFilterFactory.NameConfig]": null,
    "[RewriteResponseHeaderGatewayFilterFactory@20c812c8 configClass = RewriteResponseHeaderGatewayFilterFactory.Config]": null,
    "[MapRequestHeaderGatewayFilterFactory@39666e42 configClass = MapRequestHeaderGatewayFilterFactory.Config]": null,
    "[ModifyResponseBodyGatewayFilterFactory@5a515e5d configClass = ModifyResponseBodyGatewayFilterFactory.Config]": null,
    "[PrefixPathGatewayFilterFactory@423a0e1d configClass = PrefixPathGatewayFilterFactory.Config]": null,
    "[PreserveHostHeaderGatewayFilterFactory@32f32623 configClass = Object]": null
}

返回结果包含应用于全部路由的GatewayFilter的详细信息。显示每一个工厂提供字符串格式的相应对象(例如, [PreserveHostHeaderGatewayFilterFactory@32f32623 configClass = Object])。请注意,null值是因为endpoint controller实现不完整形成的,由于它尝试在filter chain中设置对象的顺序,这不适用于GatewayFilter工厂对象。

3.清除路由的缓存

curl -X POST http://localhost:9001/actuator/gateway/refresh

没有返回值,只有200的状态码

4.检测网关中定义的路由

curl -X GET http://localhost:9001/actuator/gateway/routes

返回结果以下

[
    {
        "predicate": "Paths: [/sys/**], match trailing slash: true",
        "route_id": "dyzh-demo-service",
        "filters": [],
        "uri": "lb://dyzh-demo-service",
        "order": 0
    }
]

结果中包含网关中全部定义的路由信息

Path Type Description
id String The route ID.
predicates Array The collection of route predicates. Each item defines the name and the arguments of a given predicate.
filters Array The collection of filters applied to the route.
uri String The destination URI of the route.
order Number The route order.
5.获取单个路由信息

curl -X GET http://localhost:9001/actuator/gateway/routes/{id}

返回结果以下:

{
    "predicate": "Paths: [/sys/**], match trailing slash: true",
    "route_id": "dyzh-demo-service",
    "filters": [],
    "uri": "lb://dyzh-demo-service",
    "order": 0
}
6. 建立一个路由

curl -X POST
http://localhost:9001/actuator/gateway/routes/test
-H ‘Content-Type: application/json’
-d ‘{
“id”:“dyzh-back-server”,
“uri”:“lb//dyzh-back-server”
}’

请求成功返回201的状态码

7.删除一个路由

curl -X DELETE http://localhost:9001/actuator/gateway/routes/dyzh-demo-service

3.跨域拦截

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "https://domain"
            allowedMethods:
            - GET
            allowHeaders:
            - Content-Type

4.过滤器 GateWayFilter

Spring Cloud Gateway的filte只有两个:“pre”和“post”:

  • pre:这种过滤器在请求被路由以前调用。能够利用这个过滤器实现身份验证、在集群中选择请求的微服务、记录调试的信息。

  • post:这种过滤器在路由到服务器以后执行。这种过滤器可用来为响应添加HTTP Header、统计信息和指标、响应从微服务发送给客户端等。

Spring Cloud gateway的filter分为两种:GatewayFilter和Globalfilter。GlobalFilter会应用到全部的路由上,而Gatewayfilter将应用到单个路由或者一个分组的路由上。

若是要自定义一个GatewayFilter,须要实现GatewayFilterFactory。下面是一个你须要集成的抽象类 AbstractGatewayFilterFactory

PreGatewayFilterFactory.java.

public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

    public PreGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            //If you want to build a "pre" filter you need to manipulate the
            //request before calling chain.filter
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            //use builder to manipulate the request
            return chain.filter(exchange.mutate().request(request).build());
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

PostGatewayFilterFactory.java.

public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

    public PostGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                //Manipulate the response in some way
            }));
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

5.全局过滤器 GlobalFilter

Spring Cloud Gateway根据做用范围分为GatewayFilter和GlobalFilter,两者区别以下:

GatewayFilter : 须要经过spring.cloud.routes.filters 配置在具体路由下,只做用在当前路由上或经过spring.cloud.default-filters配置在全局,做用在全部路由上。

当请求与路由匹配时,过滤Web处理程序会将的全部实例GlobalFilter和全部特定GatewayFilter于路由的实例添加到过滤器链中。该组合的过滤器链按org.springframework.core.Ordered接口排序,您能够经过实现该getOrder()方法进行设置。

ExampleConfiguration.java

@Bean
public GlobalFilter customFilter() {
    return new CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("custom global filter");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

6.http超时配置

connect-timeout必须以毫秒为单位指定。 response-timeout必须指定为java.time.Duration

  • 全局http超时示例
spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s
  • 要配置每一个路由超时:
    connect-timeout必须以毫秒为单位指定。
    response-timeout必须以毫秒为单位指定
- id: per_route_timeouts
        uri: https://example.org
        predicates:
          - name: Path
            args:
              pattern: /delay/{timeout}
        metadata:
          response-timeout: 200
          connect-timeout: 200

欢迎你们关注个人微信公众号共同窗习进步:

在这里插入图片描述