一、Gateway 简介

Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和 Project Reactor等技术。Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能, 例如:熔断、限流、重试等。
Spring Cloud Gateway 具有如下特性:

  • 基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建;
  • 动态路由:能够匹配任何请求属性;
  • 可以对路由指定 Predicate(断言)和 Filter(过滤器);
  • 集成Hystrix的断路器功能;
  • 集成 Spring Cloud 服务发现功能;
  • 易于编写的 Predicate(断言)和 Filter(过滤器);
  • 请求限流功能;
  • 支持路径重写。

二、相关概念

  • Route(路由):路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由;
  • Predicate(断言):指的是Java 8 的 Function Predicate。
    输入类型是Spring框架中的ServerWebExchange。
    这使开发人员可以匹配HTTP请求中的所有内容,例如请求头或请求参数。如果请求与断言相匹配,则进行路由;
  • Filter(过滤器):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前后对请求进行修改。

三、创建gateway模块

这里我们创建一个api-gateway模块来演示Gateway的常用功能。

在pom.xml中添加相关依赖

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

Gateway 提供了两种不同的方式用于配置路由,

  • 一种是通过yml文件来配置,
  • 另一种是通过Java Bean来配置
  • 使用yml配置

在application.yml中进行配置:

server:port: 2007
spring:cloud:gateway:discovery:locator:enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由routes:- id: user-service   #路由的ID,没有固定规则但要求唯一,建议配合服务名# uri: http://localhost:8008     #匹配后提供服务的路由地址uri:  lb://user-service #匹配后提供服务的路由地址,进行负载均衡predicates:- Path=/user/**         # 断言,路径相匹配的进行路由- id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名#uri: http://localhost:8001          #匹配后提供服务的路由地址uri: lb://payment-service #匹配后提供服务的路由地址predicates:- Path=/payment/lb/**         # 断言,路径相匹配的进行路由#- After=2021-05-21T15:51:37.485+08:00[Asia/Shanghai]#- Cookie=username,xxxx#- Header=X-Request-Id, \d+  # 请求头要有X-Request-Id属性并且值为整数的正则表达式
  • java Bean配置方式
    添加相关配置类,并配置一个RouteLocator对象
/*** @author Cristianoxm*/
@Configuration
public class GateWayConfig {@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();return routes.route("user-service1", r -> r.path("/user/getByUsername").uri("http://localhost:8088/user/getByUsername")).build();}
}

四、启动nacos,user-service和gateway服务


nacos控制面板:

并调用该地址测试:http://localhost:2007/user/1

因为我采用了负载均衡策略,所以可以看到,8086的微服务,和8088的微服务被轮询访问


访问:http://localhost:2007/user/getByUsername?username=andy

五、Route Predicate 的使用

Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。 Spring Cloud Gateway包括许多内置的Route Predicate工厂。 所有这些Predicate都与HTTP请求的不同属性匹配。 多个Route Predicate工厂可以进行组合,下面我们来介绍下一些常用的Route Predicate。
注意:Predicate中提到的配置都在application-predicate.yml文件中进行修改,并用该配置启动api-gateway服务。

  1. After Route Predicate:在指定时间之后的请求会匹配该路由。
spring:cloud:gateway:routes:- id: after_routeuri: ${service-url.user-service}predicates:- After=2019-09-24T16:30:00+08:00[Asia/Shanghai]
  1. Before Route Predicate:在指定时间之前的请求会匹配该路由。
spring:cloud:gateway:routes:- id: before_routeuri: ${service-url.user-service}predicates:- Before=2019-09-24T16:30:00+08:00[Asia/Shanghai]
  1. Between Route Predicate:在指定时间区间内的请求会匹配该路由。
spring:cloud:gateway:routes:- id: before_routeuri: ${service-url.user-service}predicates:- Between=2019-09-24T16:30:00+08:00[Asia/Shanghai], 2019-09-25T16:30:00+08:00[Asia/Shanghai]
  1. Cookie Route Predicate:带有指定Cookie的请求会匹配该路由。
spring:cloud:gateway:routes:- id: cookie_routeuri: ${service-url.user-service}predicates:- Cookie=username,macro

使用curl工具发送带有cookie为username=macro的请求可以匹配该路由。

curl http://localhost:9201/user/1 --cookie "username=macro"
  1. Header Route Predicate:带有指定请求头的请求会匹配该路由。
spring:cloud:gateway:routes:- id: header_routeuri: ${service-url.user-service}predicates:- Header=X-Request-Id, \d+

使用curl工具发送带有请求头为X-Request-Id:123的请求可以匹配该路由。

curl http://localhost:9201/user/1 -H "X-Request-Id:123"
  1. Host Route Predicate
    带有指定Host的请求会匹配该路由。
spring:cloud:gateway:routes:- id: host_routeuri: ${service-url.user-service}predicates:- Host=**.xxxxxx.com

使用curl工具发送带有请求头为Host:www.xxxxx.com的请求可以匹配该路由。

curl http://localhost:9201/user/1 -H "Host:www.xxxxx.com"
  1. Method Route Predicate:发送指定方法的请求会匹配该路由。
spring:cloud:gateway:routes:- id: method_routeuri: ${service-url.user-service}predicates:- Method=GET

使用curl工具发送GET请求可以匹配该路由。

curl http://localhost:9201/user/1

使用curl工具发送POST请求无法匹配该路由。

curl -X POST http://localhost:9201/user/1
  1. Path Route Predicate:发送指定路径的请求会匹配该路由。
spring:cloud:gateway:routes:- id: path_routeuri: ${service-url.user-service}/user/{id}predicates:- Path=/user/{id}

使用curl工具发送/user/1路径请求可以匹配该路由。

curl http://localhost:9201/user/1

使用curl工具发送/abc/1路径请求无法匹配该路由。

curl http://localhost:9201/abc/1
  1. Query Route Predicate:带指定查询参数的请求可以匹配该路由
spring:cloud:gateway:routes:- id: query_routeuri: ${service-url.user-service}/user/getByUsernamepredicates:- Query=username

使用curl工具发送带username=macro查询参数的请求可以匹配该路由。

curl http://localhost:9201/user/getByUsername?username=macro

使用curl工具发送带不带查询参数的请求无法匹配该路由。

curl http://localhost:9201/user/getByUsername
  1. RemoteAddr Route Predicate:从指定远程地址发起的请求可以匹配该路由。
spring:cloud:gateway:routes:- id: remoteaddr_routeuri: ${service-url.user-service}predicates:- RemoteAddr=192.168.1.1/24

使用curl工具从192.168.1.1发起请求可以匹配该路由。

curl http://localhost:9201/user/1
  1. Weight Route Predicate:使用权重来路由相应请求。
    以下表示有80%的请求会被路由到localhost:8201,20%会被路由到localhost:8202。
spring:cloud:gateway:routes:- id: weight_highuri: http://localhost:8201predicates:- Weight=group1, 8- id: weight_lowuri: http://localhost:8202predicates:- Weight=group1, 2

六、Route Filter 的使用

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生,下面我们介绍下常用路由过滤器的用法。

  1. AddRequestParameter GatewayFilter:给请求添加参数的过滤器。
spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: http://localhost:8201filters:- AddRequestParameter=username, macropredicates:- Method=GET

以上配置会对GET请求添加username=macro的请求参数,通过curl工具使用以下命令进行测试。

curl http://localhost:9201/user/getByUsername

相当于发起该请求:

curl http://localhost:8201/user/getByUsername?username=macro
  1. StripPrefix GatewayFilter:对指定数量的路径前缀进行去除的过滤器。
spring:cloud:gateway:routes:- id: strip_prefix_routeuri: http://localhost:8201predicates:- Path=/user-service/**filters:- StripPrefix=2

以上配置会把以/user-service/开头的请求的路径去除两位,通过curl工具使用以下命令进行测试。

curl http://localhost:9201/user-service/a/user/1

相当于发起该请求:

curl http://localhost:8201/user/1
  1. PrefixPath GatewayFilter:与StripPrefix过滤器恰好相反,会对原有路径进行增加操作的过滤器。
spring:cloud:gateway:routes:- id: prefix_path_routeuri: http://localhost:8201predicates:- Method=GETfilters:- PrefixPath=/user

以上配置会对所有GET请求添加/user路径前缀,通过curl工具使用以下命令进行测试。

curl http://localhost:9201/1

相当于发起该请求:

curl http://localhost:8201/user/1
  1. Hystrix GatewayFilter:Hystrix 过滤器允许你将断路器功能添加到网关路由中,使你的服务免受级联故障的影响,并提供服务降级处理。配合Hystrix实现流控

要开启断路器功能,我们需要在pom.xml中添加Hystrix的相关依赖:

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

然后添加相关服务降级的处理类:

@RestController
public class FallbackController {@GetMapping("/fallback")public Object fallback() {Map<String,Object> result = new HashMap<>();result.put("data",null);result.put("message","Get request fallback!");result.put("code",500);return result;}
}

在application-filter.yml中添加相关配置,当路由出错时会转发到服务降级处理的控制器上:

spring:cloud:gateway:routes:- id: hystrix_routeuri: http://localhost:8201predicates:- Method=GETfilters:- name: Hystrixargs:name: fallbackcmdfallbackUri: forward:/fallback

关闭user-service,调用该地址进行测试:http://localhost:9201/user/1 ,发现已经返回了服务降级的处理信息。

  1. RequestRateLimiter GatewayFilter:RequestRateLimiter 过滤器可以用于限流,使用RateLimiter实现来确定是否允许当前请求继续进行,如果请求太大默认会返回HTTP 429-太多请求状态。

在pom.xml中添加相关依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

添加限流策略的配置类,这里有两种策略一种是根据请求参数中的username进行限流,另一种是根据访问IP进行限流;

@Configuration
public class RedisRateLimiterConfig {@BeanKeyResolver userKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("username"));}@Beanpublic KeyResolver ipKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());}
}

我们使用Redis来进行限流,所以需要添加Redis和RequestRateLimiter的配置,这里对所有的GET请求都进行了按IP来限流的操作;

server:port: 9201
spring:redis:host: localhostpassword: 123456port: 6379cloud:gateway:routes:- id: requestratelimiter_routeuri: http://localhost:8201filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 1 #每秒允许处理的请求数量redis-rate-limiter.burstCapacity: 2 #每秒最大处理的请求数量key-resolver: "#{@ipKeyResolver}" #限流策略,对应策略的Beanpredicates:- Method=GET
logging:level:org.springframework.cloud.gateway: debug

多次请求该地址:http://localhost:9201/user/1 ,会返回状态码为429的错误;

  1. Retry GatewayFilter:对路由请求进行重试的过滤器,可以根据路由请求返回的HTTP状态码来确定是否进行重试。

修改配置文件:

spring:cloud:gateway:routes:- id: retry_routeuri: http://localhost:8201predicates:- Method=GETfilters:- name: Retryargs:retries: 1 #需要进行重试的次数statuses: BAD_GATEWAY #返回哪个状态码需要进行重试,返回状态码为5XX进行重试backoff:firstBackoff: 10msmaxBackoff: 50msfactor: 2basedOnPreviousValue: false

文章转自

更多关于gateway的配置

Spring Cloud GatewayAPI网关服务相关推荐

  1. spring cloud的网关服务Zuul

    微服务架构讲究系统的高内聚性,即只做该系统该做的事情,而其他的事情可以通过网关去做.spring cloud的zuul可以快速的搭建一个网关系统,其主要功能如下: 当加入了spring cloud的z ...

  2. Spring Cloud——API网关服务:Spring Cloud Zuul

    API网关像是整个微服务框架系统的门面一样,所有的客户端访问都需要经过它来进行调度和过滤.它实现了请求路由.负载均衡.校验过滤等功能.zuul包含了hystrix.ribbon.acturator等重 ...

  3. SpringCloud 2020版本教程2:使用spring cloud gateway作为服务网关

    点击关注公众号,Java干货及时送达 Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关.网关作为流量的,在微服务系统中有着非常作用,网关常见 ...

  4. Spring Cloud构建微服务架构(五)服务网关

    通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了.比如下图所示: alt 我们使用Spring Cloud Netflix中的Eureka实 ...

  5. Spring Cloud构建微服务架构:服务网关(路由配置)【Dalston版】

    在上一篇<Spring Cloud构建微服务架构:服务网关(基础)>一文中,我们通过使用Spring Cloud Zuul构建了一个基础的API网关服务,同时也演示了Spring Clou ...

  6. spring cloud gateway 网关_微服务网关Spring Cloud Gateway全搞定

    一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...

  7. 《深入理解 Spring Cloud 与微服务构建》第十一章 服务网关

    <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 文章目录 <深入理解 Spring Cloud 与微服务构建>第十一章 服务网关 一.服务网关简介 二. ...

  8. 《深入理解 Spring Cloud 与微服务构建》第十章 路由网关 Spring Cloud Zuul

    <深入理解 Spring Cloud 与微服务构建>第十章 路由网关 Spring Cloud Zuul 文章目录 <深入理解 Spring Cloud 与微服务构建>第十章 ...

  9. Spring Cloud入门-Gateway服务网关(Hoxton版本)

    文章目录 Spring Cloud入门系列汇总 摘要 Gateway 简介 相关概念 创建 api-gateway模块 在pom.xml中添加相关依赖 两种不同的配置路由方式 使用yml配置 使用Ja ...

最新文章

  1. 返朴归真,也谈面向对象编程的几个原则
  2. kubernetes一次生产故障日记
  3. Mac电脑 + Windows机械键盘?功能键映射了解一下
  4. java 输出视频文件格式_java – 如何从各种视频文件格式中提取元数据?
  5. php 获得焦点,jquery中blur()失去焦点与focus() 获取焦点事件
  6. python 进程池阻塞和非阻塞_Python协程还不理解?请收下这份超详细的异步编程教程!还没学会来找我!...
  7. MSP430学习总结——定时器
  8. 艾美智能影库服务器ip,华语视听,家庭影院,发烧音响,智能家居,私人影院,声学装修,专业音箱-艾美影库 MS-300...
  9. win7系统如何开启蓝牙
  10. 几个简约Jekyll主题推荐
  11. 上twitter_如何在Twitter上阻止某人
  12. PHP 实现 apple 苹果快捷登录
  13. ios sdk 穿山甲_iOS 穿山甲广告 SDK 的使用
  14. python笔记2 - 函数,表达式,语句
  15. @敏捷组织从业者,开放敏捷架构O-AA™标准考试及认证项目重磅上线!
  16. 苹果手机来电归属地_工信部 : 暂未出台取消手机号码归属地政策!
  17. 腾讯:建造“通天塔”的“帝企鹅”
  18. 新版ripro全站美化子主题美化包使用说明手册
  19. 联想笔记本那些有手写功能_联想笔记本那些有手写功能_Windows 8 下笔记本如何实现手写输入...
  20. 中国手持式红外测温仪市场深度研究分析报告(2021)

热门文章

  1. logstash 利用drop 丢弃过滤日志
  2. [动规] hihocoder 1149 回文字符序列
  3. 中科燕园GIS外包-----基于ArcGIS的应急平台
  4. [译]GLUT教程 - 键盘高级特性
  5. 使用sprc097的DSP281x_usDelay.asm
  6. C语言补漏(1)--- char到int赋值的一个陷阱
  7. 编程的精髓:发现问题,解决问题
  8. C与CUDA混合编程的配置问题
  9. 无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]
  10. 论文阅读:Deep Filter Banks for Texture Recognition and Segmentation