Java SpringContextShutdownHook防止JVM关闭
当我Java SpringContextShutdownHook防止JVM关闭,java,jvm,project-reactor,Java,Jvm,Project Reactor,当我SIGTERMJVM时,我有一个反应式应用程序的行为有点奇怪。基本上,JVM无法正常退出,因为其中一个关机挂钩似乎被卡住了。当我SIGTERM时,我看到以下日志: {"timeStamp":"2021-04-14T19:52:44.472+05:30","message":"Shutting down ExecutorService 'applicationTaskExecutor'","logger&
SIGTERM
JVM时,我有一个反应式应用程序的行为有点奇怪。基本上,JVM
无法正常退出,因为其中一个关机挂钩似乎被卡住了。当我SIGTERM
时,我看到以下日志:
{"timeStamp":"2021-04-14T19:52:44.472+05:30","message":"Shutting down ExecutorService 'applicationTaskExecutor'","logger":"org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor","thread":"SpringContextShutdownHook","level":"INFO"}
这之后什么都没有VisualVM
显示此线程(SpringContextShutdownHook
)处于startPark
状态
@EventListener(ApplicationReadyEvent.class)
public void poll() {
String queueUrl =
String.format("%s/%s", properties.getSqs().getHost(), properties.getSqs().getQueue());
ReceiveMessageRequest request =
new ReceiveMessageRequest()
.withQueueUrl(queueUrl)
.withMaxNumberOfMessages(
properties.getSqs().getClientConfiguration().getMaxNoOfMessages());
RetryBackoffSpec retryStrategy =
Retry.backoff(
Long.MAX_VALUE,
Duration.ofMillis(properties.getSqs().getClientConfiguration().getInitialBackoff()))
.jitter(properties.getSqs().getClientConfiguration().getJitter());
Flux.<List<Message>>generate(
sink -> {
List<Message> messages = client.receiveMessage(request).getMessages();
sink.next(messages);
})
.subscribeOn(Schedulers.boundedElastic())
.retryWhen(retryStrategy)
.flatMap(messages -> Flux.fromIterable(messages).subscribeOn(Schedulers.parallel()))
.map(
message ->
Pair.of(message, convertor.deserialize(message.getBody(), BackendEvent.class)))
.flatMap(
pair -> {
Event event = pair.getRight();
EventInfo eventInfo = event.getEventInfo();
return factory
.getHandler(event)
.handle(pair.getRight())
.map(ignored -> pair.getLeft())
.onErrorResume(
err -> Mono.just(pair.getLeft())); // todo: handle failed messages using DLQs
})
.publishOn(Schedulers.boundedElastic())
.doOnNext(
message ->
client.deleteMessage(
new DeleteMessageRequest().withReceiptHandle(message.getReceiptHandle())))
.blockLast();
}
@EventListener(ApplicationReadyEvent.class)
公众投票{
字符串队列URL=
String.format(“%s/%s”、properties.getSqs().getHost()、properties.getSqs().getQueue());
ReceiveMessageRequest请求=
新的ReceiveMessageRequest()
.withQueueUrl(queueUrl)
.withMaxNumberOfMessages(
getSqs().getClientConfiguration().getMaxNoOfMessages());
RetryBackoffSpec retryStrategy=
重试。退避(
Long.MAX_值,
持续时间(properties.getSqs().getClientConfiguration().getInitialBackoff())
.jitter(properties.getSqs().getClientConfiguration().getJitter());
通量生成(
水槽->{
List messages=client.receiveMessage(request.getMessages();
sink.next(消息);
})
.subscribeOn(Schedulers.BoundedElistic())
.retryWhen(retryStrategy)
.flatMap(messages->Flux.fromIterable(messages).subscribeOn(Schedulers.parallel())
.地图(
信息->
对(message,convertor.deserialize(message.getBody(),BackendEvent.class)))
.平面图(
配对->{
Event=pair.getRight();
EventInfo EventInfo=event.getEventInfo();
返回工厂
.getHandler(事件)
.handle(pair.getRight())
.map(忽略->pair.getLeft())
A.简历(
err->Mono.just(pair.getLeft());//todo:使用DLQ处理失败的消息
})
.publishOn(Schedulers.boundedElastic())
doOnNext先生(
信息->
client.deleteMessage(
新建DeleteMessageRequest().withReceiptHandle(message.getReceiptHandle()))
.blockLast();
}
VisualVM
输出:
获取线程转储并查看非守护进程线程的堆栈跟踪。