【发布时间】:2017-01-26 16:00:56
【问题描述】:
我们有一个比较特殊的情况,我们需要与外部 API 交互,这需要我们长时间轮询他们的端点以获取他们所谓的实时事件。
问题是我们可能有多达 80,000 人/设备在任何给定时间访问此端点,监听事件,每个设备/人 1 个连接。
当客户端从我们的 Spring 服务发出长轮询事件的请求时,我们的服务会依次对外部 API 进行异步调用以长轮询事件。外部 API 已定义 minimum 长轮询超时可设置为 180 秒。
所以在这里我们遇到了一个带有队列的线程池将无法工作的情况,因为如果我们有一个线程池具有类似(5 min,10 max,10 queue)的东西,那么正在工作的 10 个线程可能会占用在当前 10 个中的一个完成之前,聚光灯和队列中的 10 个将没有机会。
我们需要服务或失败(我们将在其后面放置负载平衡器等),但我们不希望在没有实际轮询发生的情况下让客户端挂起。
我们一直在研究为此使用 DeferredResult,并从控制器返回。
有什么好调的
@RequestMapping(value = "test/deferredResult", method = RequestMethod.GET)
DeferredResult<ResponseEntity> testDeferredResult() {
final DeferredResult<ResponseEntity> deferredResult = new DeferredResult<ResponseEntity>();
CompletableFuture.supplyAsync(() -> testService.test()).whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));
return deferredResult;
}
我在质疑我是否走在正确的道路上,我是否应该为CompletableFuture.supplyAsync() 方法提供一个执行器以及什么样的执行器(和配置)才能最好地完成我们的任务。
我已经阅读了各种文章、帖子等,我想看看是否有人有任何知识可能有助于我们的具体情况。
【问题讨论】:
-
也许你可以给一个机会来vert'x?它有非常好的异步支持