当前位置:

Spring Cloud入门-Gateway网关

访客 2024-01-05 866 0

摘要

SpringCloudGateway为SpringBoot应用提供了API网关支持,有强大的路由和过滤功能

简介

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

SpringCloudGateway具有如下几个特性

  1. 基于SpringFramework5,ProjectReactor和SpringBoot2.0进行构建;
  2. 动态路由,能匹配任何请求属性
  3. 可以对路由指定Predicate(断言)和Filter(过滤器),并且易于编写
  4. 集成Hystrix的断路器功能
  5. 集成SpringCloud服务发现功能
  6. 请求限流功能
  7. 支持路径重写

相关概念

  1. Route(路由)这是构成网关的基础模块,由Id,目标URL、一系列断言和过滤器,如果断言为true则匹配改路由;
  2. Predicate(断言)指的是Java8的FunctionPredicate。输入类型是Spring框架中的ServerWebExchange。这使开发人员可以匹配HTTP请求中的所有内容,例如请求头或请求参数。如果请求与断言相匹配,则进行路由;
  3. Filter(过滤器)指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前后对请求进行修改。

创建api_gateway模块

这里创建一个api_gateway模块来演示GateWay的常用功能

在pom.xml中添加相关依赖

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

两种不同的配置路由方式

gateway提供了两种不同方式的应用于配置路由,一种是通过yml文件来配置,另外一种是javaBean的方式,下面介绍下

使用YML配置

在application.yml中进行配置:

server:port:9000service-url:user-service:http://localhost:8090eureka:client:service-url:defaultZone:http://localhost:8081/eureka/spring:cloud:gateway:routes:#路由的ID-id:path_route#匹配后路由地址uri:${service-url.user-service}/user/{id}predicates:#断言,路径相匹配的进行路由-Path=/user/{id}

启动注册中心、网关、业务服务,测试地址http://localhost:9000/user/1
最终发现请求落在了业务服务上http://localhost:8090/user/1

使用JavaBean配置

添加相关配置类,并配置一个RouteLocator对象:

@ConfigurationpublicclassGatewayConfig{@BeanpublicRouteLocatorcustomerRouteLocator(RouteLocatorBuilderbuilder){returnbuilder.routes().route("path_route2",r->r.path("/user/getByUsername").uri("http://localhost:8201/user/getByUsername")).build();}}

请求:localhost:9000/user/getByUserName?userName=123
最后落到
localhost:8090/user/getByUserName?userName=123

RoutePredicate的使用

SpringCloudGateway将路由匹配作为SpringWebFluxHandlerMapping基础架构的一部分。SpringCloudGateway包括许多内置的RoutePredicate工厂。所有这么Predicate都将对应HTTP请求的各种属性。并且多个Predicate工厂是可以组合使用的(是&&的关系)
下面介绍一些常用的Predicate

server:port:9002service-url:user-service:http://localhost:8090spring:cloud:gateway:routes:#路由的ID-id:route#匹配后路由地址uri:${service-url.user-service}predicates:#断言,时间之后-After=2021-05-01T18:30:0008:00[Asia/Shanghai]#断言,之间之前#-Before=2019-12-29T18:30:0008:00[Asia/Shanghai]#断言,时间之内#-Between=2019-12-29T18:30:0008:00[Asia/Shanghai],2019-12-30T18:30:0008:00[Asia/Shanghai]#Cookie=username,jourwonCookie#-Cookie=username,jourwon#X-Request-Id后边带有整型#-Header=X-Request-Id,\d#指定host的请求-Host=xx.zglx.com-#get请求的-Method=GET#匹配路由-Path=/user/{id}#匹配参数-Query=username#匹配请求远程地址-RemoteAddr=192.168.1.1/24

WeightRoutePredicate

使用权重来路由相应请求,以下表示有80%的请求会被路由到localhost:8090,20%会被路由到localhost:8091。

server:port:9003service-url:user-serviceOne:http://localhost:8090user-serviceTwo:http://localhost:8091spring:cloud:gateway:routes:#路由的ID-id:route_one#匹配后路由地址uri:${service-url.user-serviceOne}predicates:-Weight=one,8-id:route_two#匹配后路由地址uri:${service-url.user-serviceTwo}predicates:-Weight=one,2

RouteFilter的使用

server:port:9004service-url:user-service:http://localhost:8090eureka:client:service-url:defaultZone:http://localhost:8081/eureka/spring:cloud:gateway:routes:#路由的ID-id:path_route#匹配后路由地址uri:${service-url.user-service}#predicates:#-Method=GET#AddRequestParameter,springcloud内置了很多路由过滤器#filters:##给请求添加参数#-AddRequestParameter=username,jourwon###predicates:#-Path=/user-service/**#filters:##/user-service/开头的请求的路径去除两位#-StripPrefix=2predicates:-Method=GETfilters:#/user路径前缀-PrefixPath=/user

HystrixGatewayFilter

Hystrix过滤器允许你将断路器功能添加到网关路由中,使你的服务免受级联故障的影响,并提供服务降级处理。

pom文件添加

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>packagecom.example.zglx.gateway.controller;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.HashMap;importjava.util.Map;/***@Description:*@Author:Zlx*@Date:2021/10/163:52下午*/@RestControllerpublicclassFallbackController{@GetMapping("/fallback")publicObjectfallback(){Map<String,Object>result=newHashMap<>();result.put("data",null);result.put("message","Getrequestfallback!");result.put("code",500);returnresult;}}spring:cloud:gateway:routes:-id:hystrix_routeuri:${service-url.user-service}predicates:-Method=GETfilters:-name:Hystrixargs:name:fallbackcmdfallback-uri:forward:/fallback

RequestRateLimiterGatewayFilter

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

pom依赖

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

限流策略

packagecom.example.zglx.gateway.config;importorg.springframework.cloud.gateway.filter.ratelimit.KeyResolver;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importreactor.core.publisher.Mono;@ConfigurationpublicclassRedisRateLimiterConfig{@BeanpublicKeyResolveripKeyResolver(){returnexchange->Mono.just(exchange.getRequest().getRemoteAddress().getHostName());}}server:port:9001service-url:user-service:http://localhost:8090eureka:client:service-url:defaultZone:http://localhost:8081/eureka/spring:redis:host:localhostpassword:''port:6379cloud:gateway:routes:-id:requestratelimiter_routeuri:http://localhost:8090filters:-name:RequestRateLimiterargs:#每秒允许处理的请求数量redis-rate-limiter.replenishRate:1#每秒最大处理的请求数量redis-rate-limiter.burstCapacity:2#限流策略,对应策略的Beankey-resolver:"#{@ipKeyResolver}"predicates:-Method=GETlogging:level:org.springframework.cloud.gateway:debug

多次请求http://localhost:8090/user/1

RetryGatewayFilter

server:port:9005service-url:user-service:http://localhost:8090eureka:client:service-url:defaultZone:http://localhost:8081/eureka/spring:cloud:gateway:routes:#路由的ID-id:path_route#匹配后路由地址uri:${service-url.user-service}predicates:#断言,路径相匹配的进行路由-Method=GET#filters:#-name:Hystrix#args:#name:fallbackcmd#fallback-uri:forward:/fallbackfilters:-name:Retryargs:retries:1#需要进行重试的次数statuses:BAD_GATEWAY#返回哪个状态码需要进行重试,返回状态码为5XX进行重试backoff:firstBackoff:10msmaxBackoff:50msfactor:2basedOnPreviousValue:false

如果服务提供者异常,网关会重试两次

结合注册中心使用

根据注册中心,使用动态路由

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>server:port:9006service-url:user-service:http://localhost:8090eureka:client:service-url:defaultZone:http://localhost:8081/eureka/spring:cloud:gateway:#使用lb指定路由使用负载均衡routes:-id:prefixpath_route#此处需要使用lb协议,才能使用gateway的负载均衡uri:lb://user-servicepredicates:-Method=GETfilters:-PrefixPath=/userdiscovery:locator:#开启从注册中心动态创建路由的功能enabled:true#使用小写服务名,默认是大写lower-case-service-id:true#日志logging:level:org.springframework.cloud.gateway:debug

发表评论

  • 评论列表
还没有人评论,快来抢沙发吧~