标签:令牌 实现 springcloud 算法 限流 new import public
在高并发中,限流是必不可少的一个环节,如何使用springcloud-zuul实现限流,限流的实现最重要在于算法,常见的限流算法包
括了漏桶算法及令牌桶算法。
漏桶算法
漏桶这个名字就很形象,算法内部有一个容器,类似于漏斗。进来的请求类似于加水,不管倒入的水流量多大,下面出去的水流量很稳定。
不管服务调用方多么不稳定,通过漏桶算法进行限流,每隔固定的时间处理一次请求。因为处理请求的速率固定,所以新加入的请求会被放
置在桶中,等待下一次请求处理,若桶已经放满,则丢弃要加入的请求。
令牌桶算法
令牌桶算法中,有一个桶,算法按照一定的速率向桶中添加令牌,拿到了令牌的请求才能被处理。若请求没有拿到令牌则等待可用的令牌,或者
直接拒绝。若桶中令牌数量达到了上线,就丢弃令牌。
springcloudGateWay实现限流
GoogleGuava提供了限流工具类RateLimiter,如下编写一个pre类型的filter,适用于单zuul节点的情况。
import com.google.common.util.concurrent.RateLimiter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletResponse; @Component public class RateLimitZuulFilter extends ZuulFilter { //同一時刻允許請求的個數 3個 private RateLimiter rateLimiter = RateLimiter.create(2); @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return Ordered.HIGHEST_PRECEDENCE; } @Override public boolean shouldFilter() { //可以考慮弄個開關 return true; } @Override public Object run() throws ZuulException { RequestContext requestContext = RequestContext.getCurrentContext(); HttpServletResponse response = requestContext.getResponse(); if(!rateLimiter.tryAcquire()){//超过设置的请求个数 HttpStatus tooManyRequests = HttpStatus.TOO_MANY_REQUESTS; response.setContentType(MediaType.TEXT_PLAIN_VALUE); response.setStatus(tooManyRequests.value()); requestContext.setSendZuulResponse(false); throw new ZuulException(tooManyRequests.getReasonPhrase(),tooManyRequests.value(),tooManyRequests.getReasonPhrase()); } return null; } }
编写测试类,模仿http请求访问某个服务。
public class HttpRequest { public static void main(String[] args)throws Exception { Thread []thread = new Thread[10]; for(int i = 0;i < 10;i++){ thread[i] = new Thread(()->{ try{ URI url = new URI("http://localhost:9527/menbbo/springcloudzuul/index"); SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory(); ClientHttpRequest request = simpleClientHttpRequestFactory.createRequest(url, HttpMethod.POST); ClientHttpResponse execute = request.execute(); InputStream body = execute.getBody(); InputStreamReader ins = new InputStreamReader(body); BufferedReader bufferedReader = new BufferedReader(ins); String s = ""; while ((s=bufferedReader.readLine())!=null){ System.out.println(s); } } catch (Exception e){ e.printStackTrace(); } }); } for(int i =0;i<10;i++){ thread[i].start(); } } }
结果如下:
调用成功3次,其他被过滤掉。
源码地址:https://gitee.com/menbbo/springclouddemo.git
标签:令牌,实现,springcloud,算法,限流,new,import,public 来源: https://www.cnblogs.com/menbo/p/13881998.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。