Spring Cloud GateWay学习之微服务网关Zuul、Gateway、nginx的区别和Spring Cloud GateWay的使用。

3,659 阅读4分钟

Spring Cloud GateWay 是什么

网关,Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

GateWay整体流程

image

Spring Cloud GateWay 作用

  • 协议转换,路由转发
  • 流量聚合,对流量进行监控,日志输出
  • 作为整个系统的前端工程,对流量进行控制,有限流的作用
  • 作为系统的前端边界,外部流量只能通过网关才能访问系统
  • 可以在网关层做权限判断
  • 可以在网关层做缓存

微服务网关Zuul、Gateway、nginx的区别

zuul:

  • 是Netflix的,早期在微服务中使用较广泛,是基于servlet实现的,阻塞式的api,不支持长连接。
  • 只能同步,不支持异步
  • 不依赖spring-webflux,可以扩展至其他微服务框架。
  • 内部没有实现限流、负载均衡,其负载均衡的实现是采用 Ribbon + Eureka 来实现本地负载均衡。
  • 代码简单,注释多,易理解。

Gateway:

  • 是springcloud自己研制的微服务网关,是基于Spring5构建,,能够实现响应式非阻塞式的Api,支持长连接。
  • 支持异步
  • 功能更强大,内部实现了限流、负载均衡等,扩展性也更强。Spring Cloud Gateway明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。
  • 依赖于spring-webflux,仅适合于Spring Cloud套件。
  • 代码复杂,注释少。

nginx:

  • C语言编写,采用服务器实现负载均衡,高性能的HTTP和反向代理web服务器。

Nginx适合于服务器端负载均衡,Zuul和gateway 是本地负载均衡,适合微服务中实现网关。Spring Cloud Gateway 天然适合Spring Cloud 生态。

Spring Cloud GateWay 的使用

Spring Cloud GateWay概念

Route(路由): 路由网关的基本构建块。 它由ID,目标URI,谓词集合和过滤器集合定义。 如果聚合谓词为真,则匹配路由。

Predicate(断言): 这是一个Java 8函数谓词。 输入类型是Spring Framework ServerWebExchange。 这允许开发人员匹配HTTP请求中的任何内容,例如标头或参数。

Filter(过滤器): 这些是使用特定工厂构建的Spring Framework GatewayFilter实例。 这里,可以在发送下游请求之前或之后修改请求和响应。

1. 引入依赖:
导入依赖
 <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
2. application.yml配置predicates配置文件

在这里插入图片描述 predicates的几种方式,官网只说了11种,但后面两种代码中有。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue
  • 这里是指根据Cookie进行转发,只要访问的Cookie是mycookie为mycookievalue,就会转发到example.org。
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]
  • 匹配请求时间在2017-01-20T17:42:47.789-07:00[America/Denver]的请求。
spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
  • 匹配请求时间在2017-01-20T17:42:47.789-07:00[America/Denver]的请求
spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
  • 匹配时间在2017-01-20T17:42:47.789-07:00[America/Denver]和2017-01-21T17:42:47.789-07:00[America/Denver]之间的请求
spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+
  • 匹配请求头参数X-Request-Id 的值符合正则表达式 \d+ 的请求。
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org
  • 匹配以.somehost.org和.anotherhost.org为后缀的域名,如www.somehost.org,beta.somehost.org。
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

  • 匹配请求方式为GET或POST的请求
spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}
  • 匹配路径满足这个正则表达式的路径
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=green
  • 根据请求查询参数进行匹配,如果查询参数中有green 则命中。
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=red, gree.
  • 根据请求查询参数进行匹配,如果请求参数有red参数,并且参数值为 gree开头(gree. 为正则表达式),则命中。如 green,greet
spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

  • 根据请求来源的ip地址进行匹配。
spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2
3. 或者使用配置类进行路由代理
@Configuration
public class GatewayConfig {

    /*
    * 第二种代理的方法
    * 只需要访问 http://localhost:9527/guonei  就能访问到uri中的网址
    * */
    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder){
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path var",
                r ->r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();

        return routes.build();
    }
}
4. 使用filters对所有下游请求参数进行修改
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=red, blue

将添加red=blue到所有匹配请求的下游请求的查询字符串中。

官方文档地址