Spring MVC зависает при запросе POST с заголовком Content-Length, но без тела POST - PullRequest
0 голосов
/ 15 октября 2018

У меня есть сервер, написанный на Java с Spring MVC (Spring BOOT), работающий под Tomcat.Мы замечаем, что некоторые клиенты отправляют запрос POST с заголовком длины содержимого, но без тела объекта.Когда этот запрос приходит, запрос зависает на 20 секунд, а затем с сервера возвращается ответ (400).

Прикрепление профилировщика показывает, что зависший поток сервера имеет следующий стек.

"http-nio-31114-exec-4" # 52 демон prio = 5 os_prio = 31 tid = 0x00007fc26e6b6000 nid = 0x9f03 ожидание при условии [0x0000700010a1f000] java.lang.Thread.State: TIMED_WAITisc (стоянка) в sun.mUnsafe.park (собственный метод) - парковка для ожидания (java.util.concurrent.CountDownLatch $ Sync) в java.util.concurrent.locks.LockSupport.parkNanos (LockSupport.java:215) в java.util.concurrent.Замки.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.uelectorPolNioSelectorPool.java:235) в org.apache.tomcat.util.net.NioSelectorPool.read (NioSelectorPool.java:216) в org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.fillReadBuffer.javaE: NioSв org.apache.tomcat.util.net.NioEndpoint $ NioSocketWrapper.read (NioEndpoint.java:1182) в org.apache.coyote.http11.Http11InputBuffer.fill (Http11InputBuffer.java:713) в org.apt.ht.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.InffByffer (InbuBu)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 (InvocableDandjetM:по адресу org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle (ServletInvocableHandlerMethod.java:102) по адресу org.springframework.web.servlet.mvc.aphв org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal (RequestMappingHandlerAdapter.java:783) в org.springframework.web.servlet.mvc.method.AbstractHandlerMethog.springframework.web.servlet.DispatcherServlet..java: 974) в org.springframework.web.servlet.FrameworkServlet.doPost (FrameworkServlet.java:877) в javax.servlet.http.HttpServlet.service (HttpServlet.java:707) в org.springframe.b.servlet.FrameworkServlet.service (FrameworkServlet.java:851) по адресу javax.servlet.http.HttpServlet.service (HttpServlet.java:790) по адресу org.apache.catalina.core.ApplicationFilterChain.internalFilterFilter (2по адресу org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) по адресу org.springframework.web.filter.RequestContextFilter.doFilterInternal (RequestContextFilter.java:99.ReililOF)(OncePerRequestFilter.java:107) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193) в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilg.web.filter.HttpPutFormContentFilter.doFilterInternal (HttpPutFormContentFilter.java:109) в org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:10apil.Filter.Filter.Filter.FlF.FF).erChain.java:193) в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) в org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal (HavahodFilter).filter.) в org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter.doFilter (ExceptionLoggingFilter.java:48) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.jinag):core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) в brave.servlet.TracingFilter.doFilter (TracingFilter.java:61) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter: atFilter (ApplicationFilter) в приложении.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) в org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter (ErrorPageFilter.java:130) в org.springfrabebowork.ErrorPageFilter.access $ 000 (ErrorPageFilter.java:66) по адресу org.springframework.boot.web.servlet.support.ErrorPageFilter $ 1.doFilterInternal (ErrorPageFilter.java:105) по адресу org.springframework.web.filterFJava: 107) в org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter (ErrorPageFilter.java:123) в org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChaache.j)).catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)по адресу org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:200) по адресу org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.in.hain.Finter.Fineter.Cat.F:(ApplicationFilterChain.java:193) в org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) в org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValache.jav.j).catalina.core.StandardContextValve.invoke (StandardContextValve.java:96) в org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:478) в org.apache.catalina.core.StandardHVOve140) в org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:80) в org.apache.catalina.valves.AbstractAccessLogValve.invoke (AbstractAccessLogValve.java:624) в org.apache.inealvec..invoke (StandardEngineValve.java:87)t com.fabrikam.valve.RequestTraceValve.lambda $ invoke $ 0 (RequestTraceValve.java:41) в com.fabrikam.valve.RequestTraceValve $$ Lambda $ 423 / 855335917.accept (неизвестный источник) в com.fabrikam.tomcat.request.tra.RequestTraceInitializer.invoke (RequestTraceInitializer.java:140) в com.fabrikam.valve.RequestTraceValve.invoke (RequestTraceValve.java:39) в org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapg).apache.coyote.http11.Http11Processor.service (Http11Processor.java:799) в org.apache.coyote.AbstractProcessorLight.process (AbstractProcessorLight.java:66) в org.apache.coyote.AbstractProtocol $ ConnectionHandler.cess $ (Abstract Abstract Protocol):861) в org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun (NioEndpoint.java:1455) в org.apache.tomcat.util.net.SocketProcessorBase.run (SocketProcessorBase.java:49) - заблокировано (aorg.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)

Сервлет выглядит следующим образом:

@CrossOrigin @RequestMapping (path = "/ event / {apikey} / {anonymousId}", method = RequestMethod.POST,производит = "application / json") public void clickRawPost (@PathVariable String apikey, @PathVariable String anonymousId, @RequestBody (обязательно = false) Строка postContent, запрос HttpServletRequest, ответ HttpServletResponse) выдает команду IOException {0 * 100 *выглядит следующим образом:

$ time curl -s http://localhost:8080/event/test/foo -H 'тип контента: application / json' -H 'длина контента: 100' -X POST -v

Время ожидания этой команды составляет 20 с.

Я ожидал, что она очень быстро потерпит неудачу, поскольку в запросе нет тела объекта.

...