GateWay(持续更新)

什么是网关
网关是用户管理微服务访问问题。可以通过不同的规则路由到不同的微服务。
为什么采用网关
微服务的地址可能存在变化,需要有一个可以统一管理微服务地址的功能,
网关有什么功能
路由(只用了这一部分),认证,鉴权,熔断,限流,日志监控…
必要术语
路由:用于对不同的服务进行转发(真正意思:一个合集包含Id,url,predicates,filters)
断言:对请求进行判断是否应该进该路由。(org.springframework.cloud.gateway.handler.predicate)
过滤:对请求进行修改和添加等操作
过滤器
● 根据生命周期分为pre和post
a. pre为在转发给服务的前做的操作
a. post是转发后服务回来后所做的操作
pre代码模板
@Component
public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthorizeGatewayFilterFactory.Config> {

private static final String AUTHORIZE_TOKEN = "token";

//构造函数,加载Config
public AuthorizeGatewayFilterFactory() {
    //固定写法
    super(Config.class);
    System.out.println("Loaded GatewayFilterFactory [Authorize]");
}

//读取配置文件中的参数 赋值到 配置类中
@Override
public List<String> shortcutFieldOrder() {
    //Config.enabled
    return Arrays.asList("enabled","name");
}

@Override
public GatewayFilter apply(Config config) {
    return (exchange, chain) -> {
        //判断是否开启授权验证
        if (!config.isEnabled()) {
            return chain.filter(exchange);
        }

        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        //从请求头中获取token
        String token = headers.getFirst(AUTHORIZE_TOKEN);
        if (token == null) {
            //从请求头参数中获取token
            token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
        }

        ServerHttpResponse response = exchange.getResponse();
        //如果token为空,直接返回401,未授权
        if (StringUtils.isEmpty(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //处理完成,直接拦截,不再进行下去
            return response.setComplete();
        }
        /**
         * todo chain.filter(exchange) 之前的都是过滤器的前置处理
         *
         * chain.filter().then(
         *  过滤器的后置处理...........
         * )
         */
        //授权正常,继续下一个过滤器链的调用
        return chain.filter(exchange);
    };
}


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

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Config(boolean enabled, String name) {
        this.enabled = enabled;
        this.name = name;
    }

    public Config() {
    }

    public boolean isEnabled() {
            return enabled;
        }

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

}

post过滤器模板
@Component
public class AccessLogGlobalFilter implements GlobalFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    //filter的前置处理
    ServerHttpRequest request = exchange.getRequest();
    String path = request.getPath().pathWithinApplication().value();
    InetSocketAddress remoteAddress = request.getRemoteAddress();
    return chain
            //继续调用filter
            .filter(exchange)
            //filter的后置处理
            .then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                HttpStatus statusCode = response.getStatusCode();
                System.out.println("------test---------"+new Date());

// log.info(“请求路径:{},远程IP地址:{},响应码:{}”, path, remoteAddress, statusCode);
}));
}

@Override
public int getOrder() {
    return -1;
}

}

● 按照作用域可分为局部过滤域和全局过滤器。
两者的区别:
○ 局部过滤器需要在配置文件中配置方可生效,而全局过滤器不需要。
○ 局部只对声明了的路由进行过滤,全局过滤器只要注册了对所有的路由进行过滤
使用GateWay过滤
是通过过滤器实现限流的:计数器,漏桶,令牌漏桶
RequestRateLimiterGatewayFilterFactory 整体的实现代码
原理是:通过配置KeyResolver来作为redis中的key当执行一次就会往redis进行插入操作,用redis来判断是否超流。
1.实现KeyResolver接口
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

public class IpKeyResolver implements KeyResolver {

@Override
public Mono<String> resolve(ServerWebExchange exchange) {
    //用于控制key的值
    return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}

}

2.注入到容器中
@Bean(name = “ipKeyResolver”)
public KeyResolver userIpKeyResolver() {
return new IpKeyResolver();
}
3.配置过滤器
filters:
- StripPrefix=1
# 指定过滤器
- name: RequestRateLimiter
args:
# 指定限流标识
key-resolver: ‘#{@ipKeyResolver}’
# 速率限流
redis-rate-limiter.replenishRate: 1
# 能容纳的并发流量总数
redis-rate-limiter.burstCapacity: 2
踩坑集
当使用nacos+gateway访问时出现503的错误:原因是无法根据lb去识别

org.springframework.cloud
spring-cloud-loadbalancer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值