zeus00456

导航

微服务架构 | 服务网关 - [Gateway]

@

§1 官网与简介

Zuul
Gateway
This project provides a library for building an API Gateway on top of Spring WebFlux. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.

特性:

  • Built on Spring Framework 5, Project Reactor and Spring Boot 2.0
  • Able to match routes on any request attribute
  • Predicates and filters are specific to routes
  • Circuit Breaker integration
  • Spring Cloud DiscoveryClient integration
  • Easy to write Predicates and Filters
  • Request Rate Limiting
  • Path Rewriting

对比:

  • 由 Springcloud 团队打造,天然亲和 Springcloud 生态,更新和社区更友好
  • 底层使用 webflux(相比web mvc 非阻塞) 的 reactor-netty 响应式编程组件,zuul 底层是基于 servlet 的阻塞式 I/O,高并发上有优势
  • 整合 Spring5 / project reactor / springboot / websocket 等

网关在微服务架构中的位置
在这里插入图片描述

组成、工作流程和作用
在这里插入图片描述

网关由路由、断言、过滤器构成:

  • 断言:起比较作用,可以比较请求的所有部分,比较后匹配的由路由处理
  • 路由:由 ID 、url、断言、过滤器组成,最终由它决定请求交给哪个服务接口处理
  • 过滤:由 spring gateway filter 实例实现,可以在请求前后进行一些操作,比如请求重写
    在这里插入图片描述

通过上述组件可以实现:

  • 反向代理
  • 鉴权
  • 流量控制
  • 熔断
  • 日志监控
  • 重写

§2 简单使用(路由)

依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

注意,网关的使用需要 排除 下面两个依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

配置
YML 方式

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_routh #payment_route    #路由的唯一id
          uri: http://localhost:8001          #服务的路由地址
          predicates:
            - Path=/payment/get/**         # 服务下接口的地址
		#多个路由如下配置
        - id: payment_routh2 #payment_route
          uri: lb://cloud-payment-service #配置 spring.cloud.gateway.discovery.locator.enabled = true后,可以使用服务名作为服务地址
          predicates:
            - Path=/payment/lb/** 

Configuration 方式

@Configuration
public class GatewayRoutelocatorConfig {
    @Bean
    RouteLocator routeLocator(RouteLocatorBuilder builder){
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("n",
                r->r.path("/").uri("http://www.gamersky.com/"));
        return routes.build();
    }
}

§3 常用断言

由 RoutePredicateFactory 实现

§3.1 path

Path 路由断言工厂接收一个参数,根据 Path 定义好的规则来判断访问的 URI 是否匹配。

spring:
  cloud:
    gateway:
      routes:
        - id: host_route
    uri: http://c.biancheng.net
    predicates:
      - Path=/blog/detail/{segment}

如果请求路径为 /blog/detail/xxx,则此路由将匹配。也可以使用正则,例如 /blog/detail/** 来匹配 /blog/detail/ 开头的多级 URI。
path 断言匹配成功后会将断言部分拼接上 uri 作为实际请求路径
即,若断言为 /a,那实际路径一定是 http://....../a
示例

http://localhost:9527/blog/detail/36185 -->
http://c.biancheng.net/blog/detail/36185

§3.2 query

Query 路由断言工厂接收两个参数

  • 一个必需的参数,用于匹配请求中的 query 字段
  • 一个可选的正则表达式,用于匹配请求中的 query 字段的值
spring:
  cloud:
    gateway:
      routes:
        - id: query_route
      uri: http://c.biancheng.net
      predicates:
        - Query=foo, ba.

示例

http://localhost:2001/?foo=baz

§3.3 method

Method 路由断言工厂接收一个参数,匹配的是 http 的 method

spring:
  cloud:
    gateway:
      routes:
        - id: method_route
  uri: http://baidu.com
  predicates:
    - Method=GET

§3.4 header

Header 路由断言工厂接收两个参数

  • 一个必需的参数,用于匹配请求中的请求头名称
  • 一个可选的正则表达式,用于匹配请求中的请求头的值
spring:
  cloud:
    gateway:
      routes:
        - id: header_route
  uri: http://example.org
  predicates:
    - Header=X-Request-Id, \d+

cookie 路由断言工厂接收两个参数

  • 一个必需的参数,用于匹配请求中的 cookie 名
  • 一个可选的正则表达式,用于匹配请求中的 cookie 的值
spring:
  cloud:
    gateway:
      routes:
        - id: query_route
      uri: http://c.biancheng.net
      predicates:
        - Cookie=chocolate, ch.p

§3.6 时间

时间匹配规定路由路由规则生效的时间范围,有三种模式

  • Before
  • After
  • Between
    时间格式要求为带有时区的时间戳,对应 ZoneDateTime
spring:
  cloud:
    gateway:
      routes:
        - id: query_route
      uri: http://c.biancheng.net
      predicates:
        - Between=2022-01-20T17:42:47.789-07:00[Asia/Shanghai],2023-01-20T17:42:47.789-07:00[Asia/Shanghai]

§4 过滤器

由 GatewayFilterFactroies 实现,原理和 servlet 的 filter 类似。
filter 分为两类

  • gateway filter
  • global filter

§4.1 预设过滤器(TODO)

§4.2 自定义过滤器(TODO)

加入类扫描,实现默认接口

  • GlobalFilter 全局过滤接口
  • Order 用于指定优先级
    注意 Gateway 的 filter 可以实现拦截器的功能
@Component
@Slf4j
public class TestGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("<<<TestGlobalFilter>>> start");
        String name = exchange.getRequest().getQueryParams().getFirst("name");
        if(StringUtils.isEmpty(name)){
            log.info("<<<TestGlobalFilter>>> no-name");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

本文部分内容来自 Spring Cloud Gateway的常用路由断言工厂


传送门:
微服务架构 | 组件目录

posted on 2022-07-28 15:44  问仙长何方蓬莱  阅读(109)  评论(0编辑  收藏  举报