spring-cloud-gateway基础篇

文章目录

  • spring cloud gateway 基础篇
    • 1.断言 Predicate
    • 2.过滤器 Filter
      • 全局过滤器
      • 网关过滤器工厂
    • 3.兼容服务注册中心(Nacos)
    • 4.请求限流

spring cloud gateway 基础篇

1.断言 Predicate

内置断言

名称 功能 使用
Path 请求路径匹配 - Path=/red/{segment},/blue/{segment}
Query 请求参数匹配 - Query=tenantId,123456
Method 请求类型匹配 - Method=GET,POST
After 某个时间之后 - After=1996-10-12T10:12:00.789-07:00[America/Denver]
Befor 某个时间之前 - Befor=1996-10-12T10:12:00.789-07:00[America/Denver]
Between 时间段内 - Between=开始时间,结束时间
Cookie cookie中包含 - Cookie=chocolate, 某个正则表达式
Header header中包含 - Header=X-Request-Id, 某个正则表达式
Host 请求的host值 - Host=.somehost.org,.anotherhost.org
RemoteAddr 请求的远程地址 - RemoteAddr=192.168.1.1/24
Weight 路由转发权重 - Weight=group1, 2
XForwardedRemoteAddr 许根据 X-Forwarded-For的 HTTP Header 对请求进行过滤 - XForwardedRemoteAddr=192.168.1.1/24

自定义断言

  • 继承 AbstractRoutePredicateFactory 抽象类,重写 apply() 方法实现断言逻辑
  • 通过 @Component 交予 spring boot 容器管理
  • 路由中配置断言工厂
@Component
public class CustomRoutePredicateFactory extends AbstractRoutePredicateFactory<CustomRoutePredicateFactory.Config> {
    public QueryParamRoutePredicateFactory() { super(Config.class); }
 
    @Override
    public List<String> shortcutFieldOrder() { return Arrays.asList("param", "regexp"); }
 
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            boolean flage = flase;
            // 业务逻辑
            return flag;
        };
    }
 
    public static class Config {
        private String param;
        private java.util.regex.Pattern regexp;
 
        public Config(String param, String regexp) {
            this.param = param;
            this.regexp = java.util.regex.Pattern.compile(regexp);
        }
    }
}

路由配置

spring:
  cloud:
    gateway:
      routes:
        - id: my-route-id-1
          predicates:
            - Path=/order-service/**
            - Custom=param,lcl
          uri: http://127.0.0.1:7777
          filters:
            - StripPrefix=1

2.过滤器 Filter

全局过滤器

父级:

public interface GlobalFilter {
	Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
public interface Ordered {
    // 值越小,优先级越高
	int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
    // 值越大,优先级越低
	int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
	int getOrder();
}

内置全局过滤器:

名称 排序 说明
RemoveCachedBodyFilter MIN_VALUE 清除上下文中的body缓存,配合AdaptCachedBodyGlobalFilter使用
AdaptCachedBodyGlobalFilter MIN_VALUE + 1000 在请求处理的不同阶段,缓存请求和响应的body
NettyWriteResponseFilter -1 将使用Netty发起的服务的响应数据返回到客户端
WebClientWriteResponseFilter -1 将使用WebClient发起的服务的响应数据返回到客户端
ForwardPathFilter 0 用来处理Forward URI,对应ForwardRoutingFilter来转发请求
GatewayMetricsFilter 0 收集网关的基本性能指标数据,例如请求的数量、响应时间等‌
RouteToRequestUrlFilter 1000 根据请求的URL将请求路由到适当的目标微服务
WeightCalculatorWebFilter 10000 + 1 是动态调整路由权重
ReactiveLoadBalancerClientFilter 10150 负载均衡和运行状况检查
LoadBalancerServiceInstanceCookieFilter 10150 + 1 处理负载均衡服务实例的cookie
WebsocketRoutingFilter MAX_VALUE- 1 处理WebSocket协议的请求转发
ForwardRoutingFilter MAX_VALUE 处理forward协议的请求,将ForwardPathFilter构建的新的Request发送给DispatcherHandler处理
NettyRoutingFilter MAX_VALUE 使用 Netty 作为客户端进行HTTP请求处理路由决策
WebClientHttpRoutingFilter MAX_VALUE 使用WebClient作为客户端进行HTTP请求处理路由决策【构建反应式应用和服务】

自定义全局过滤器:注册即生效与所有路由

  • 继承 GlobalFilter 接口,重写 filter() 方法实现过滤器逻辑
  • 继承 Ordered 接口,重写 getOrder() 方法指定排序
  • 通过 @Component 交予 spring boot 容器管理
@Slf4j @Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info(">>>>> 自定义全局过滤器执行,排序号=10");
        // TODO 业务逻辑
        return chain.filter(exchange);
    }

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

网关过滤器工厂

父级:

public abstract class AbstractGatewayFilterFactory<C> extends AbstractConfigurable<C> implements GatewayFilterFactory<C>, ApplicationEventPublisherAware {

	private ApplicationEventPublisher publisher;

	@SuppressWarnings("unchecked")
	public AbstractGatewayFilterFactory() { super((Class<C>) Object.class); }
	public AbstractGatewayFilterFactory(Class<C> configClass) { super(configClass); }

	protected ApplicationEventPublisher getPublisher() { return this.publisher; }
	@Override
	public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; }

	public static class NameConfig {
		private String name;
		public String getName() { return name; }
		public void setName(String name) { this.name = name; }
	}

}

public interface Ordered {
    // 值越小,优先级越高
	int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
    // 值越大,优先级越低
	int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
	int getOrder();
}

内置网关过滤器工厂:

名称 说明
OrderedGatewayFilter 管理过滤器链中的过滤器执行顺序
RequestRateLimiter 请求限流
AddRequestHeader 添加请求头
AddRequestHeadersIfNotPresent 添加请求头(只在 header 信息不存在的情况)
RemoveRequestHeader 删除请求头
SetRequestHeader 修改请求头
SetRequestHostHeader 替换请求的host
SecureHeaders 在HTTP响应中添加安全相关的HTTP头部,以增强应用的安全性
PreserveHostHeader 保留原始请求的Host头信息
AddRequestParameter 添加请求参数
RemoveRequestParameter 删除请求参数
MapRequestHeader 修改请求中的头部信息
RequestHeaderSize 限制通过网关的请求头的大小
ModifyRequestBody 重写请求体(这个过滤器只能通过使用Java DSL来配置)
CacheRequestBody 缓存响应体(请求体只能被读取一次)
名称 说明
AddResponseHeader 添加响应头
RemoveResponseHeader 删除响应头
SetResponseHeader 修改响应头
RewriteResponseHeader 重写响应头中的值
RewriteLocationResponseHeader 修改Location响应头
DedupeResponseHeader 响应头去重
RemoveJsonAttributesResponseBody 移除响应体中的某些JSON属性
ModifyResponseBody 重写响应体(这个过滤器只能通过使用Java DSL来配置。)
LocalResponseCache 缓存响应数据,后续相同的请求,网关可以直接从缓存中获取响应,无需再次发送请求
名称 说明
PrefixPath 为匹配成功的路由添加请求路径前缀
StripPrefix 去掉部分URL路径
SetPath 设置请求的路径
RewritePath 重写请求的路径
RedirectTo 将客户端的请求重定向到另一个URL
名称 说明
SetStatus 修改HTTP响应的状态码
CircuitBreaker 熔断。防止服务雪崩,通过断路机制来保护系统免受突发流量或服务故障的影响
FallbackHeaders 在请求失败时,向客户端返回一个自定义的响应头
JSONToGRPCFilter 将一个JSON格式的请求转换为gRPC请求
SaveSession 在请求处理过程中保存会话信息
Retry 提供重试机制,帮助处理网络延迟、服务暂时不可用等临时性问题
TokenRelay 在请求转发过程中,将原始请求中的Token信息传递给下游服务

自定义网关过滤器:注册后,还需在路由中配置使用

  • 继承 AbstractGatewayFilterFactory 抽象类,重写 apply() 方法实现过滤器逻辑
  • 继承 Ordered 接口,重写 getOrder() 方法指定排序
  • 通过 @Component 交予 spring boot 容器管理
  • 路由中配置网关过滤器工厂
@Slf4j @Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.Config> implements Ordered {
    public CustomGatewayFilterFactory() { super(Config.class); }

    @Override
    public List<String> shortcutFieldOrder() { return Arrays.asList("name", "age"); }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            log.info(">>>>> 自定义网关过滤器工厂执行:order=10,config={}", config);
            // TODO 业务逻辑
            return chain.filter(exchange);
        };
    }

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

    @Data
    public static class Config {
        private String name;
        private String age;
    }
}

路由配置

spring:
  cloud:
    gateway:
      routes:
        - id: my-route-id-1
          predicates:
            - Path=/order-service/**
          uri: http://127.0.0.1:7777
          filters:
            - StripPrefix=1
            - AddRequestParameter=tenantId, 123456
            - Custom=张三,18 # 配置自定义网关过滤器

3.兼容服务注册中心(Nacos)

添加Nacos依赖

<dependencyManagement>
    <dependencies>
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-alibaba-dependenciesartifactId>
            <version>${spring-cloud-alibaba.version}version>
            <type>pomtype>
            <scope>importscope>
        dependency>
dependencyManagement>
<dependencies>
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
    dependency>
    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-loadbalancerartifactId>
    dependency>
dependencies>

配置Nacos,设置 spring.cloud.gateway.discovery.locator.enabled=true 并确保 DiscoveryClient 实现

spring:
  cloud:
    # Nacos 配置
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true # 让 gateway 可以配合 nacos,自动路由微服务,并实现负责均衡
      routes:
        - id: nacos-service-route 
          predicates:
            - Path=/order-service/** 
          uri: lb://ORDER-SERVICE # lb是负载均衡,后面跟服务名称【uri=lb://TEST_SERVICE】
          filters:
            - StripPrefix=1 # 内置过滤器-StripPrefix:表示截断路径前缀。如果请求的路径为/order-service/order/1,则路径会修改为/order/1】

4.请求限流

通过配置内置网关过滤器工厂RequestRateLimiterGatewayFilterFactory

spring:
  cloud:
    gateway:
      routes:
        - id: nacos-service-route 
          predicates:
            - Path=/order-service/** 
          uri: lb://ORDER-SERVICE
          filters:
            - StripPrefix=1
			- name: RequestRateLimiter # 内置限流过滤器-RequestRateLimiterGatewayFilterFactory:这个Filter依赖于Redis实现的令牌桶限流
              args:
                key-resolver: '#{@uriKeyResolver}' # 限流维度实现类:可以根据ip,uri,设备号,用户id等进行限流,这里使用uriKeyResolver对url进行限流
                redis-rate-limiter.replenishRate: 1 # 每秒填充平均速率,相当于QPS
                redis-rate-limiter.burstCapacity: 1 # 限流容量
                redis-rate-limiter.requestedTokens: 1 # 每个请求需要的令牌数

不同的限流维度Bean

@Configuration
public class RateConfig {
    /** Uri维度限流方法 */
    @Bean
    public KeyResolver uriKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
    }
}

你可能感兴趣的:(spring-cloud-gateway基础篇)