Spring Cloud Alibaba系列(四)gateway网关

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

什么是网关

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

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

为什么要用网关

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

什么是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工作原理

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

路由规则

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

  • 后置路由谓词工厂

    该谓词匹配在当前日期时间之后发生的请求。参数名为 After
    
  • 前置路由谓词工厂

    该谓词匹配当前日期时间之前发生的请求。参数名为 Before
    
  • 时间段路由谓词工厂

    该谓词匹配在datetime1之后和datetime2之前发生的请求。参数名为 Between
    
  • cookie路由谓词工厂

    该谓词匹配具有给定名称的cookie,并且值匹配正则表达式。参数名为 Cookie
    
  • 标头路由谓词工厂

    该谓词与具有给定名称的标头匹配,并且值与正则表达式匹配。参数名为 Header
    
  • 主机路由谓词工厂

    该谓词是指由路由进行匹配,匹配多个路由时用,隔开。参数名为 Host
    
  • 方法路由谓词工厂

    该参数是一个或多个要匹配的HTTP方法。参数名为 Method
    
  • 路径路由谓词工厂

    该谓词是指在请求路径上加一个前缀,以此来匹配。参数名为 Path
    
  • 查询路由谓词工厂
  • RemoteAddr路由谓词工厂
  • 重量路线谓词工厂

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

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

spring:
  cloud:
    gateway:
      discovery:
          locator:
              enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
          # 路由id,建议配合服务名
        - id: demo_route 
          #匹配路由名
          uri: lb://demo-provider 
          predicates:
          # 断言,路径相匹配的进行路由
          - Path=/demo/** 

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

网关过滤器

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

序号 过滤器工厂 作用 参数
1 AddRequestHeader 为原始请求添加Header Header的名称及值
2 AddRequestParameter 为原始请求添加请求参数 参数名称及值
3 AddResponseHeader 为原始响应添加Header Header的名称及值
4 DedupeResponseHeader 剔除响应头中重复的值 需要去重的Header名称及去重策略
5 Hystrix 为路由引入Hystrix的断路器保护 HystrixCommand的名称
6 CircuitBreaker 为路由引入Resilience4J断路器保护 CircuitBreaker的名称
7 FallbackHeaders 为fallbackUri的请求头中添加具体的异常信息 Header的名称
MapRequestHeader 更新原始请求中的Header Header的值
9 PrefixPath 为原始请求头添加前缀 前缀路径
10 PreserveHostHeader 为请求添加preserverHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的host
11 RequestRateLimiter 用于对请求限流,限流算法为令牌桶 keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus
12 RedirectTo 将原始请求重定向到指定的url http状态码及重定向的url
13 RemoveHopByHopHeadersFilter 为原始请求删除IETF组织规定的一系列Header 默认就会启用,可以通过配置指定仅删除哪些Header
14 RemoveRequestHeader 为原始请求删除某个Header Header名称
15 RemoveResponseHeader 为原始响应删除某个Header Header名称
16 RewritePath 重写原始的请求路径 原始路径正则表达式以及重写后路径的正则表达式
17 RewriteLocationResponseHeader 重写响应头的Location 的值
18 RewriteResponseHeader 重写原始响应中的某个Header Header名称,值的正则表达式,重写后的值
19 SaveSession 在转发请求之前,强制执行WebSession::save操作
20 SecureHeaders 为原始响应添加一系列起安全作用的响应头 无,支持修改这些安全响应头的值
21 SetPath 修改原始的请求路径 修改后的值
22 SetRequestHeader 修改原始请求中的某个Header的值 Header名称,修改后的值
23 SetResponseHeader 修改原始响应中某个Header的值 Header名称,修改后的值
24 SetStatus 修改原始响应的状态码 HTTP 状态码,可以是数字,也可以是字符串
25 StripPrefix 用于截断原始请求的路径 使用数字表示要截断的路径的数量
26 Retry 针对不同的响应进行重试 retries、statuses、methods、series
27 RequestSize 设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large 请求包大小,单位为字节,默认值为5M
28 ModifyRequestBody 在转发请求之前修改原始请求体内容 修改后的请求体内容
29 ModifyResponseBody 修改原始响应体的内容 修改后的响应体内容
30 Default 为所有路由添加过滤器 过滤器工厂名称及值

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

spring:
  cloud:
    gateway:
      discovery:
          locator:
              enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
          # 路由id,建议配合服务名
        - id: demo_route 
          #匹配路由名
          uri: lb://demo-provider 
          predicates:
          # 断言,路径相匹配的进行路由
          - Path=/demo/** 
          filters:
          - StripPrefix=1

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

自定义网关过滤器

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

1. 实现GatewayFilter接口和Ordered接口

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

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

public class TokenGatewayFilter implements GatewayFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        System.out.println("这里处理自身逻辑");

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

@Configuration
class RouteConfiguration{

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder){

        return builder.routes().route( r->
                r.path("/demo/**")
                .uri("lb://demo-provider ")
                .filter(new TokenGatewayFilter())
                .id("demo_route "))
                .build();
    }
}

2.继承AbstractGatewayFilterFactory类

@Component
public class TokenCheckGatewayFilterFactory extends AbstractGatewayFilterFactory<TokenCheckGatewayFilterFactory.Config> {
    public TokenCheckGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("enabled");
    }
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            system.out.println("这里处理自身逻辑")
            return chain.filter(exchange);
        };

    }

    public static class Config {
        // 控制是否开启认证
        private boolean enabled = true;

        public Config() {}

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }
}

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

spring:
  cloud:
    gateway:
      routes:
        - id: demo_route # 路由id,建议配合服务名
          uri: lb://demo-provider #匹配路由名
          predicates:
          - Path=/demo/** # 断言,路径相匹配的进行路由
          filters:
          - TokenCheck=true

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

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

spring:
  cloud:
    gateway:
      default-filters:
        - TokenCheck=true

3.实现GlobalFilter和ordered

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

@Component
public class TokenGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("这里处理自身逻辑");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

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

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
目录
相关文章
|
7月前
|
人工智能 Java Nacos
基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
本文将针对 Spring AI Alibaba + Nacos 的分布式多智能体构建方案展开介绍,同时结合 Demo 说明快速开发方法与实际效果。
5104 99
|
8月前
|
存储 缓存 负载均衡
Gateway 网关坑我! 被这个404 问题折腾了一年?
小富分享了一个困扰团队一年多的 SpringCloud Gateway 路由 404 问题。通过日志追踪和源码分析,发现是网关在 Nacos 配置更新后未能正确清理旧的路由权重缓存,导致负载均衡时仍使用已删除的路由数据。最终通过监听路由刷新事件并手动更新缓存,成功解决了问题。
1239 125
Gateway 网关坑我! 被这个404 问题折腾了一年?
|
7月前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
7747 111
|
8月前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
6933 2
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
|
7月前
|
机器学习/深度学习 Kubernetes API
【Azure APIM】自建网关(self-host gateway)收集请求的Header和Body内容到日志中的办法
在Azure API Management中,通过配置trace策略可完整记录API请求的Header和Body信息。在Inbound和Outbound策略中分别使用context.Request/Response.Headers和Body.As&lt;string&gt;方法捕获数据,并写入Trace日志,便于排查与审计。
240 8
|
7月前
|
人工智能 监控 Java
Spring AI Alibaba实践|后台定时Agent
基于Spring AI Alibaba框架,可构建自主运行的AI Agent,突破传统Chat模式限制,支持定时任务、事件响应与人工协同,实现数据采集、分析到决策的自动化闭环,提升企业智能化效率。
Spring AI Alibaba实践|后台定时Agent
|
9月前
|
人工智能 Java 开发者
邀您参与 “直通乌镇” Spring AI Alibaba 开源竞技挑战赛!
邀您参与 “直通乌镇” Spring AI Alibaba 开源竞技挑战赛!
|
SpringCloudAlibaba API 开发者
新版-SpringCloud+SpringCloud Alibaba
新版-SpringCloud+SpringCloud Alibaba
|
负载均衡 Dubbo Java
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
|
人工智能 SpringCloudAlibaba 自然语言处理
SpringCloud Alibaba AI整合DeepSeek落地AI项目实战
在现代软件开发领域,微服务架构因其灵活性、可扩展性和模块化特性而受到广泛欢迎。微服务架构通过将大型应用程序拆分为多个小型、独立的服务,每个服务运行在其独立的进程中,服务与服务间通过轻量级通信机制(通常是HTTP API)进行通信。这种架构模式有助于提升系统的可维护性、可扩展性和开发效率。
5373 2

热门文章

最新文章