7.Cloud-GateWay

0.概述

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

1.入门配置

1.1 POM

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

<!-- nacos -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

1.2 YML

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: payment-route
          uri: lb://cloud-order-service
          predicates:
            - Path=/v2/order/**
          filters:
            - StripPrefix=1
    nacos:
      discovery:
        server-addr: 192.168.2.18:8848
    inetutils:
      ignored-interfaces: ['VMware.*']

1.3 主启动类

@SpringBootApplication
public class GateWayMain {
    public static void main(String[] args) {
        SpringApplication.run(GateWayMain.class, args);
    }
}

1.4 测试

localhost:9527/v2/order/

2.Predicate的使用

cs 复制代码
pring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: lb://cloud-order-service
        predicates:
      # 在某个时间之前的请求才会被转发到 http://localhost:8001,
          - Before=2017-01-20T17:42:47.789+08:00[Asia/Shanghai]
      # 在某个时间之后的请求才会被转发
      #   - After=2017-01-20T17:42:47.789+08:00[Asia/Shanghai]
      # 在某个时间段之间的才会被转发
      #   - Between=2017-01-20T17:42:47.789+08:00[Asia/Shanghai], 2017-01-21T17:42:47.789+08:00[Asia/Shanghai]
 
      # 名为chocolate的表单或者满足正则ch.p的表单才会被匹配到进行请求转发
      #   - Cookie=chocolate, ch.p
    
      # 携带参数X-Request-Id或者满足\d+的请求头才会匹配
      #   - Header=X-Request-Id, \d+
 
      # 按Host主机名匹配
      #   - Host=qiying.com:8080
	
      # 按请求方法进行匹配,只有GET方法才会匹配
      #   - Method=GET
      # 按请求路径进行匹配
      #   - Path=/app/{path}
	
        filters:
      # 在请求路径前加上自定义的路径
      #   - PrefixPath=/app
      # 重写请求路径
      # 访问localhost:8080/test, 请求会转发到localhost:8001/app/test
      #   - RewritePath=/test, /app/test
      #   - RewritePath=(?<oldPath>^/), /app$\{oldPath}
      # 通过模板设置路径
      #   - SetPath=/app/{path}

3.Filter的使用

3.1 自定义全局过滤器

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;

import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        log.info("*********come in MyLogGateWayFilter: "+new Date());

        String name = exchange.getRequest().getQueryParams().getFirst("username");
        if(StringUtils.isEmpty(name))
        {
            log.info("*****用户名为Null 非法用户,(┬_┬)");
            exchange.getResponse().setRawStatusCode(HttpStatus.NOT_ACCEPTABLE.value());
            return exchange.getResponse().setComplete();
        }

        return chain.filter(exchange);
    }

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

3.2 令牌桶算法限流

  1. YML配置

    spring:
    application:
    name: cloud-gateway
    cloud:
    gateway:
    routes:
    - id: cloud-order-service
    uri: lb://cloud-order-service
    predicates:
    - Path=/v2/**
    - After=2024-02-17T10:41:00.000+08:00[Asia/Shanghai]
    filters:
    - name: StripPrefix
    args:
    parts: 1
    - name: RequestRateLimiter
    args:
    keyResolver: '#{@myKeyResolver}'
    redis-rate-limiter.replenishRate: 1 #生产令牌速度,每秒多少个
    redis-rate-limiter.burstCapacity: 5 #令牌桶容量
    nacos:
    discovery:
    server-addr: 192.168.2.18:8848
    inetutils:
    ignored-interfaces: ['VMware.*']
    redis:
    host: 192.168.2.18
    password: 123456

  2. 创建MyKeyResolver类

    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;

    @Component
    public class MyKeyResolver implements KeyResolver {

     @Override
     public Mono<String> resolve(ServerWebExchange exchange) {
    
         String address = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
         return Mono.just(address);
     }
    

    }

  3. request_rate_limiter.lua

    local tokens_key = KEYS[1]
    local timestamp_key = KEYS[2]
    --redis.log(redis.LOG_WARNING, "tokens_key " .. tokens_key)

    local rate = tonumber(ARGV[1])
    local capacity = tonumber(ARGV[2])
    local now = tonumber(ARGV[3])
    local requested = tonumber(ARGV[4])

    local fill_time = capacity/rate
    local ttl = math.floor(fill_time*2)

    --redis.log(redis.LOG_WARNING, "rate " .. ARGV[1])
    --redis.log(redis.LOG_WARNING, "capacity " .. ARGV[2])
    --redis.log(redis.LOG_WARNING, "now " .. ARGV[3])
    --redis.log(redis.LOG_WARNING, "requested " .. ARGV[4])
    --redis.log(redis.LOG_WARNING, "filltime " .. fill_time)
    --redis.log(redis.LOG_WARNING, "ttl " .. ttl)

    local last_tokens = tonumber(redis.call("get", tokens_key))
    if last_tokens == nil then
    last_tokens = capacity
    end
    --redis.log(redis.LOG_WARNING, "last_tokens " .. last_tokens)

    local last_refreshed = tonumber(redis.call("get", timestamp_key))
    if last_refreshed == nil then
    last_refreshed = 0
    end
    --redis.log(redis.LOG_WARNING, "last_refreshed " .. last_refreshed)

    local delta = math.max(0, now-last_refreshed)
    local filled_tokens = math.min(capacity, last_tokens+(delta*rate))
    local allowed = filled_tokens >= requested
    local new_tokens = filled_tokens
    local allowed_num = 0
    if allowed then
    new_tokens = filled_tokens - requested
    allowed_num = 1
    end

    --redis.log(redis.LOG_WARNING, "delta " .. delta)
    --redis.log(redis.LOG_WARNING, "filled_tokens " .. filled_tokens)
    --redis.log(redis.LOG_WARNING, "allowed_num " .. allowed_num)
    --redis.log(redis.LOG_WARNING, "new_tokens " .. new_tokens)

    redis.call("setex", tokens_key, ttl, new_tokens)
    redis.call("setex", timestamp_key, ttl, now)

    return { allowed_num, new_tokens }

  4. 如果请求每秒超过5个,将无法访问, 执行的类,RedisRateLimiter.isAllowed

3.3 自定义断言过滤器

  1. 创建过滤器

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.cloud.gateway.filter.GatewayFilter;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;

    import java.util.Arrays;
    import java.util.List;

    @Component
    @Slf4j
    public class XXGatewayFilterFactory extends AbstractGatewayFilterFactory<XXGatewayFilterFactory.Config> {

     public XXGatewayFilterFactory()
     {
         super(Config.class);
     }
    
     @Override
     public List<String> shortcutFieldOrder() {
    
         return Arrays.asList("path");
     }
    
     @Override
     public GatewayFilter apply(Config config) {
    
         return new GatewayFilter() {
             @Override
             public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
                 log.info("xx-GatewayFilter-filter");
                 return chain.filter(exchange);
             }
         };
     }
    
     public static class Config
     {
         public String getPath() {
             return path;
         }
    
         public void setPath(String path) {
             this.path = path;
         }
    
         private String path;
     }
    

    }

  2. YML

    spring:
    cloud:
    gateway:
    routes:
    - id: cloud-order-service
    uri: lb://cloud-order-service
    predicates:
    - Path=/v2/**
    - After=2024-02-17T10:41:00.000+08:00[Asia/Shanghai]
    filters:
    - name: XX

3.4

4.跨域

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowedHeaders: "*"
            allowedOrigins: "*"
            allowedMethods: "*"
相关推荐
疯一样的码农几秒前
Apache Maven简介
java·maven·apache
小安同学iter13 分钟前
Java进阶五 -IO流
java·开发语言·intellij-idea
码到成功>_<22 分钟前
Spring Boot实现License生成和校验
数据库·spring boot·后端
尽兴-23 分钟前
Redis模拟延时队列 实现日程提醒
java·redis·java-rocketmq·mq
书埋不住我43 分钟前
java第三章
java·开发语言·servlet
boy快快长大1 小时前
将大模型生成数据存入Excel,并用增量的方式存入Excel
java·数据库·excel
孟秋与你1 小时前
【spring】spring单例模式与锁对象作用域的分析
java·spring·单例模式
菜菜-plus1 小时前
java 设计模式 模板方法模式
java·设计模式·模板方法模式
萨达大1 小时前
23种设计模式-模板方法(Template Method)设计模式
java·c++·设计模式·软考·模板方法模式·软件设计师·行为型设计模式
tian-ming1 小时前
(十八)JavaWeb后端开发案例——会话/yml/过滤器/拦截器
java·开发语言·前端