Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Cloud Gateway MVC produces OOM when uploading large files #3479

Open
rpajdak opened this issue Jul 29, 2024 · 1 comment
Open

Spring Cloud Gateway MVC produces OOM when uploading large files #3479

rpajdak opened this issue Jul 29, 2024 · 1 comment

Comments

@rpajdak
Copy link

rpajdak commented Jul 29, 2024

Spring Boot 3.2.3, Spring Cloud Gateway MVC 4.4

After migration from ZuulProxy to Spring Cloud Gateway MVC in my application i am encountering an OutOfMemory error when I send a JSON file of approximately 200MB or more to my backend service. This issue does not occur when I switch to Spring Cloud Gateway for testing purposes, but I cannot make this switch in a production environment because I rely on a library provided by a client that does not support WebFlux.

This is my configuration:

spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: my-service
          uri: lb://my-service
          predicates:
            - Path=/upload/**
          filters:
            - StripPrefix=1
        - id: my-service-2
          uri: lb://my-service
          predicates:
            - Path=/**

This is the stacktrace:

jakarta.servlet.ServletException: Handler dispatch failed: java.lang.OutOfMemoryError: Java heap space
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1104) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.4.jar:6.1.4]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:547) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.4.jar:6.1.4]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at org.springframework.cloud.gateway.server.mvc.filter.WeightCalculatorFilter.doFilter(WeightCalculatorFilter.java:229) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at org.springframework.cloud.gateway.server.mvc.filter.FormFilter.doFilter(FormFilter.java:93) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.4.jar:6.1.4]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.4.jar:6.1.4]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109) ~[spring-web-6.1.4.jar:6.1.4]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.4.jar:6.1.4]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.4.jar:6.1.4]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101) ~[undertow-servlet-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:393) ~[undertow-core-2.3.12.Final.jar:2.3.12.Final]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859) ~[undertow-core-2.3.12.Final.jar:2.3.12.Final]
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282) ~[xnio-api-3.8.8.Final.jar:3.8.8.Final]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.lang.OutOfMemoryError: Java heap space
at org.springframework.util.FastByteArrayOutputStream.addBuffer(FastByteArrayOutputStream.java:325) ~[spring-core-6.1.4.jar:6.1.4]
at org.springframework.util.FastByteArrayOutputStream.write(FastByteArrayOutputStream.java:126) ~[spring-core-6.1.4.jar:6.1.4]
at java.base/java.io.InputStream.transferTo(InputStream.java:783) ~[na:na]
at org.springframework.util.StreamUtils.copy(StreamUtils.java:150) ~[spring-core-6.1.4.jar:6.1.4]
at org.springframework.cloud.gateway.server.mvc.handler.RestClientProxyExchange.copyBody(RestClientProxyExchange.java:44) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at org.springframework.cloud.gateway.server.mvc.handler.RestClientProxyExchange.lambda$exchange$1(RestClientProxyExchange.java:39) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at org.springframework.cloud.gateway.server.mvc.handler.RestClientProxyExchange$$Lambda$1328/0x000000700174ae38.writeTo(Unknown Source) ~[na:na]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.lambda$body$2(DefaultRestClient.java:393) ~[spring-web-6.1.4.jar:6.1.4]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec$$Lambda$1329/0x000000700174b280.writeTo(Unknown Source) ~[na:na]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:471) ~[spring-web-6.1.4.jar:6.1.4]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchange(DefaultRestClient.java:449) ~[spring-web-6.1.4.jar:6.1.4]
at org.springframework.cloud.gateway.server.mvc.handler.RestClientProxyExchange.exchange(RestClientProxyExchange.java:40) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at org.springframework.cloud.gateway.server.mvc.handler.ProxyExchangeHandlerFunction.handle(ProxyExchangeHandlerFunction.java:120) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions$LookupProxyExchangeHandlerFunction.handle(HandlerFunctions.java:107) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$ofRequestProcessor$3(HandlerFilterFunction.java:83) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.function.HandlerFilterFunction$$Lambda$798/0x00000070014b5930.filter(Unknown Source) ~[na:na]
at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$andThen$0(HandlerFilterFunction.java:58) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.function.HandlerFilterFunction$$Lambda$1263/0x0000007001722300.handle(Unknown Source) ~[na:na]
at org.springframework.cloud.gateway.server.mvc.filter.LoadBalancerFilterFunctions.lambda$lb$5(LoadBalancerFilterFunctions.java:112) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at org.springframework.cloud.gateway.server.mvc.filter.LoadBalancerFilterFunctions$$Lambda$807/0x00000070014bb1f0.filter(Unknown Source) ~[na:na]
at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$andThen$0(HandlerFilterFunction.java:58) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.function.HandlerFilterFunction$$Lambda$1263/0x0000007001722300.handle(Unknown Source) ~[na:na]
at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$ofRequestProcessor$3(HandlerFilterFunction.java:83) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.function.HandlerFilterFunction$$Lambda$798/0x00000070014b5930.filter(Unknown Source) ~[na:na]
at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$andThen$0(HandlerFilterFunction.java:58) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.function.HandlerFilterFunction$$Lambda$1263/0x0000007001722300.handle(Unknown Source) ~[na:na]
at org.springframework.cloud.gateway.server.mvc.config.RouterFunctionHolderFactory.lambda$getRouterFunction$3(RouterFunctionHolderFactory.java:154) ~[spring-cloud-gateway-server-mvc-4.1.2.jar:4.1.2]
at org.springframework.cloud.gateway.server.mvc.config.RouterFunctionHolderFactory$$Lambda$799/0x00000070014b60a8.filter(Unknown Source) ~[na:na]
at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$andThen$0(HandlerFilterFunction.java:58) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.function.HandlerFilterFunction$$Lambda$1263/0x0000007001722300.handle(Unknown Source) ~[na:na]
at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$ofRequestProcessor$3(HandlerFilterFunction.java:83) ~[spring-webmvc-6.1.4.jar:6.1.4]
at org.springframework.web.servlet.function.HandlerFilterFunction$$Lambda$798/0x00000070014b5930.filter(Unknown Source) ~[na:na]
@spencergibb spencergibb changed the title Spring Cloud Gateway MVC produces OOM Spring Cloud Gateway MVC produces OOM when uploading large files Sep 27, 2024
@spencergibb
Copy link
Member

With zuul, the solution was to skip the spring dispatcher servlet altogether, I'm not sure what to do here as we can not skip the dispatcher servlet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants