当前位置: 代码网 > it编程>编程语言>Java > 【Spring Cloud】Gateway 服务网关限流

【Spring Cloud】Gateway 服务网关限流

2024年07月31日 Java 我要评论
网关是所有请求的公共入口,所以可以在网关进行限流,而且限流的方式也很多,我们本次采用前面学过的 Sentinel 组件来实现网关的限流。


网关是所有请求的公共入口,所以可以在网关进行限流,而且限流的方式也很多,我们本次采用前面学过的 sentinel 组件来实现网关的限流。

在这里插入图片描述

从1.6.0版本开始,sentinel提供了springcloud gateway的适配模块,可以提供两种资源维度的限流:

  • route维度:即在spring配置文件中配置的路由条目,资源名为对应的routeld;
  • 自定义api维度:用户可以利用sentinel提供的api来自定义一些api分组;

route限流

导入依赖

<dependency>
	<groupid>com.alibaba.csp</groupid>
	<artifactid>sentinel-spring-cloud-gateway-adapter</artifactid>
</dependency>

编写配置类

基于sentinel的gateway限流是通过其提供的filter来完成的,使用时只需注入对应的sentinelgatewayfilter实例以及sentinelgatewayblockexceptionhandler实例即可。

@configuration
public class gatewayconfiguration {
    private final list<viewresolver> viewresolvers;
    private final servercodecconfigurer servercodecconfigurer;

    public gatewayconfiguration(objectprovider<list<viewresolver>> viewresolversprovider, servercodecconfigurer servercodecconfigurer) {
        this.viewresolvers = viewresolversprovider.getifavailable(collections::emptylist);
        this.servercodecconfigurer = servercodecconfigurer;
    }

    //初始化一个限流的过滤器
    @bean
    @order(ordered.highest_precedence)
    public globalfilter sentinelgatewayfilter() {
        return new sentinelgatewayfilter();
    }

    //配置初始化的限流参数
    @postconstruct
    public void initgatewayrules() {
        set<gatewayflowrule> rules = new hashset<>();
        rules.add(new gatewayflowrule("shop-product")//资源名称,对应路由id
                        .setcount(1)//限流阀值
                        .setintervalsec(1)//统计时间窗口,单位是秒,默认是1秒
        );
        gatewayrulemanager.loadrules(rules);
    }


    //配置限流异常处理器
    @bean
    @order(ordered.highest_precedence)
    public sentinelgatewayblockexceptionhandler sentinelgatewayblockexceptionhandler() {
        return new sentinelgatewayblockexceptionhandler(viewresolvers, servercodecconfigurer);
    }

    //自定义限流异常页面
    @postconstruct
    public void initblockhandlers() {
        blockrequesthandler blockrequesthandler = new blockrequesthandler() {
            @override
            public mono<serverresponse> handlerequest(serverwebexchange serverwebexchange, throwable throwable) {
                map map= new hashmap<>();
                map.put("code", 0);
                map.put("message", "接口被限流了");
                return serverresponse
                        .status(httpstatus.ok)
                        .contenttype(mediatype.application_json_utf8)
                        .body(bodyinserters.fromobject(map));
            }
        } ;
        gatewaycallbackmanager.setblockhandler(blockrequesthandler);
    }
}

其中,gatewayflowrule 网关限流规则中提供了如下属性:

  • resource:资源名称,可以是网关中的route名称或者用户自定义的api分组名称。
  • resourcemode:资源模型,限流规则是针对api gateway的 route (resource_mode_route_id)还是用户在sentinel 中定义的api分组(resource_mode_custom_api_name),默认route。
  • grade:限流指标维度,同限流规则的 grade 字段。
  • count:限流阈值。
  • intervalsec:统计时间窗口,单位是秒, 默认是1 秒。
  • controlbehavior:流量整形的控制效果,同限流规则的controlbehavior字段,目前支持快速失败和匀速排队两种模式,默认快速失败。
  • burst:应对突发请求时额外允许的请求数目。
  • maxqueueingtimeoutms:匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效。
  • paramitem:参数限流配置。若不提供,则代表针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换热点规则。其中的字段如下:
    • arsestrategy: 从请求中提取参数的策略,目前支持提取来源ip(param_parse_strategy_client_ip)、host(param_parse_strategy_host)、任意header(param_parse_strategy_header)和任意url 参数(param_parse_strategy_url_param)四种模式。
    • fieldname:若提取策略选择header模式或者url参数模式,则需要指定对应的header名称或url参数名称。
    • pattern和matchstrategy: 为后续参数匹配特性预留,目前末实现。

测试

在一秒钟内多次访问http://localhost:7000/product/product/1?token=1232就可以看到限流启作用了。

在这里插入图片描述

自定义api分组

自定义api分组是一种更细粒度的限流规则定义

//配置初始化的限流参数
@postconstruct
public void initgatewayrules() {
    set<gatewayflowrule> rules = new hashset<>();
    rules.add(new gatewayflowrule("shop_product_api").setcount(1).setintervalsec(1));
    rules.add(new gatewayflowrule("shop_order_api").setcount(1).setintervalsec(1));
    gatewayrulemanager.loadrules(rules);
}

//自定义api分组
@postconstruct
private void initcustomizedapis(){
    set<apidefinition> definitions = new hashset<>();
    //定义小组1
    apidefinition api1 = new apidefinition("shop_product_api")
            .setpredicateitems(new hashset<apipredicateitem>(){{
                //以/product/product/api1开头的请求
                add(new apipathpredicateitem().setpattern("/product/product/**")
                        .setmatchstrategy(sentinelgatewayconstants.url_match_strategy_prefix));
            }});
    //定义小组2
    apidefinition api2 = new apidefinition("shop_order_api")
            .setpredicateitems(new hashset<apipredicateitem>(){{
                //完全匹配/order/order2/message
                add(new apipathpredicateitem().setpattern("/order/order2/message"));
            }});
    definitions.add(api1);
    definitions.add(api2);
    gatewayapidefinitionmanager.loadapidefinitions(definitions);
}

在一秒钟内多次访问http://localhost:7000/product/product/1?token=1232也可以看到限流启作用了。
在这里插入图片描述

总结

到这儿,gateway 服务网关限流的内容就已经介绍完了。下一篇将为大家带来链路追踪sleuth相关的文章,敬请期待吧!

后续的文章,我们将继续完善我们的微服务系统,集成更多的alibaba组件。想要了解更多java后端知识,请点击文末名片与我交流吧。留下您的一键三连,让我们在这个寒冷的东西互相温暖吧!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com