Micronaut背压

问题描述

我们正在寻找最好的方法来限制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级别实施,则会影响整个应用程序。