我们开发了一个由辅助系统访问的微服务。两个系统都使用 Swagger/OpenApi API 相互通信。我们将客户端生成为“java”(底层 okhttp-Client)。
当我们在一段时间后对系统进行负载测试时,我们得到java.lang.OutOfMemoryError:无法在客户端上创建新的 native 线程
,尽管系统配置了足够的内存(通过 - Xmx)。
我们怎样才能避免这种情况呢?怎么了?
最佳答案
OpenApi 生成“java”客户端,以便 ApiClient
的每个实例都包装 OkHttpClient
的一个实例。 OkHttpClient
的文档指出,每个实例都会创建一个 ThreadPool
以及一个缓存。它还指出,OkHttpClient
- 实例应该在多个请求之间共享。
如果您不这样做并在每次调用时生成一个 ApiClient
,您将会泄漏 Thread
。一旦垃圾收集消除了未使用的 ApiClient
实例,这些就会被恢复,但是,如果您的系统配置了足够的内存,则此 gc 调用可能不会频繁发生,并且您最终可能会得到更多请求的 native 线程超出了底层操作系统可以提供的范围。
解决方案是在应用程序中重用 ApiClient
实例或切换到基于客户端的实例,例如在 Spring RestTemplate
上。
对于那些好奇的人:OkHttpClient
似乎保留了处理异步 http/2 请求的线程 - 如果您的应用程序实际上并不执行异步调用,那么这有点过大了。
关于java - 为什么在对 Swagger-Webservice 进行负载测试时会出现 OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59058870/