文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java微服务Filter过滤器集成Sentinel实现网关限流过程详解

2023-02-10 09:00

关注

Gateway-过滤器Filter

过滤器就是在请求的传递过程中,对请求和响应做一些手脚.

在Gateway中, Filter的生命周期只有两个:“pre”和“post”"。

.PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。

.POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTPHeader、收集统计信息和指标、将响应从微服务发送给客户端等。

在Gateway中,Filter的作用范围两种:

.GatewayFilter:应用到单个路由或者一个分组的路由上。

.GlobalFilter:应用到所有的路由上

局部路由过滤器

第一步:编写配置文件

第二步:创建局部过滤器类

@Component
    public class TimeGatewayFilterFactory extends AbstractGatewayFilterFactory<TimeGatewayFilterFactory.Config> {
        //解析参数
        public TimeGatewayFilterFactory(){
            super(Config.class);
        }
        //读取配置文件中的参数  赋值到  配置类中
        public List<String> shortcutFieldOrder(){
            return Arrays.asList("show");
        }
        //拦截到之后就会调用apply方法,把创建对象时候反射创建出来的config传入进来
        @Override
        public GatewayFilter apply(Config config) {
            return new GatewayFilter() {
                @Override
                public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                    //前置的逻辑
                    System.out.println("前置逻辑");
                    return chain.filter(exchange).then(Mono.fromRunnable(()->{
                        //后置的逻辑
                        System.out.println("后置逻辑");
                    }));
                }
            };
        }
        //将解析好的参数注入其中
        @Setter
            @Getter
            static class Config{
                private boolean show;
            }
    }

使用局部过滤器

假设我们给商品类创建一个局部过滤器,当传入参数为true的时候,控制台内返回网关转发到服务的时间

创建一个过滤器类:

@Component
    public class TimeGatewayFilterFactory extends AbstractGatewayFilterFactory<TimeGatewayFilterFactory.Config> {
        //解析参数
        public TimeGatewayFilterFactory(){
            super(Config.class);
        }
        //读取配置文件中的参数  赋值到  配置类中
        public List<String> shortcutFieldOrder(){
            return Arrays.asList("show");
        }
        //拦截到之后就会调用apply方法,把创建对象时候反射创建出来的config传入进来
        @Override
        public GatewayFilter apply(Config config) {
            return new GatewayFilter() {
                @Override
                public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                    if(!config.show){
                        return chain.filter(exchange);
                    }

                    //前置的逻辑
                    long start = System.currentTimeMillis();
                    return chain.filter(exchange).then(Mono.fromRunnable(()->{
                        System.out.println("请求耗时:"+(System.currentTimeMillis()-start));
                    }));
                }
            };
        }
        //将解析好的参数注入其中
        @Setter
            @Getter
            static class Config{
                private boolean show;
            }
    }

运行结果:

当参数为true的时候

如果访问别的模块,控制台是不会返回的,这就是局部过滤

当参数为false的时候

全局过滤器

全局过滤器作用于所有路由,无需配置,通过全局过滤器可以实现对权限的统一校验,安全性验证等功能。

假设我们现在有一个需求:实现统一鉴权的功能,我们需要在网关判断请求是否包含token且,如果没有则不转发路由,有则正常逻辑。

使用全局过滤器

1.编写全局过滤类

@Component
public class AuthGlobalFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //前置逻辑
        //获取请求中的token信息,验证token是否有效,如果无效拦截请求,
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if(StringUtils.isEmpty(token)||!"123".equals(token)){
            System.out.println("鉴定失败");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
}

运行结果:

集成Sentinel实现网关限流

网关是所有请求的公共入口,所以可以在网关进行限流,而且限流的方式也很多,我们本次采用前

面学过的Sentinel组件来实现网关的限流。Sentinel支持对SpringCloud Gateway、Zuul等主流网关进 行限流。 从1.6.0版本开始,Sentinel提供了SpringCloud Gateway的适配模块,可以提供两种资源维度的限流: . route维度:即在spring配置文件中配置的路由条目,资源名为对应的routeld ·自定义API维度:用户可以利用Sentinel提供的API来自定义一些API分组

实现步骤:

1.添加依赖

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

2.添加配置文件

cloud:
  sentinel:
    transport:
      port: 9999
      dashboard: localhost:8080

运行结果

那么问题来了,如果给网关限流了,那还有必要给接口限流吗?

答案是一定的,网关限流是为了控制通过网关转发到各个微服务的流量,为了防止网关因为流量过大而损坏,但是万一该微服务中被其它若干个别的模块调用的时候,同样也会遭受到很大的压力,容易造成该模块服务器的损坏

总结一句话

网关限流是为了控制访问该微服务的总体流量,但没有办法控制访问该其中特定接口的流量,接口同样也要增加限流

网关限流

API分组限流

第一步:创建API分组

创建流控:

到此这篇关于Java微服务Filter过滤器集成Sentinel实现网关限流过程详解的文章就介绍到这了,更多相关Java实现网关限流内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯