问题描述
我有简单的 SpringBoot 2.5.1 和 Tomcat 9.0.46(默认工作线程池大小 = 200)。我做了性能测试,得到了奇怪的结果。
控制器:
@GetMapping("/{code}/score")
@ResponseStatus(HttpStatus.OK)
public CompletableFuture<TeamscoreDTO> score(@PathVariable(name = "code") String teamCode) {
log.info("GET on /team/score received!");
var res = service.score(TeamCode.valueOf(teamCode));
log.info("GET on /team/score returned!");
return res;
}
申请服务:
public CompletableFuture<TeamscoreDTO> score(TeamCode teamCode) {
var parentName = Thread.currentThread().getName();
var resultAsync = CompletableFuture.supplyAsync(() -> loadTeamDetails(teamCode,parentName))
.whenComplete(handleAsyncException());
return resultAsync.whenComplete(handleAsyncException()).thenApply(it -> TeamscoreDTO.from(teamCode,it.getPosition()));
}
异步中使用的自定义线程池:
private ExecutorService detailsServicePool =
new ThreadPoolExecutor(100,100,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),MyThreadFactory.create());
响应缓慢的应用服务:
public TeamDetailsDTO get(TeamCode key,String parentThreadName) {
try {
TimeUnit.MILLISECONDS.sleep(500);
log.info("= Run with thread => "+Thread.currentThread().getName() + " parent-thread=> "+ parentThreadName);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return TeamDetailsDTO.from(TeamCode.PL,"Poland",30);
}
测试包括由 n 个客户端发送 2000 个请求(其中 n = {200,400,600,800})。
hey -n 2000 -c 400 http://localhost:8080/team/PL/score
我期望得到以下结果:
真实结果:
-
应用很慢 例如,对于 400 个连接:
延迟分布: 1.5125 秒内 10%
2.0000 秒内 25%
50% 2.0011 秒
2.0055 秒内达到 75%
2.0138 秒内达到 90%
2.0298 秒内达到 95%
在 2.1020 秒内达到 99%
-
cpu 使用率低且恒定 (~25%)
-
当 (n = {600,800}) 并非所有调用都以状态 200 结束时,这对我来说很奇怪
[200] 1800 个回复(n=600,应该是 2000)
[200] 1600 个回复(n=800,应该是 2000)
我无法获得有关其他请求发生情况的任何信息。我在日志中没有看到任何异常。
应用程序日志看起来不错,响应是异步的,在单独的线程池中调用慢速服务。
如此糟糕的表现可能是什么原因?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)