Spring端点接收到较大的HTTP请求时收到截断的主体。

huangapple go评论60阅读模式
英文:

Spring endpoint receives truncated body for larger http requests

问题

I have a component, deployed in an EC2-instance on AWS, which will fail 'randomly' (~70% of the request) when sending a larger payload (40k).

Sending the request is done using Postman. Sending the same request over and over again (with same delay in between or just as quickly as I can), every time I get a few failures, then a success (sometimes 2 in a row, then some failures, repeat).

It's a Java Spring Boot application, the controller-snippet:

@PostMapping
@RequestMapping("/some/url")
ResponseEntity<MyClass> methodName(@RequestBody String data, @RequestHeader("content-length") String header) {

        log.info("Content-Length header was: "+header);
        log.info("Length of inputJson (@RequestBody) was: "+data.length());
        log.info(inputJson);

For every request (failed or successful) I get the same value for the content-length-header.
The data-length is either the same (successful call) or shorter (failed call).

I added some logging as above, which seems to prove that the data received is actually truncated.

I enabled access-log using:

server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %{content-length}i %{Content-Length}i

The access-log shows the same value as the content-length-header.

Looking around I found several articles, none with an answer that I could use.
Considering this also succeeds 30% (or with smaller requests) I figure the code itself is probably fine.
Just out of ideas on what to change next to investigate this further.

Some related links which did not help my problem (which might help others):

英文:

I have a component, deployed in an EC2-instance on AWS, which will fail 'randomly' (~70% of the request) when sending a larger payload (40k).

Sending the request is done using Postman. Sending the same request over and over again (with same delay in between or just as quickly as i can), every time i get a few failures, then a success (sometimes 2 in a row, then some failures, repeat)

It's a Java Spring Boot application, the controller-snippet:

	@PostMapping
	@RequestMapping(&quot;/some/url&quot;)
	ResponseEntity&lt;MyClass&gt; methodName(@RequestBody String data, @RequestHeader(&quot;content-length&quot;) String header) {

        log.info(&quot;Content-Length header was: &quot;+header);
        log.info(&quot;Length of inputJson (@RequestBody) was: &quot;+data.length());
        log.info(inputJson);

For every request (failed or successful) i get the same value for the content-length-header.
The data-length is either the same (successful call) or shorter (failed call).

I added some logging as above, which seems to prove that the data-received is actually truncated.

I enabled access-log using

server.tomcat.accesslog.pattern=%h %l %u %t &quot;%r&quot; %s %b %{content-length}i %{Content-Length}i

The access-log shows the same value as the content-length-header.

Looking around I found several articles, none with an answer that i could use.
Considering this also succeeds 30% (or with smaller requests) i figure the code itself is probably fine.
Just out-of-ideas on what to change next to investigate this further.

Some related links which did not help my problem (which might help others):

答案1

得分: 8

在我们的情况下,我们遇到了一个类似的问题,即请求会随机截断(约10-20%)。相同的应用程序版本部署在多个环境中。问题只存在于某些环境中。我们尝试通过以下方式复现问题:

  • 将应用程序API端点从HTTPS更改为HTTP,没有任何问题。我们还将ALB的后端协议从HTTPS更改为HTTP。
  • 尝试从本地主机访问HTTPS端点。问题不存在。

后来,我们检查了已部署的应用程序服务器。我们在Spring Boot应用程序中使用的是嵌入式Tomcat,版本为9.0.31。
已知此版本的Tomcat在处理HTTPS上的负载时存在问题。
通过在pom.xml中明确定义版本,将Tomcat版本更改为9.0.30后,问题得以解决。

相关链接以便对他人有所帮助:

英文:

In our case, we faced a similar issue where requests were getting truncated randomly(~ 10-20%). The same application version was deployed across multiple environments. The issue was present in only some environments. We tried to reproduce the issue by doing the following:

  • Changing the application API endpoint from HTTPS to HTTP, there wasn't any issue. We also changed the backend protocol of the ALB from HTTPS to HTTP.
  • Tried hitting the HTTPS endpoint from the localhost. The issue was not present.

Later on we checked the application server that was in place. We were using embedded tomcat in the spring boot application which was 9.0.31.
This version of tomcat is known to have issues with payload over HTTPS.
Changing the tomcat version to 9.0.30 by explicitly defining this version in the pom.xml resolved the issue for us.

Related links so that this may help others:

答案2

得分: 1

对于那些遇到类似问题的人,帮助我们解决这个问题的方法是由AWS进行的配置更改。他们使用了更大的节点来处理AWS应用负载均衡器。
撤销这个更改重新引入了问题。

这是我们自己无法执行的配置更改。
AWS仍在努力找出根本原因。

有一个提示有助于复现/定位问题:

  • 当从EC2机器向自身发出(curl-)请求时,请求总是成功的。
  • 当从另一个EC2机器向暴露的端点发出(curl-)请求(从而命中负载均衡器)时,再次出现了失败。
  • 这有助于证明问题存在于AWS堆栈内部,而不是代码问题,也不是我的客户端/网络问题。
英文:

For those having a similar problem, the fix that helped us with this was a configuration change made by AWS. They used bigger nodes for the AWS Application LoadBalancer.
Rolling that change back re-introduced the issue.

This is a config-change we could not do ourselves.
AWS is still figuring out the root-cause.

One pointer that helped to reproduce / pinpoint:

  • when making a (curl-)request from the EC2-machine to itself, the request always passed.
  • when making a (curl-)request from another EC2-machine towards the exposed endpoints (and by doing so hitting the LoadBalancer) the failures occurred again.
  • This helped to proof the issue was within the AWS-stack, not a code-issue, not a network-issue on my client/network.

huangapple
  • 本文由 发表于 2020年7月31日 18:46:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63190403.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定