java版spring cloud+spring boot 社交电子商务平台--Spring cloud gateway限流
限流一般有两个实现方式,令牌桶和漏桶。
金牌桶是初始化令牌(容器)的个数,通过拿走里边的令牌就能通过, 没有令牌不能报错,可以设置向容器中增加令牌的速度和最大个数
漏桶是向里边放入请求,当请求数量达到最大值后,丢弃,漏桶中的数据以一定速度流出,没有则不流出
金牌桶实现方式如下:
pom
<dependency> <groupId>com.github.vladimir-bukhtoyarov</groupId> <artifactId>bucket4j-core</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>
创建下边类并且继承下边类
public class LimitFilter implements GatewayFilter, Ordered { private final Logger logger = LoggerFactory.getLogger(LimitFilter.class); int capacity; int refillTokens; Duration refillDuration; public LimitFilter(int capacity, int refillTokens, Duration refillDuration) { this.capacity = capacity; this.refillTokens = refillTokens; this.refillDuration = refillDuration; } private static final Map<String,Bucket> CACHE = new ConcurrentHashMap<>(); private Bucket createNewBucket() { Refill refill = Refill.of(refillTokens,refillDuration); Bandwidth limit = Bandwidth.classic(capacity,refill); return Bucket4j.builder().addLimit(limit).build(); } @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress(); Bucket bucket = CACHE.computeIfAbsent(ip,k -> createNewBucket()); logger.info("IP: " + ip + ",TokenBucket Available Tokens: " + bucket.getAvailableTokens()); if (bucket.tryConsume(1)) { return chain.filter(exchange); } else { exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS); return exchange.getResponse().setComplete(); } } @Override public int getOrder() { return 0; } }
配置路由
@Bean public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) { // @formatter:off return builder.routes() .route(r -> r.path("/consulserver/**") .filters(f -> f.stripPrefix(1) .filter(new LimitFilter(10,1,Duration.ofSeconds(1)))) .uri("lb://consulserver") .order(0) .id("throttle_customer_service") ).build(); // @formatter:on }
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Python的C/C++扩展——Python的C语言接口
Python语言最初是用C语言实现的一种脚本语言,后来被称为CPython,是因为后来又有其它语言实现的Python,比如Python实现的Python——PyPy,Java语言实现的Python——Jython,.Net实现的Python——IronPython。 CPython具有优良的开放性和可扩展性,并提供了方便灵活的应用程序接口(API),从而使得C/C++程序员能够在各个级别上对Python解释器的功能进行扩展。 Python的C语言接口很适合封装C语言实现的各种函数,如果要封装C++的类,使用boost_python或者SWIG更方便和合适。 1 模块封装 假设我们有一个C函数: /* 文件名: mylib.c */ int addone(int a) { return a+1; } 如果想在Python解释器中调用该函数,则应该首先将其实现为Python中的一个模块,这需要编写相应的封装接口,如下所示: /* wrap_mylib.c */ #include <Python.h> #include "mylib.h" PyObject* wrap_addon...
- 下一篇
Python用ctypes调用动态库的方式使用科大讯飞语音识别
ctypes 是 Python 的一个模块,它提供了C语言相关的数据类型,可以方便的调用C语言编写的DLL(Windows 动态链接库)和so(Linux动态链接库)。科大讯飞的语音识别客户端SDK提供了Linux下的C语言SDK,却没有Python的。有了ctypes,我们就可以很轻松的用Python来使用科大讯飞的语音识别了。 通过LoadLibrary()函数加载动态库: xflib = ctypes.cdll.LoadLibrary('msc/libmsc.so') 在Python里面调用C函数时主要是注意参数的类型。语音识别的接口的具体参数可以参考其提供的文档,比如接口函数: const char* MSPAPI QISRSessionBegin( const char* grammarList, const char* params, int* errorCode ) 返回的是一个char指针作为sessionID以供后续接口作为参数使用,在Python里面要用ctypes.c_voidp类型: ret = ctypes.c_int() sessionId = ctypes...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL8.0.19开启GTID主从同步CentOS8
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Hadoop3单机部署,实现最简伪集群