当前位置: 首页 > news >正文

gateway网关的理解和使用

一、概述

spring-cloud-gateway是一个库,可以在spring webflux之上建立一个API网关,它的目的是提供一个简单,有效的方式去路由到APIS并且提供:安全、监控和弹性。gateway构建于spring boot2.x,spring webFlux,and Project Reactor,所以,许多同步库如spring Data和spring security不适用于gateway项目中。因为gateway是异步非阻塞的。
gateway要求spring boot和spring webFlux提供Netty运行环境。它不能工作在传统的servlet容器或打成一个War包。

二、特点

1、能够对任意的请求属性进行路由匹配

2、能对路由进行断言和过滤

3、集成了熔断器

4、集成了spring-cloud-discoveryclient

5、很容易的写断言和过滤

6、限流

7、路径重写

三、三大组件

1、Route。是构建网关的基本模块,他是ID,目标URL,一系列的断言和过滤器组成,如果断言为true,则匹配该路由

2、Rredicate。参考的是Java8的Predicate,开发人员可以匹配HTTP请求中的所有内容,如果请求与断言相匹配则进行路由

3、Filter。指的是spring框架中GatewayFileter的实例,使用过滤器,可以在请求被路由前由前或者之后对请求进行修改。

四、gateway的工作流程

在这里插入图片描述
客户端将请求发给spring cloud gateway,如果gateway handle mapping 确定这个请求和一个路由匹配,它将此请求发给 gateway web handle. 这个 handle 运行这个请求,通过一个filter chain,这个 filter chain在请求路由前后都能执行。

五、gateway的限流

gateway作为网关,与其他网关技术不同的是它能实现限流。gateway使用的是令牌桶算法实现限流。常见的限流算法有:

1、计数器算法:以QPS为100举例,如果1秒钟内钱200ms请求数量到达了100,后面800ms中的请求都会被拒绝,这种情况称为”突刺现象“

2、漏桶算法:可以解决突刺现象。比如创建一个很大的队列来接收请求,一个较小的线程池来处理请求。但是也有极限情况,当队列满了时, 请求也会拒绝掉。

3、令牌桶算法:可以说是漏桶算法的改进。在桶中放令牌,请求获取令牌后才能继续执行。如果桶中无令牌,请求可以选择进行等待或直接拒绝。

在项目中使用gateway网关做限流一般结合的redis,使用令牌桶算法。

六、gateway的断言

gateway包含了许多内置的路由断言工厂。所有的这些断言匹配不同的HTTP请求属性。你能组合这些路由断言工厂。我们一般是在配置文件中配置predicates,当然我们也可以自定义Predicate,如下:

@Component
public class CustomeRoutePredicateFactory extends AbstractRoutePredicateFactory<PathRoutePredicateFactory.Config> {public CustomeRoutePredicateFactory() {super(PathRoutePredicateFactory.Config.class);}@Overridepublic Predicate<ServerWebExchange> apply(PathRoutePredicateFactory.Config config) {System.out.println("TokenRoutePredicateFactory Start...");return exchange -> {ServerHttpRequest request = exchange.getRequest();//take information from the request to see if it//matches configuration.return matches(config, request);};}private boolean matches(PathRoutePredicateFactory.Config config, ServerHttpRequest request) {System.out.println(request.getBody());RequestPath path = request.getPath();if(path.toString().contains("gateway")) return false;return true;}
}yml
routes:- id: path_routeuri: lb://PROVIDER  # lb的意思是负载均衡predicates:- Custome=/gateway/**    #这个Custome就是自定义类CustomeRoutePredicateFactory的前缀,仿照PathRoutePredicateFactory写的filters:- name: Hystrix    #表示filter中使用Hystrix来做熔断降级args:name: fallbackcmd  #名字唯一即可fallbackUri: forward:/defaultfallback  #在本gateway中产生的异常或超时将调用本gateway中的control层中的defaultfallback  

上面的逻辑是,获取路径值,如果存在gateway字符串,则返回false。

gateway给我们提供了很多内置的Predicate,如断言时间的 AfterRoutePredicateFactory、BeforeRoutePredicateFactory…,断言cookie的CookieRoutePredicateFactory,断言请求头的HeaderRoutePredicateFactory,一般见其名知其意,且yml中配置时只需要写前缀即可,且一般有两个参数,第一个值一般都是Java的正则表达式。例如

	spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, ch.p    #Cookie就是前缀名

七、gateway的filter

gateway的filter有三种:全局Filter、默认Filter和自定义Filter
全局Filter一般是我们定义,全局的filter一般要实现GlobalFilter 和Orderd,我们可以设置getOrder()方法来设置当前Filter的执行权重。order值越小,请求服务前的优先级越高,服务返回后执行的优先级越低

如下

@Beanpublic GlobalFilter customGlobalFilter() {return (exchange, chain) -> exchange.getPrincipal().map(Principal::getName).defaultIfEmpty("Default User").map(userName -> {//adds header to proxied requestexchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();return exchange;}).flatMap(chain::filter);}@Beanpublic GlobalFilter customGlobalPostFilter() {return (exchange, chain) -> chain.filter(exchange).then(Mono.just(exchange)).map(serverWebExchange -> {//adds header to responseserverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");return serverWebExchange;}).then();}

gateway也为我们提供了很多的内置Filter,即默认的Filter,像AddRequestHeaderGatewayFilter,AddRequestParameterGatewayFilter等等。在yml中配置也只需要写前缀即可,如下

spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: https://example.orgfilters:- AddRequestParameter=red, blue

下面讲几个常用的gateway内置的Filter:ForwardRoutingFilter和ReactiveLoadBalancerClientFilter

ForwardRoutingFilter:这个过滤器将URI视为是可改变的属性。当URL有forward修饰时,例如:forward://localendpoint,它会使用spring的DispatcherHandle来处理请求,换句话说,就是用DispatcherHandle来处理forward请求转发。
ReactiveLoadBalancerClientFilter:就是用来负载均衡的。当URL有lb时,例如:lb://myservice,它使用springCloud的ReactLoadBalancer去解析服务名为myservice的微服务(将这个myservice解析为实际的主机和端口,并替换当前的URI),找到这个微服务的集群,并负载均衡到某一台,执行服务。

spring:cloud:gateway:routes:- id: myRouteuri: lb://servicepredicates:- Path=/service/**

注意:gateway支持所有的loadbalancer特性

八、gateway的降级熔断

先看看官网的例子,如下

spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: lb://backing-service:8088predicates:- Path=/consumingServiceEndpointfilters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/inCaseOfFailureUseThis- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

表示如果发生了fallback,则重定向到fallbackUri地址中的controller。正常的话,是到uri中的controller

当然,你也可以使用配置的方式,如下

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {return builder.routes().route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint").filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis")).rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088").build();
}

熔断器也可以这样写,没有fallback或处理在gateway应用中,而是有一个注册在主机9994端口下的应用,这个应用可以处理fallback。

spring:cloud:gateway:routes:- id: ingredientsuri: lb://ingredientspredicates:- Path=//ingredients/**filters:- name: CircuitBreakerargs:name: fetchIngredientsfallbackUri: forward:/fallback- id: ingredients-fallbackuri: http://localhost:9994predicates:- Path=/fallback

下面看看我们自己设置的熔断降级,如下

//在当前gateway中的controller,如果Yml中没有配置其他主机的fallback方法,如果配置了,则该方法配置在另外的主机上。
@Configuration
public class CircuitConfig {@HystrixCommand(commandKey = "gatewayCommand",fallbackMethod = "gatewayFallback",commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED,value = "true"),@HystrixProperty(name =HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,value = "10000"),@HystrixProperty(name =HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,value = "40"),@HystrixProperty(name =HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,value = "5"),})public String gatewayCommand(){return "gatewayCommand method..";}public String gatewayFallback(){return "gatewayFallback method..";}
gateway的ymlroutes:- id: path_routeuri: lb://PROVIDER  # lb的意思是负载均衡predicates:- Custome=/gateway/**filters:- name: Hystrixargs:name: fallbackcmdfallbackUri: forward:/defaultfallback

注意,当前fallbackuri只能使用forward!如果没配置其他的处理fallback的主机,则重定向到当前网关主机的controller路径。

九、gateway整合actuator

需要actuator的依赖。
一般gateway的路由信息是配置注册中心,我们可以使用原始的手工方式刷新路由缓存。使用post请求/actuator/gateway/refresh 即可。当然这需要导入spring的actuator依赖
你也可以检索gateway中所有的路由信息,以手工方式。使用get请求/actuator/gateway/routes
你也可以检索某一个路由信息,使用get请求/actuator/gateway/routes/{id}
总之,可以使用actuator来CRUD路由。

十、总结

1、gateway网关作为整个项目的最上层,其实就是对请求的处理,细化说有:请求路由转发,限流,熔断降级和负载均衡等。但是在项目中一般使用的请求转发和负载均衡。
2、gateway中限流使用的是令牌桶算法。
3、gateway的熔断降级只能在本网关内出现的异常和超时,如果正常请求到别的微服务,而在别的微服务中出现的超时和异常,配置在gateway网关中的熔断降级不起效。
4、gateway使用的异步非阻塞的模型,底层使用的Netty框架,可和springwebFlux、springMvc结合使用。
5、gateway中的Fileter可以理解为是spring中的Aop机制中的环绕通知。有前置和后置,针对请求服务前后而言。Filter的order值越小,执行前置的优先级越大,执行后置的优先级越小。

http://www.xdnf.cn/news/808273.html

相关文章:

  • Mysql current_time,current_date()与now()区别
  • response.setHeader()的用法
  • C语言read函数和pread函数
  • 实训-永恒之蓝入侵系统
  • Linux:分享七款界面非常漂亮的Linux操作系统
  • Linux命令:traceroute命令(路由跟踪)
  • 实用在线词典
  • 一文搞懂Path环境变量
  • 【一】Java快速入门
  • CyanogenMOD移植教程]
  • Android SDK安装教程(超详细),从零基础入门到实战,从看这篇开始
  • 【转】Linux下进程隐藏的常见手法及侦测手段
  • VRRP----虚拟路由器冗余协议
  • 软件测试笔记:黑盒测试——边界测试
  • zCloud - 自治智能的数据库云管平台
  • 《通信技术 - USB》USB基础知识
  • 【C语言编程】新手学C语言时,那些不得不注意的小细节!
  • Pytorch 版本的lookahead 优化函数使用(附代码)
  • WML语言与编程
  • Java 枚举(enum)剖析
  • AI编程助手 Kodezi : 记录、分享一个 VS code 插件
  • 如何符合E-NCAP测试规范?TPT让AEB场景测试更简单:AEB系统的测试场景 | 测试执行与评估 | 测试用例渲染展示
  • 允许Traceroute探测
  • SQL中的distinct的使用方法
  • System.getProperty()方法获取系统变量
  • ubuntu 10.04 下载源列表
  • 《疯狂的站长》读后感1
  • 惊奇的发现37个上班族必看的网站,不看就OUT了
  • iPhone4s降级ios6.1.3流程总结
  • 分享几个普通人做私活赚外快的好地方