所以,
最近我开始使用非阻塞的异步servlet(Servlet 3.1)。据我了解, 通过使用异步servlet,可以在非阻塞时释放工作线程 正在进行操作,所以基本上没有一个线程被阻塞。所以我开始做一些 使用Gatling stress tol进行负载测试,我使用Spring RestController创建两个简单的控制器 - 一个人使用RestTemplate(Spring的HTTP客户端)进行阻塞HTTP,一个人进行非阻塞 请求使用AsyncRestTemplate并在处理带回调的消息后,请遵循以下内容:
@RequestMapping("/non-blocking")
public DeferredResult<String> nonBlocking() throws IOException {
DeferredResult<String> deferredResult = new DeferredResult<String>();
AsyncRestTemplate restTemplate = new AsyncRestTemplate();
String URL ="http://localhost:8080/static.html";
HttpMethod method = HttpMethod.GET;
Class<String> responseType = String.class;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
HttpEntity<String> requestEntity = new HttpEntity<String>("params", headers);
ListenableFuture<ResponseEntity<String>> future = restTemplate.exchange(URL, method, requestEntity, responseType);
future.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
@Override
public void onSuccess(ResponseEntity<String> result) {
deferredResult.setResult(result.getBody());
}
@Override
public void onFailure(Throwable ex) {
System.out.println("Failure while processing");
}
});
return deferredResult;
}
@RequestMapping("/blocking")
public String blockingRouter() {
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
LOG.logStartBlocking();
try {
ResponseEntity<String> result = restTemplate.getForEntity("http://localhost:8080/static.html");
status = result.getStatusCode();
return result.getBody();
} finally {
System.out.println("Processing done");
}
}
所以,你可以看到非阻塞正在返回DefferedResult(Spring的Future抽象),如果我 在发送HTTP请求之后,应该释放线程并释放一些(可能)其他线程 当它可用时会返回响应。好吧,在对200个并发用户进行了一些负载测试之后,测试对于非阻塞版本来说非常错误。线程很好,但是在达到400 req / s时,控制器刚刚停止返回响应 - 它被卡住,可能是因为响应时间太长。阻止一个用cca 1000 req / s响应所有请求。所以问题是我做了一个很好的测试或错过了什么,因为结果对我来说完全出乎意料。使用的服务器是具有50个线程的Tomcat(+ NIO连接器) - 希望证明非阻塞不会使用很多线程直到最后到达并且阻塞将因线程耗尽而失败,但它没有发生。有什么建议吗?
提前致谢。