Spring 开机休息控制器反应很慢
Spring boot rest controller pretty slow repsonse
你好堆栈溢出社区。我正在使用 Spring 引导,它对我来说工作得很好,但是当涉及到 "large" 数据集时,它变得非常慢,让我给你看一个示例代码:
@GetMapping("/get/some/example/data/{lines}")
public ResponseEntity<String> getTestData(@PathVariable("lines") long lines) {
StringBuilder stringBuilder = new StringBuilder();
for(int i=0; i<lines; i++){
stringBuilder.append("...very long string here...");
}
return ResponseEntity.ok(stringBuilder.toString());
}
好的,您看到的只是一个非常简单的 rest 控制器,用于生成动态大小的响应。
假设 stringBuilder.append() 中的字符串是 500 个字符或更多。
现在让我们用浏览器调用这个端点并用 chrome 的 DevTools(F12) 观察结果:
响应Headers:
Content-Encoding: gzip
Content-Type: text/html;字符集=UTF-8
Transfer-Encoding:分块
变化:accept-encoding
线路 = 100 的调用端点:
- 419 KB 资源
- 完成 377 毫秒(+- 50 毫秒...)
线路 = 1000 的调用端点:
- 3.0 MB 资源
- 完成 2108000 毫秒(+- 3000 毫秒)
让我们比较一下这些结果。好吧,由于 gzip 压缩,资源大小不是精确的 10 倍。
但我的问题是响应时间。 10 倍的数据需要 377ms 和 210800ms。
这意味着 10 倍的数据需要 559 倍的时间。
可以看到没有数据库连接,也没有复杂的代码。 1000 次迭代的 for 循环耗时不到 5 毫秒,因此问题出在幕后或 HTTP 中。
你能帮我理解为什么大量数据对性能的影响如此之大吗?能否请您帮助找到改善响应时间的解决方案。
另外,在headers中可以看到mime类型"Content-Type: text/html",当这个改成application/json时,虽然快了,但还是不快。
另请参阅此处的请求 headers:
接受:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,es-VE;q=0.8,es;q=0.7,en-US;q=0.6,en ;q=0.5
Cache-Control: no-cache
连接:keep-alive
主持人:localhost:8080
编译指示:no-cache
Sec-Fetch-Mode: 导航
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如 Gecko)
Chrome/79.0.3945.130 Safari/537.36
依赖项:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.0.RELEASE</version>
...
非常感谢任何提示和建议。
我刚刚发现根本没有性能问题。我刚刚安装了 Postman 来检查它是否相同。不,不是,Postman 和 Firefox DevTools 告诉我它非常快。出于某种原因,我最喜欢的浏览器 chrome 在处理大量数据时速度变慢了。
信不信由你,在 firefox 和 chrome 上相同的请求对于 14.41 MB 的响应大约需要 223 毫秒,而在 chrome 上大约需要 23000 毫秒......
但这仅适用于开放式构建工具,因此当您观看时
你会在没有 gzip 的情况下尝试相同的代码吗? (server.compresstion.enabled=false
)
或者通过覆盖 tomcat 的 GzipOutputFilter
class 来降低 gzip 压缩级别? (默认压缩级别为 6,将其降低至 BEST_SPEED
)
你好堆栈溢出社区。我正在使用 Spring 引导,它对我来说工作得很好,但是当涉及到 "large" 数据集时,它变得非常慢,让我给你看一个示例代码:
@GetMapping("/get/some/example/data/{lines}")
public ResponseEntity<String> getTestData(@PathVariable("lines") long lines) {
StringBuilder stringBuilder = new StringBuilder();
for(int i=0; i<lines; i++){
stringBuilder.append("...very long string here...");
}
return ResponseEntity.ok(stringBuilder.toString());
}
好的,您看到的只是一个非常简单的 rest 控制器,用于生成动态大小的响应。 假设 stringBuilder.append() 中的字符串是 500 个字符或更多。
现在让我们用浏览器调用这个端点并用 chrome 的 DevTools(F12) 观察结果:
响应Headers:
Content-Encoding: gzip
Content-Type: text/html;字符集=UTF-8
Transfer-Encoding:分块
变化:accept-encoding
线路 = 100 的调用端点:
- 419 KB 资源
- 完成 377 毫秒(+- 50 毫秒...)
线路 = 1000 的调用端点:
- 3.0 MB 资源
- 完成 2108000 毫秒(+- 3000 毫秒)
让我们比较一下这些结果。好吧,由于 gzip 压缩,资源大小不是精确的 10 倍。 但我的问题是响应时间。 10 倍的数据需要 377ms 和 210800ms。 这意味着 10 倍的数据需要 559 倍的时间。
可以看到没有数据库连接,也没有复杂的代码。 1000 次迭代的 for 循环耗时不到 5 毫秒,因此问题出在幕后或 HTTP 中。 你能帮我理解为什么大量数据对性能的影响如此之大吗?能否请您帮助找到改善响应时间的解决方案。
另外,在headers中可以看到mime类型"Content-Type: text/html",当这个改成application/json时,虽然快了,但还是不快。
另请参阅此处的请求 headers: 接受: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,es-VE;q=0.8,es;q=0.7,en-US;q=0.6,en ;q=0.5
Cache-Control: no-cache
连接:keep-alive
主持人:localhost:8080
编译指示:no-cache
Sec-Fetch-Mode: 导航
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如 Gecko)
Chrome/79.0.3945.130 Safari/537.36
依赖项:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.0.RELEASE</version>
...
非常感谢任何提示和建议。
我刚刚发现根本没有性能问题。我刚刚安装了 Postman 来检查它是否相同。不,不是,Postman 和 Firefox DevTools 告诉我它非常快。出于某种原因,我最喜欢的浏览器 chrome 在处理大量数据时速度变慢了。 信不信由你,在 firefox 和 chrome 上相同的请求对于 14.41 MB 的响应大约需要 223 毫秒,而在 chrome 上大约需要 23000 毫秒...... 但这仅适用于开放式构建工具,因此当您观看时
你会在没有 gzip 的情况下尝试相同的代码吗? (server.compresstion.enabled=false
)
或者通过覆盖 tomcat 的 GzipOutputFilter
class 来降低 gzip 压缩级别? (默认压缩级别为 6,将其降低至 BEST_SPEED
)