问题描述
我们正在寻找最好的方法来限制Micronaut 2.0.1公开的HTTP端点接受的并发连接数。端点接受图像文件,将它们写入磁盘并创建缩略图。请求过多,我们的内存不足。
到目前为止,我们发现的是 settings for Netty thread pools 。尽管我们怀疑这些是否可以使我们强制执行特定的限制。他们似乎与Netty事件循环线程池有更多关系?
有没有像Micronaut和Netty这样的行之有效的背压方法?
解决方法
没有开箱即用的配置可以强制执行您想要的并发限制。您可能希望实现一个HttpServletFilter来跟踪当前正在执行的请求的数量,并在数量超过配置的限制时以状态429 Too Many Requests
进行响应。类似于以下代码的东西应该可以工作(注意:未经测试)
@Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request,ServerFilterChain chain) {
return Flowable.fromCallable(() -> atomicRequestCounter.incrementAndGet())
.subscribeOn(Schedulers.computation())
.flatMap(numConcurrentRequests -> {
if (numConcurrentRequests > MAX_ALLOWED_CONCURRENCY) {
return Flowable.just(HttpResponse.status(HttpStatus.TOO_MANY_REQUESTS));
} else {
return chain.proceed(request);
}
})
.doOnNext(res -> atomicRequestCounter.decrementAndGet());
}
如果您真的想将其插入Netty层,请查看ChannelPipelineCustomizer。您可以应用与上述相同的原理,并在管道中添加一个处理程序,以跟踪并发连接。请注意,基于过滤器的方法的优势在于,它允许您对特定的URI /资源实施限制,而如果在Netty级别实施,则会影响整个应用程序。