我有一台用Java编写的服务器,该服务器具有在Tomcat下运行的Spring MVC(Spring BOOT)。我们注意到有些客户端正在发送带有内容长度标头但没有实体主体的POST请求。当该请求到达时,请求挂起20秒,然后服务器返回响应(400)。
附加分析器显示挂起的服务器线程具有以下堆栈。
“ http-nio-31114-exec-4”#52守护程序prio = 5 os_prio = 31 tid = 0x00007fc26e6b6000 nid = 0x9f03等待条件[0x0000700010a1f000] java.lang.Thread.State:TIMED_WAITING(停车) 在sun.misc.Unsafe.park(本机方法) -停车等待(java.util.concurrent.CountDownLatch $ Sync) 在java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 在java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1037) 在java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1328) 在java.util.concurrent.CountDownLatch.await(CountDownLatch.java:277) 在org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.awaitLatch(NioEndpoint.java:1106) 在org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.awaitReadLatch(NioEndpoint.java:1108) 在org.apache.tomcat.util.net.NioBlockingSelector.read(NioBlockingSelector.java:184) 在org.apache.tomcat.util.net.NioSelectorPool.read(NioSelectorPool.java:235) 在org.apache.tomcat.util.net.NioSelectorPool.read(NioSelectorPool.java:216) 在org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1233) 在org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.read(NioEndpoint.java:1182) 在org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:713) 在org.apache.coyote.http11.Http11InputBuffer.access $ 300(Http11InputBuffer.java:40) 在org.apache.coyote.http11.Http11InputBuffer $ SocketInputBuffer.doRead(Http11InputBuffer.java:1063) 在org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:140) 在org.apache.coyote.http11.Http11InputBuffer.doRead(Http11InputBuffer.java:257) 在org.apache.coyote.Request.doRead(Request.java:541) 在org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:326) 在org.apache.catalina.connector.InputBuffer.checkByteBufferEof(InputBuffer.java:634) 在org.apache.catalina.connector.InputBuffer.readByte(InputBuffer.java:337) 在org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:93) 在java.io.FilterInputStream.read(FilterInputStream.java:83) 在java.io.PushbackInputStream.read(PushbackInputStream.java:139) 在org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver $ EmptyBodyCheckingHttpInputMessage。(AbstractMessageConverterMethodArgumentResolver.java:319) 在org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:192) 在org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:157) 在org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:130)处 在org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124) 在org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) 在org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131) 在org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) 在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) 在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) 在org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) 在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) 在org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) 在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) 在org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:707) 在org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) 在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) 在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter.doFilter(ExceptionLoggingFilter.java:48) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在brave.servlet.TracingFilter.doFilter(TracingFilter.java:61) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:130) 在org.springframework.boot.web.servlet.support.ErrorPageFilter.access $ 000(ErrorPageFilter.java:66) 在org.springframework.boot.web.servlet.support.ErrorPageFilter $ 1.doFilterInternal(ErrorPageFilter.java:105) 在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:123) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) 在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) 在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) 在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) 在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) 在org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) 在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 在com.fabrikam.valve.RequestTraceValve.lambda $ invoke $ 0(RequestTraceValve.java:41) 在com.fabrikam.valve.RequestTraceValve $$ Lambda $ 423 / 855335917.accept(未知来源) 在com.fabrikam.tomcat.request.trace.RequestTraceInitializer.invoke(RequestTraceInitializer.java:140) 在com.fabrikam.valve.RequestTraceValve.invoke(RequestTraceValve.java:39) 在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) 在org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) 在org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 在org.apache.coyote.AbstractProtocol $ ConnectionHandler.process(AbstractProtocol.java:861) 在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1455) 在org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) -锁定(org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) 在org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61) 在java.lang.Thread.run(Thread.java:745)
该servlet看起来像这样:
@CrossOrigin @RequestMapping(path =“ / event / {apikey} / {anonymousId}”,方法= RequestMethod.POST,产生=“ application / json”) 公共无效clickRawPost( @PathVariable String apikey, @PathVariable字符串onymousId, @RequestBody(required = false)字符串postContent, HttpServletRequest请求, HttpServletResponse响应) 引发IOException {
repro命令如下:
$ time curl -s http://localhost:8080/event/test/foo -H'内容类型: application / json'-H'内容长度:100'-X POST -v
此命令在20秒后超时。
我期望它很快就会失败,因为请求中没有实体。