欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringCloudGateway搭建和常见使用方法

程序员文章站 2022-06-14 19:59:49
...

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

温馨提示:在学习新技术之前建议先看看 官方文档

SpringCloudGateway搭建和常见使用方法

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

  • 引入jar包

           <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:
      application:
        name: dyzh-gateway
      cloud:
        nacos:
          discovery:
            enabled: true
            register-enabled: true
            server-addr: 127.0.0.1:8848
    
    
  • 配置路由

    • 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 端口。

  • 开启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

​ 返回结果如下:

{
    "oraaa@qq.com195113de": -1,
    "aaa@qq.come689": 2147483647,
    "aaa@qq.comfeb6b0": 0,
    "org.saaa@qq.com3e900e1a": -2147482648,
    "aaa@qq.com9": 0,
    "aaa@qq.com3ebc955b": -2147483648,
    "aaa@qq.com5aa781f2": 2147483646,
    "oraaa@qq.com25974207": 10100,
    "oaaa@qq.com21a46ff1": 10000,
    "aaa@qq.comb5f4e2": 2147483647
}

返回结果包含已就绪的global filters的详细信息(如 oraaa@qq.com25974207。对于每个global filters,返回结果字符串对应过滤器链中的相应顺序。

2.检索所有的路由【 global filters 】

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

返回结果如下:

{
    "[aaa@qq.com configClass = RequestSizeGatewayFilterFactory.RequestSizeConfig]": null,
    "[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[aaa@qq.com configClass = RedirectToGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = RewritePathGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = RetryGatewayFilterFactory.RetryConfig]": null,
    "[aaa@qq.com configClass = AbstractGatewayFilterFactory.NameConfig]": null,
    "[aaa@qq.com configClass = StripPrefixGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = RequestHeaderSizeGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[aaa@qq.com configClass = AbstractGatewayFilterFactory.NameConfig]": null,
    "[aaa@qq.com configClass = SetStatusGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = ModifyRequestBodyGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[aaa@qq.com configClass = RewriteLocationResponseHeaderGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = DedupeResponseHeaderGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = Object]": null,
    "[aaa@qq.com configClass = AbstractGatewayFilterFactory.NameConfig]": null,
    "[aaa@qq.com configClass = Object]": null,
    "[aaa@qq.com configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
    "[aaa@qq.com configClass = SetPathGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = AbstractGatewayFilterFactory.NameConfig]": null,
    "[aaa@qq.com configClass = RewriteResponseHeaderGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = MapRequestHeaderGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = ModifyResponseBodyGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = PrefixPathGatewayFilterFactory.Config]": null,
    "[aaa@qq.com configClass = Object]": null
}

返回结果包含应用于所有路由的GatewayFilter的详细信息。显示每个工厂提供字符串格式的相应对象(例如, [aaa@qq.com 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

欢迎大家关注我的微信公众号共同学习进步:

SpringCloudGateway搭建和常见使用方法