SpringCloud之在Zuul上实现微服务粒度的限流(jmeter模拟高并发测试吞吐量实战)
发布日期:2021-06-29 19:25:59 浏览次数:3 分类:技术文章

本文共 3751 字,大约阅读时间需要 12 分钟。

1、Google Guava提供了限流工具类RateLimiter,在Zuul下添加如下依赖:

com.marcosbarbero.cloud
spring-cloud-zuul-ratelimit
1.5.0.RELEASE

2、在Zuul服务下新加RateLimitZuulFilter类,继承ZuulFilter,源码如下:

@Componentpublic class RateLimitZuulFilter extends ZuulFilter {    private Map
map = Maps.newConcurrentMap(); @Autowired private ObjectMapper objectMapper; @Autowired private SystemPublicMetrics systemPublicMetrics; @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { // 这边的order一定要大于org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter的order // 也就是要大于5 // 否则,RequestContext.getCurrentContext()里拿不到serviceId等数据。 return 5; } @Override public boolean shouldFilter() { // 这里可以考虑弄个限流开启的开关,开启限流返回true,关闭限流返回false,你懂的。 Collection
> metrics = systemPublicMetrics.metrics(); Optional
> freeMemoryMetric = metrics.stream() .filter(t -> "mem.free".equals(t.getName())) .findFirst(); // 如果不存在这个指标,稳妥起见,返回true,开启限流 if (!freeMemoryMetric.isPresent()) { return true; } long freeMemory = freeMemoryMetric.get() .getValue() .longValue(); // 如果可用内存小于700*1024KB,开启流控 System.out.println("-----------------------------------freeMemory="+freeMemory); return freeMemory < 700*1024L; } @Override public Object run() { try { RequestContext context = RequestContext.getCurrentContext(); String key = null; // 对于service格式的路由,走RibbonRoutingFilter String serviceId = (String) context.get(SERVICE_ID_KEY); if (serviceId != null) { key = serviceId; map.putIfAbsent(serviceId, RateLimiter.create(50)); }else { // 对于URL格式的路由,走SimpleHostRoutingFilter URL routeHost = context.getRouteHost(); if (routeHost != null) { String url = routeHost.toString(); key = url; map.putIfAbsent(url, RateLimiter.create(100)); } } RateLimiter rateLimiter = map.get(key); if (!rateLimiter.tryAcquire()) { accessTokenFail("系统繁忙,请稍后再试!"); } } catch (Exception e) { ReflectionUtils.rethrowRuntimeException(e); } return null; } /** * 请求失败 * @param message */ public void accessTokenFail(String message){ Result result = new Result(); RequestContext ctx = RequestContext.getCurrentContext(); HttpServletResponse response = ctx.getResponse(); ctx.setSendZuulResponse(false); result.setType(TypeEnum.FAIL.getCode()); result.setMessage(message); result.setTrue(false); result.setCode(TypeEnum.rateLimit.getCode()); response.setContentType("application/json;charset=UTF-8"); try { response.getWriter().write(objectMapper.writeValueAsString(result)); }catch (Exception e){ e.printStackTrace(); } }}

3、为了方便测试,在Zuul配置中添加如下配置:

#目标主机最大连接数和每个主机的初始连接数。zuul.host.max-total-connections=1000zuul.host.max-per-route-connections=500zuul.semaphore.max-semaphores=5000#设置Hystrix隔离策略为线程池zuul.ribbon-isolation-strategy=thread#每个路由使用独立的线程池zuul.thread-pool.use-separate-thread-pools=true#修改线程池中的coreSize 默认10hystrix.threadpool.default.coreSize=500

4、测试内容截图:

1、下载apache的jmeter进行测试2、在jmeter里新加测试计划:5000个请求在10秒内完成(500/s),这是我在上面配置的线程数3、启动测试(十秒内当系统freeMemory<700*1024L KB时,开启自动限流,返回‘系统繁忙’)

 

 

 

转载地址:https://dada-superman.blog.csdn.net/article/details/97784250 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:SpringCloud之Zuul自定义Fallback
下一篇:SpringCloud之Hystrix Dashboard的简单实现

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月12日 18时18分27秒