在Spring Cloud Zuul网关中,限流业务是放在前置过滤器实现的,也就是在请求被Zuul转发给微服务之前进行限流。另外,当前置过滤器中同时存在限流、鉴权、身份认证等业务时,应该将限流业务放在首位执行。
实现接口限流的方案有很多,常见的包括令牌桶、漏桶、计数器等,这里基于Spring Cloud Zuul网关以令牌桶限流方案来实现接口的限流,令牌桶限流方案的架构图如下所示:
令牌生成器以固定速率生成令牌,并申请将令牌放入令牌桶;如果令牌桶没有放满令牌,则放入令牌,如果令牌桶已放满令牌,则丢弃。当一个Request请求到达Spring Cloud Zuul网关时,网关首先从令牌桶申请获取一个令牌给该请求,申请令牌成功则放行该请求,否则拒绝该请求。
目前已经有很多编程语言实现了令牌桶算法,在Java程序中,应用最广泛的是谷歌提供的开源组件Guava,该组件提供了令牌桶算法的Java实现。
(1)创建Zuul网关限流过滤器
在IntelJ IDEA中打开一个Spring Cloud Zuul网关项目,新建一个过滤器RateLimiterFilter并继承ZuulFilter,代码如下所示:
package cn.org.xcore.mall.zuul.filter;
import cn.org.xcore.mall.zuul.exception.RateLimiterException;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;
/**
* Zuul限流过滤器
*
* @author 李海林 手机:13802780104|微信:lihailin9073|Email:767679879@qq.com
* @copyright 个人开发者李海林版权所有,产品详情及技术服务请登录官网查询[http://www.x-core.org.cn]
* @create 2019-09-15 15:00
*/
@Component
public class RateLimiterFilter extends ZuulFilter {
/**
* 声明一个限流器
*/
private static final RateLimiter RATE_LIMITER = RateLimiter.create(100); // 参数:每秒钟放多少个令牌进桶
@Override
public String filterType() {
return POST_TYPE; // 过滤器类型
}
@Override
public int filterOrder() {
return SERVLET_DETECTION_FILTER_ORDER - 1; // 比优先级最高的Filter还要优先执行
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
if (!RATE_LIMITER.tryAcquire()) { // 从令牌桶申请获取一个令牌
throw new RateLimiterException();
}
return null;
}
}
其中使用到的限流异常类代码如下所示:
package cn.org.xcore.mall.zuul.exception;
/**
* 限流异常类
*
* @author 李海林 手机:13802780104|微信:lihailin9073|Email:767679879@qq.com
* @copyright 个人开发者李海林版权所有,产品详情及技术服务请登录官网查询[http://www.x-core.org.cn]
* @create 2019-09-15 15:03
*/
public class RateLimiterException extends RuntimeException {
}
到此,Spring Cloud Zuul网关组件结合令牌桶算法实现了接口限流方案。
(2)测试限流效果
使用Apache 的ab压测工具,通过终端命令窗口执行如下命令:
#cd F:\phpStudy\PHPTutorial\Apache\bin
#ab -n 5000 -c 300 http://localhost:9301/ms-goods/goods/get_goods_list?_token=abc
上例表示总共访问[http://localhost:9301/ms-goods/goods/get_goods_list?_token=abc]这个接口5000次,300并发同时执行。这里简单讲解一下ab压测命令的常见用法:
-n :总共的请求执行数,缺省是1
-c: 并发数,缺省是1
-t:测试所进行的总时间,秒为单位,缺省50000s
-p:POST时的数据文件
-w: 以HTML表的格式输出结果
执行测试用例:ab -n 1000 -c 100 -w http://localhost:9301/ms-goods/goods/get_goods_list?_token=abc >>d:miss.html
上面的测试用例表示100并发的情况下,共测试访问index.php脚本1000次,并将测试结果保存到d:miss.html文件中。
(3)开源限流组件推荐
在GitHub上有一个使用量挺高的开源限流组件项目,也可以用来实现Zuul网关的限流,项目地址:https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/10457.html