我注意到project reactor不允许处理OOM错误。项目React器开发人员通过添加日志消息来拦截和处理这类错误,但没有办法为框架用户拦截和处理它们。
我想这可能是个大问题。如果OOM发生,我的应用程序的客户端发送的HTTP请求挂起,但我的应用程序继续工作并处理其他请求,并且我的应用程序的健康检查也成功。
正如我在GitHub上的评论中回答的那样,我的应用程序可能处于不可恢复的状态。是的,我同意,我更希望运行状况检查失败或应用程序在OOM发生时完成。我明白onError方法不是处理这种特殊错误的好地方。但在我看来,它可以在课堂上做钩,例如。onJvmError,这将允许正常启动关闭进程或通过实现健康检查来通知这种情况。
我使用reactor和Webflux实现了带有剩余端点的the project in Kotlin(in Java),以重现这种情况。
interface CsvRepository : ReactiveCrudRepository<CsvRow, Long>
@Service
class CsvService(val csvRepository: CsvRepository) {
fun createByteArray(): Mono<ByteArray> =
csvRepository.findAll()
.reduce(ByteArrayOutputStream()) { output, el ->
output.write(el.toString().toByteArray())
output.write("\n".toByteArray())
output
}
.map { it.toByteArray() }
}
@SpringBootApplication
class WebfluxMemoryRetroProjectApplication(val csvService: CsvService) {
@Bean
fun routing(): RouterFunction<ServerResponse> = router {
accept(MediaType.ALL).nest {
GET("/test") {
csvService.createByteArray()
.flatMap { result ->
ServerResponse.ok()
.headers { httpHeaders ->
httpHeaders.contentType = MediaType("application", "force-download")
httpHeaders.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=test.txt")
}
.bodyValue(ByteArrayResource(result))
}
}
}
}
}
字符串
作为HTTP GET请求的结果,它从数据库请求数据并创建一个大小约为70 MB的文件。因此,如果我使用-xmx 100 m运行它,我在日志中只有一个错误:
2022-02-07 12:25:06.135 ERROR 10288 --- [actor-tcp-nio-1] r.n.channel.ChannelOperationsHandler : [7edd71ea, L:/127.0.0.1:58918 - R:localhost/127.0.0.1:5432] Error was received while reading the incoming data. The connection will be closed.
java.lang.OutOfMemoryError: Java heap space
....
2022-02-07 12:25:06.141 ERROR 10288 --- [actor-tcp-nio-1] i.r.p.client.ReactorNettyClient : Connection Error
reactor.netty.ReactorNetty$InternalNettyException: java.lang.OutOfMemoryError: Java heap space
型
未处理此错误,HTTP客户端请求挂起。这是预期的行为吗?如何处理此异常?我尝试了onErrorResume
和Hooks.onOperatorError
,但我无法拦截这种类型的异常。这似乎不合逻辑的应用程序继续工作,我不能拦截和处理这样的错误。
1条答案
按热度按时间wecizke31#
我只是想找个更好的工作。同样,在发生OutOfMemory错误后,我的应用程序挂起,队列中的消息保持“未确认”,健康检查保持正常工作并返回200。
我找到的最好的选择是设置JVM属性
-XX:+CrashOnOutOfMemoryError
,这样一旦发生此错误,JVM将退出并返回代码1,并记录一条消息。我希望有一种方法来处理这些事件,例如,将有问题的消息重定向到另一个队列。