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

(Reproducable) - Memory leak and sockets leak issue - LEAK: ByteBuf.release() & OutOfDirectMemoryError #664

Closed
nilavalagansugumaran opened this issue Nov 19, 2018 · 8 comments
Assignees

Comments

@nilavalagansugumaran
Copy link

We created a gateway server running with few filters that are related to response, request decorators and readers along with other header modifier filters. The filters are mixer of pre, post, gateway and global in nature. As soon as we deployed gateway server to production, we started experiencing memory leaks, sockets leaks issues. We tried various tuning options such as increasing memory, tuning open files, removing micro-meters, moving to M1/snapshot versions and more but nothing helped hence we had to pull out gateway server from production after a month of trying.

I have managed to re-create the problem in local/dev environment by creating a simple and sample gateway server. The sample application has just two gateway filters, one reads the response and other uses response decorator. To re-produce the issue, I run the gateway server as a standalone spring boot application. And I was generating load using jemeter - 500 requests ramped up in 60 secs and continued same the load for 30 iterations.

I have used below stable versions when building the sample application -

springBootVersion = '2.0.6.RELEASE'
springCloudGatewayVersion = "2.0.2.RELEASE"

Issue can be replicable on all the below scenarios

  • Test 1 - 256mb JVM includes micro-meter, includes two filters (Took ~5 mins to fail)
  • Test 2 - 512mb JVM includes micro-meter, includes all filters (Took ~15 mins to fail)
  • Test 3 - 256mb JVM excludes micro-meter, includes all filters (Took ~8 mins to fail)
  • Test 4 - 256mb JVM excludes micro-meter & excludes filter - SampleResponseDecoratorGatewayFilter (Took ~8 mins to fail)
  • Test 5 - 256mb JVM excludes micro-meter & excludes filter - SampleWriteResponseGatewayFilter (Took ~8 mins to fail)

**No memory leaks found. Server was running over 1 hours without any issues **

  • Test 6 - 256mb JVM excludes micro-meter & removed all filters

Sample application can be found at https://github.com/nilavalagansugumaran/gateway-netty-memory-leak-issues along with instructions.

@spencergibb & @violetagg - Please can you help in getting the issue resolved with ResponseDecorators and ResponseWriters or any alternatives that we can try?

Logs and screenshots
(Full logs and heap utilisation screenshot can be found at https://github.com/nilavalagansugumaran/gateway-netty-memory-leak-issues/tree/master/logs )

2018-11-15 05:43:03.185  INFO 39279 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 7007
2018-11-15 05:49:49.387 ERROR 39279 --- [ctor-http-nio-2] io.netty.util.ResourceLeakDetector       : LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records: 
#1:
        io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:273)
        io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
 4 leak records were discarded because the leak record count is targeted to 20. Use system property io.netty.leakDetection.targetRecords to increase the limit.
2018-11-15 05:55:37.206 ERROR 39279 --- [ctor-http-nio-1] o.s.w.s.adapter.HttpWebHandlerAdapter    : Unhandled failure: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 234881031, max: 239075328), response already set (status=200)
2018-11-15 05:55:38.140 ERROR 39279 --- [ctor-http-nio-1] o.s.w.s.adapter.HttpWebHandlerAdapter    : Unhandled failure: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 234881031, max: 239075328), response already set (status=200)
2018-11-15 05:55:42.951 ERROR 39279 --- [ctor-http-nio-1] o.s.w.s.adapter.HttpWebHandlerAdapter    : Unhandled failure: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 234881031, max: 239075328), response already set (status=200)

Screenshots
jvisualvm screen shot - test 1

@nilavalagansugumaran nilavalagansugumaran changed the title (Re-producable) - Memory leak and sockets leak issue - LEAK: ByteBuf.release() & OutOfDirectMemoryError (Reproducable) - Memory leak and sockets leak issue - LEAK: ByteBuf.release() & OutOfDirectMemoryError Nov 19, 2018
@spencergibb spencergibb self-assigned this Nov 19, 2018
@spencergibb
Copy link
Member

Have you looked at these filters? https://github.com/spring-cloud/spring-cloud-gateway/tree/master/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite

Remember: once you start reading request and response bodies, the gateway is now constrained by all memory needed for concurrent requests.

@nilavalagansugumaran

This comment has been minimized.

@spencergibb
Copy link
Member

Please don't comment on unrelated issues

@nilavalagansugumaran
Copy link
Author

@spencergibb - No, this is related. As suggested in your previous comment, using this same sample application, I am trying to verify if using ModifyResponseBody filters results in Memory leak and sockets leak issue before we rewrite our production code. I am stuck with the configurations that the ModifyResponseBody filter is expecting so looking for your advice. Please can you help?

@spencergibb
Copy link
Member

You didn't say that. All you asked about was configuration. Which isn't possible in yaml yet

@nilavalagansugumaran
Copy link
Author

Thanks for getting back to me @spencergibb . Is it possible to use FilterDefinition to add this filter to existing routes programatically? It looks, FilterDefinition accepts only String arguments. Please can you advice?

@nilavalagansugumaran
Copy link
Author

@spencergibb - Thanks a lot for pointing me to the ModifyResponseBodyGatewayFilterFilter. As I was not able to add the configuration required for ModifyResponseBodyFilter in yml, I created my own filter with the logic written in ModifyResponseBodyGatewayFilterFilter and executed previous test which ran successfully and didn't see the memory leak. We will do some more tests before rewriting our production code. One last question if you feel this is relevant - We would like to use gateway version v2.1.0.M3, please can you advice what is the compatible spring-boot version we should use? I am not able find this information in the release tags. Many thanks for your help!

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

No branches or pull requests

4 participants