Spring Cloud Gateway教程

1 微服务网关概述

Spring Cloud Gateway是在 Spring 生态系统之上构建的API网关服务,旨在为微服务架构应用提供一种简单有效的统一的API路由管理方式。

Spring Cloud Gateway主要功能:

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

2 Spring Cloud Gateway三大核心概念

  • 路由(Route):它由一个 ID、一个目标 URI、断言集合和过滤器集合。如果断言为真,则路由匹配。
  • 断言 (Predicate):参考的是 Java8 的 java.util.function.Predicate,开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果与断言相匹配则进行路由。
  • 过滤器(Filter):指的是 GatewayFilter 实例,可以在请求被路由之前或之后修改请求和响应。

3 Spring Cloud Gateway工作流程

客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。

过滤器被虚线分开的原因是过滤器可以在发送代理请求之前(pre)和之后(post)运行逻辑。执行所有"pre"过滤器逻辑。然后发出代理请求。在发出代理请求之后,运行"post"过滤器逻辑。

总结:断言判断-->路由转发-->执行过滤器链

4 Spring Cloud Gateway网关微服务开发

  1. 新建网关微服务模块
  2. 修改pom文件,引入依赖
  3. 修改yml文件和主启动类,在Consul中进行服务注册

4.1 引入依赖

xml 复制代码
<dependencies>
    <!--Spring Cloud Gateway-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--Consul服务注册-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <!--指标监控健康检查的actuator-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

4.2 网关微服务注册

yml 复制代码
server:
  port: 9527 # 网关服务端口

spring:
  application:
    name: gateway-service # 网关服务名称
  cloud:
    consul:
      host: 47.120.52.144 # Consul服务地址
      port: 8500 # Consul服务端口
      discovery:
        prefer-ip-address: true # 服务注册时优先使用IP地址而不是主机名
        service-name: ${spring.application.name} # 在Consul中注册的服务名称
        heartbeat:
          enabled: true # 启用心跳检测,定期检查服务健康状态
java 复制代码
@SpringBootApplication
@EnableDiscoveryClient // 服务注册
public class Gateway9527 {
    public static void main(String[] args) {
        SpringApplication.run(Gateway9527.class, args);
    }
}

服务注册使用了 Consul,如果要使用 Nacos 进行服务注册,修改 pom 文件中的依赖和 yml 文件中的配置!

4.3 路由配置

假设场景,商城系统用户下单支付。
Consul注册中心8500 订单微服务8001 网关微服务9527 支付微服务8002 用户

网关微服务yml配置:

yml 复制代码
spring:
  gateway:
    routes:
      - id: order-route # 路由ID,没有固定规则但要求唯一,建议配合服务名
        uri: http://localhost:8001 # 路由转发地址
        predicates:
          - Path=/gateway/order/**/** # 断言,匹配请求路径
      - id: pay-route
        uri: http://localhost:8002
        predicates:
          - Path=/gateway/pay/**/**

如果要使用OpenFeign,订单微服务8001调用支付微服务8002,
Consul注册中心8500 OpenFeign 订单微服务8001 网关微服务9527 支付微服务8002 用户

服务调用链:

  1. 用户调用网关微服务9527
  2. 网关微服务9527根据配置的路由匹配到订单微服务8001
  3. 订单微服务8001根据业务需要使用OpenFeign远程调用支付微服务8002
    1. 因为支付微服务8002也需要通过网关访问,因此也要通过网关微服务9527
    2. 网关微服务9527根据配置的路由匹配到支付微服务8002,到此完成服务调用

此时,网关微服务yml配置:

yml 复制代码
spring:
  gateway:
    routes:
      - id: order-route # 路由ID,没有固定规则但要求唯一,建议配合服务名
        uri: lb://order-service # 路由转发地址,负载均衡
        predicates:
          - Path=/order/**/** # 断言,匹配请求路径
      - id: pay-route
        uri: lb://pay-service
        predicates:
          - Path=/pay/**/**
  • @FeignClient(value = "gateway-service")注解不再使用微服务名,而是使用网关服务名称!
  • 动态获取服务URI:根据微服务名称而不是固定IP+port的方式获取URI!

Spring Cloud Gateway支持丰富的路由匹配逻辑,以应对各种类型的业务诉求:

断言 示例 说明
Path - Path=/httpbin/** 路径与/httpbin/**匹配的请求会被转发
Cookie - Cookie=chocolate, ch.p 携带Cookie且内容为chocolate=ch.p的请求会被转发
Header - Header=X-Request-Id, \d+ 请求有一个名为 X-Request-Id 的头,其值与 \d+ 正则表达式匹配(即它的值为一位或多位),则此路由匹配。
Method - Method=GET,POST 请求方法是 GETPOST ,则此路由匹配。
Before - Before=2017-01-20T17:42:47.789+08:00[Asia/Shanghai] 在2017年01月20日17时42分47.789秒之前的请求,才会被转发
After - Before=2017-01-20T17:42:47.789+08:00[Asia/Shanghai] 在2017年01月20日17时42分47.789秒之后的请求,才会被转发
Between - Between=2017-01-20T17:42:47.789+08:00[Asia/Shanghai],2017-01-21T17:42:47.789+08:00[Asia/Shanghai] 在2017年01月20日17时42分47.789秒到在2017年01月21日17时42分47.789秒之间的请求,才会被转发

4.4 过滤器配置

过滤器分类 全局过滤器GlobalFilter 网关过滤器GatewayFilter 自定义过滤器

  • 全局过滤器GlobalFilter:作用在所有路由上,不需要在配置文件中配置,实现GlobalFilter接口即可
  • 网关过滤器GatewayFilter:作用在单一路由或某个路由分组上,通过spring.cloud.gateway.routes.filters配置在具体的路由上,也可以通过配置spring.cloud.gateway.default-filters让它作用于全局路由上。
  • 自定义过滤器

4.4.1 全局过滤器

java 复制代码
/**
 * Contract for interception-style, chained processing of gateway requests that may be
 * used to implement cross-cutting, application-agnostic requirements such as security,
 * timeouts, and others.
 *
 * Only applies to matched gateway routes.
 *
 * Copied from framework WebFilter
 *
 * @author Rossen Stoyanchev
 * @since 5.0
 */
public interface GlobalFilter {

	/**
	 * Process the Web request and (optionally) delegate to the next {@code GatewayFilter}
	 * through the given {@link GatewayFilterChain}.
	 * @param exchange the current server exchange
	 * @param chain provides a way to delegate to the next filter
	 * @return {@code Mono<Void>} to indicate when request processing is complete
	 */
	Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

4.4.2 网关过滤器

官网地址:https://docs.spring.io/spring-cloud-gateway/docs/4.0.9/reference/html/#gatewayfilter-factories。这里只列举一些常见的网关过滤器。

  1. 请求头(RequestHeader)相关

    1. AddRequestHeader
    2. RemoveRequestHeader
    3. SetRequestHeader
    yml 复制代码
    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_header_route
            uri: http://example.org
            filters:
            - AddRequestHeader=X-Request-red, blue
            - RemoveRequestHeader=X-Request-Foo
            - SetRequestHeader=X-Request-Red, Blue
  2. 请求参数(RequestParameter)相关

    1. AddRequestParameter
    2. RemoveRequestParameter
    yml 复制代码
    spring:
      cloud:
        gateway:
          routes:
          - id: add_request_parameter_route
            uri: http://example.org
            filters:
            - AddRequestParameter=red, blue
            - RemoveRequestParameter=red
  3. 响应头(ResponseHeader)相关

    1. AddResponseHeader
    2. RemoveResponseHeader
    3. SetResponseHeader
    yml 复制代码
    spring:
      cloud:
        gateway:
          routes:
          - id: add_response_header_route
            uri: http://example.org
            filters:
            - AddResponseHeader=X-Response-Red, Blue
            - RemoveResponseHeader=X-Response-Foo
            - SetResponseHeader=X-Response-Red, Blue
  4. 前缀和路径相关

    1. PrefixPath

      yml 复制代码
      spring:
        cloud:
          gateway:
            routes:
            - id: prefixpath_route
              uri: http://example.org
              predicates:
              - Path=/red
              filters:
              - PrefixPath=/mypath

      浏览器访问地址:http://example.org/red

      实际微服务地址:http://example.org/mypath/red

    2. SetPath

      yml 复制代码
      spring:
        cloud:
          gateway:
            routes:
            - id: prefixpath_route
              uri: http://example.org
              predicates:
              - Path=/red
              filters:
              - SetPath=/blue

      浏览器访问地址:http://example.org/red

      实际微服务地址:http://example.org/blue

    3. RedirectTo

      yml 复制代码
      spring:
        cloud:
          gateway:
            routes:
            - id: prefixpath_route
              uri: http://example.org
              predicates:
              - Path=/red
              filters:
              - RedirectTo=302, http://www.baidu.com

      浏览器访问地址:http://example.org/red

      实际微服务地址:http://www.baidu.com

  5. 其他

    1. Default:添加过滤器用于所有路由,相当于全局过滤器。

      yml 复制代码
      spring:
        cloud:
          gateway:
            default-filters:
            - AddResponseHeader=X-Response-Default-Red, Default-Blue
            - PrefixPath=/httpbin

如果调用链中再加入远程调用,调用链还是很复杂的!

4.4.3 自定义过滤器

🔔Spring Cloud Gateway自定义过滤器参考另一篇笔记

参考

相关推荐
架构师吕师傅1 小时前
性能优化实战(三):缓存为王-面向缓存的设计
后端·微服务·架构
sdg_advance4 小时前
Spring Cloud之OpenFeign的具体实践
后端·spring cloud·openfeign
潘多编程4 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
王彬泽4 小时前
【微服务】服务注册与发现、分布式配置管理 - Nacos
微服务·服务注册与发现·分布式配置管理
_阿伟_4 小时前
SpringMVC
java·spring
杨荧5 小时前
【JAVA开源】基于Vue和SpringBoot的旅游管理系统
java·vue.js·spring boot·spring cloud·开源·旅游
杨半仙儿还未成仙儿10 小时前
Spring框架:Spring Core、Spring AOP、Spring MVC、Spring Boot、Spring Cloud等组件的基本原理及使用
spring boot·spring·mvc
Java探秘者14 小时前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea
攸攸太上14 小时前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
一直在进步的派大星17 小时前
Docker 从安装到实战
java·运维·docker·微服务·容器