平滑关闭

Java消息队列任务的平滑关闭

扶醉桌前 提交于 2019-12-17 18:22:44
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 1.问题背景 对于消息队列任务的监听,我们一般使用Java写一个独立的程序,在Linux服务器上运行。当订阅者程序启动后,会通过消息队列客户端接收消息,放入线程池中并发的处理。 那么问题来了,当我们修改程序后,需要重新启动时,如何保证消息都能够被处理呢? 一些开源的消息队列中间件,会提供ACK机制(消息确认机制),当订阅者处理完消息后,会通知服务端删除对应消息,如果订阅者出现异常,服务端未收到确认消费,则会重试发送。 那如果消息队列中间件没有提供ACK机制,或者为了高吞度量的考虑关闭了ACK功能,如何最大可能保证消息都能够被处理呢? 正常来说,订阅者程序关闭后,消息会在队列中堆积,等待订阅者下次订阅消费,所以未接收的消息是不会丢失的。可能出现的问题就是在关闭的一瞬间,已经从消息队列中取出,但还没有被处理的消息。 因此我们需要一套平滑关闭的机制,保证在重启的时候,已接收的消息可以得到正常处理。 2.问题分析 平滑关闭的思路如下: 在关闭程序时,首先关闭消息订阅,保证不再接收新的消息。 关闭线程池,等待线程池中的消息处理完毕。 程序退出。 关闭消息订阅:消息队列的客户端都会提供关闭连接的方法,具体可以自行查看API。 关闭线程池:Java的 ThreadPoolExecutor 线程池提供 shutdown() 和