当前位置:   article > 正文

Gateway配合sentinel自定义限流_Spring Cloud Alibaba系列(四)使用gateway作为服务网关...

sentinelwebfluxfilter stripprefixgatewayfilterfactory

什么是网关

在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计、开发、测试、部署和管理。这时,各个独立部署单元可以用不同的开发测试团队维护,可以使用不同的编程语言和技术平台进行设计,这就要求必须使用一种语言和平台无关的服务协议作为各个单元间的通讯方式。

换句话说就是网关为所有的请求提供了统一的入口,方便我们对服务请求和响应做统一管理。

为什么要用网关

API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。

f25918e8384310e25e79cde3978950c8.png

什么是gateway

Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

gateway工作原理

df341b58a85b5394f008c8289b26d330.png
客户端向Spring Cloud网关发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序运行通过特定于请求的过滤器链发送请求。过滤器由虚线分隔的原因是,过滤器可以在发送代理请求之前或之后执行逻辑。执行所有“前置”过滤器逻辑,然后发出代理请求。发出代理请求后,将执行“后”过滤器逻辑。

路由规则

路由和过滤器是gateway中非常重要的两个概念,gateway本身提供了非常丰富的路由规则和多种过滤器来适配我们的需求。gateway提供了11种路由规则,分别是:

  • 后置路由谓词工厂
    该谓词匹配在当前日期时间之后发生的请求。参数名为 After
  • 前置路由谓词工厂
    该谓词匹配当前日期时间之前发生的请求。参数名为 Before
  • 时间段路由谓词工厂
    该谓词匹配在datetime1之后和datetime2之前发生的请求。参数名为 Between
  • cookie路由谓词工厂
    该谓词匹配具有给定名称的cookie,并且值匹配正则表达式。参数名为 Cookie
  • 标头路由谓词工厂
    该谓词与具有给定名称的标头匹配,并且值与正则表达式匹配。参数名为 Header
  • 主机路由谓词工厂
    该谓词是指由路由进行匹配,匹配多个路由时用,隔开。参数名为 Host
  • 方法路由谓词工厂
    该参数是一个或多个要匹配的HTTP方法。参数名为 Method
  • 路径路由谓词工厂
    该谓词是指在请求路径上加一个前缀,以此来匹配。参数名为 Path
  • 查询路由谓词工厂
  • RemoteAddr路由谓词工厂
  • 重量路线谓词工厂

其中,我们比较常用的就是路径路由谓词工厂,配合StripPrefix GatewayFilter工厂,实现我们的路由匹配转发。

路径路由谓词工厂配置如下:

  1. spring:
  2. cloud:
  3. gateway:
  4. discovery:
  5. locator:
  6. enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
  7. routes:
  8. # 路由id,建议配合服务名
  9. - id: demo_route
  10. #匹配路由名
  11. uri: lb://demo-provider
  12. predicates:
  13. # 断言,路径相匹配的进行路由
  14. - Path=/demo/**

配置的含义就是,如果请求路径中是/demo/**,则转发到demo-provider服务。

网关过滤器

在spring cloud gateway 2.2.2.RELEASE版本中,已经默认实现了30种过滤器。

0a762e90577524ae2c95290104e523ef.png

feb9206e62208838d258a4635f2ddc35.png

这里比较常用的如第25种,配置如下:

  1. spring:
  2. cloud:
  3. gateway:
  4. discovery:
  5. locator:
  6. enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
  7. routes:
  8. # 路由id,建议配合服务名
  9. - id: demo_route
  10. #匹配路由名
  11. uri: lb://demo-provider
  12. predicates:
  13. # 断言,路径相匹配的进行路由
  14. - Path=/demo/**
  15. filters:
  16. - StripPrefix=1

一般情况下我们配合path路由使用,这里的意思是假如,我们的demo-provider服务种有一个/test的接口,实际上我们的请求路径经过网关时应该时/demo/test,这样就能把这个路由分发到demo-provider服务中,但是分发过去的路由是/demo/test,和我们实际的/test接口不一样。这时候我们用StripPrefix=1,来截取掉一级路由,这样转发过去的路由就是/test了。

自定义网关过滤器

除了上面提供的30种过滤器外,我们还可以实现自定义的过滤器。

1. 实现GatewayFilter接口和Ordered接口

gatewayFilter接口是为了实现请求过滤,ordered接口是为了给过滤器设定优先级,值越大级别越低。

想要实现一个自定义的过滤器,无非就是两个步骤:1.实现过滤器,2.将过滤器添加到具体路由上。

  1. public class TokenGatewayFilter implements GatewayFilter, Ordered {
  2. @Override
  3. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  4. System.out.println("这里处理自身逻辑");
  5. return chain.filter(exchange);
  6. }
  7. @Override
  8. public int getOrder() {
  9. return 0;
  10. }
  11. }
  12. @Configuration
  13. class RouteConfiguration{
  14. @Bean
  15. public RouteLocator routeLocator(RouteLocatorBuilder builder){
  16. return builder.routes().route( r->
  17. r.path("/demo/**")
  18. .uri("lb://demo-provider ")
  19. .filter(new TokenGatewayFilter())
  20. .id("demo_route "))
  21. .build();
  22. }
  23. }

2.继承AbstractGatewayFilterFactory类

  1. @Component
  2. public class TokenCheckGatewayFilterFactory extends AbstractGatewayFilterFactory<TokenCheckGatewayFilterFactory.Config> {
  3. public TokenCheckGatewayFilterFactory() {
  4. super(Config.class);
  5. }
  6. @Override
  7. public List<String> shortcutFieldOrder() {
  8. return Arrays.asList("enabled");
  9. }
  10. @Override
  11. public GatewayFilter apply(Config config) {
  12. return (exchange, chain) -> {
  13. system.out.println("这里处理自身逻辑")
  14. return chain.filter(exchange);
  15. };
  16. }
  17. public static class Config {
  18. // 控制是否开启认证
  19. private boolean enabled = true;
  20. public Config() {}
  21. public boolean isEnabled() {
  22. return enabled;
  23. }
  24. public void setEnabled(boolean enabled) {
  25. this.enabled = enabled;
  26. }
  27. }
  28. }

这里我们可以直接在application.yml中为需要过滤的路由添加这个过滤器。

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: demo_route # 路由id,建议配合服务名
  6. uri: lb://demo-provider #匹配路由名
  7. predicates:
  8. - Path=/demo/** # 断言,路径相匹配的进行路由
  9. filters:
  10. - TokenCheck=true

需要注意的是,这个地方自定义的过滤器名称必须是XXGatewayFilterFactory,并且配置文件中配置过滤器时名字必须时这个XX

当然,我们也可以为每个路由都添加这个过滤器,可以直接这样写配置,而不用在每个路由上都去写。

  1. spring:
  2. cloud:
  3. gateway:
  4. default-filters:
  5. - TokenCheck=true

3.实现GlobalFilter和ordered

这个GlobalFilter从名字中就可以看出,是一个全局过滤器,也就是说实现这个接口后,所有的请求都会被过滤,我们就不需要在去找往某个路由中加过滤器了。

  1. @Component
  2. public class TokenGlobalFilter implements GlobalFilter, Ordered {
  3. @Override
  4. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  5. System.out.println("这里处理自身逻辑");
  6. return chain.filter(exchange);
  7. }
  8. @Override
  9. public int getOrder() {
  10. return 0;
  11. }
  12. }

以上就是实现自定义网关过滤器的三种方式了。实际开发中根据需求来实现合适的过滤器就可以了。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/739444
推荐阅读
相关标签
  

闽ICP备14008679号