如何使用WebClient限制请求/秒? [英] How to limit the request/second with WebClient?

查看:131
本文介绍了如何使用WebClient限制请求/秒?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用WebClient对象将Http Post请求发送到服务器. 它正在迅速发送大量请求(QueueChannel中大约有4000条消息).问题是...服务器似乎无法足够快地响应...所以我收到很多服务器错误500,并且过早关闭了连接.

I'm using a WebClient object to send Http Post request to a server. It's sending a huge amount of requests quite rapidly (there is about 4000 messages in a QueueChannel). The problem is... it seems the server can't respond fast enough... so I'm getting a lot of server error 500 and connexion closed prematurely.

是否有一种方法可以限制每秒的请求数?还是限制它正在使用的线程数?

Is there a way to limit the number of request per seconds ? Or limit the number of threads it's using ?

Message端点在QueueChannel中处理消息:

The Message endpoint processe message in a QueueChannel :

@MessageEndpoint
public class CustomServiceActivator {

    private static final Logger logger = LogManager.getLogger();

    @Autowired
    IHttpService httpService;

    @ServiceActivator(
            inputChannel = "outputFilterChannel",
            outputChannel = "outputHttpServiceChannel",
            poller = @Poller( fixedDelay = "1000" )
    )
    public void processMessage(Data data) {
        httpService.push(data);
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

WebClient服务类:

The WebClient service class :

@Service
public class HttpService implements IHttpService {

    private static final String URL = "http://www.blabla.com/log";

    private static final Logger logger = LogManager.getLogger();

    @Autowired
    WebClient webClient;

    @Override
    public void push(Data data) {
        String body = constructString(data);
        Mono<ResponseEntity<Response>> res = webClient.post()
                .uri(URL + getLogType(data))
                .contentLength(body.length())
                .contentType(MediaType.APPLICATION_JSON)
                .syncBody(body)
                .exchange()
                .flatMap(response -> response.toEntity(Response.class));

        res.subscribe(new Consumer<ResponseEntity<Response>>() { ... });
    }
}

推荐答案

问题限制率使用Reactor的请求提供了两个答案(一个在注释中)

Question Limiting rate of requests with Reactor provides two answrers (one in comment)

zip使用另一个充当速率限制器的流量

.zipWith(Flux.interval(Duration.of(1,ChronoUnit.SECONDS)))

.zipWith(Flux.interval(Duration.of(1, ChronoUnit.SECONDS)))

仅延迟每个Web请求

使用 delayElements 函数

编辑:下面的答案对于阻止RestTemplate有效,但并不完全适合被动模式.

edit: answer below is valid for blocking RestTemplate but do not really fit well into reactive pattern.

WebClient没有限制请求的功能,但是您可以使用合成功能轻松添加此功能.

WebClient does not have ability to limit request, but you could easily add this feature using composition.

您可以使用Guava/的RateLimiter从外部限制您的客户端 ( https://google.github.io/guava/releases/19.0/api/docs/index.html?com/google/common/util/concurrent/RateLimiter.html )

You may throttle your client externally using RateLimiter from Guava/ (https://google.github.io/guava/releases/19.0/api/docs/index.html?com/google/common/util/concurrent/RateLimiter.html)

在本教程中, http://www.baeldung.com/guava-rate-limiter您将找到如何以阻塞方式或超时使用速率限制器.

In this tutorial http://www.baeldung.com/guava-rate-limiter you will find how to use Rate limiter in blocking way, or with timeouts.

我会装饰所有需要在单独的类中限制的呼叫

I would decorate all calls that need to be throttled in separate class that

  1. 限制每秒的通话次数
  2. 使用WebClient进行实际的网络通话

这篇关于如何使用WebClient限制请求/秒?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆