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条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS6,CentOS7官方镜像安装Oracle11G
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2全家桶,快速入门学习开发网站教程