如何通过JMS API从Solace监听器向Solace队列发送NACK?
Solace JMS 消息NACK实现及参数配置方案
如何通过Java API发送NACK
标准JMS规范未提供NACK(负确认)原生接口,Solace对JMS API做了私有扩展,具体实现方式如下:
将接收到的JMS消息强转为Solace私有实现类SolJmsMessage,调用setNACKd(true)标记消息为负确认状态即可。为了避免后续消息被确认时连带未确认的失败消息,建议标记NACK后抛出运行时异常终止当前批次消息处理。
代码示例:
import com.solacesystems.jms.SolJmsMessage; import org.apache.kafka.common.KafkaException; public class MyListener implements MessageListener { @Override public void onMessage(Message message) { try { // 毒消息校验、发送到Kafka业务逻辑 sendToKafka(message); // Kafka返回成功后确认消息 message.acknowledge(); } catch (KafkaException e) { // Kafka发送失败,标记NACK if (message instanceof SolJmsMessage) { SolJmsMessage solMsg = (SolJmsMessage) message; solMsg.setNACKd(true); } // 抛出异常终止后续消息处理,避免窗口连带确认问题 throw new RuntimeException("Kafka发送失败,触发消息重发", e); } } }
如果是Kafka全宕机这类批量失败场景,不需要单条标记NACK,直接调用session.recover()即可将所有未确认消息全部重发,实现更简单。
参数取值建议
Max_Un_Ack_Message(未确认消息窗口大小)
- 强顺序消费场景:建议设置为1,保证同一时间只有1条消息处于未确认状态,完全避免窗口连带确认问题,吞吐量会受一定影响,适合消息量不大、对顺序要求高的业务。
- 高吞吐量、无顺序要求场景:建议设置为10~100,可根据单条消息平均处理耗时调整,值越大吞吐量越高,但出现单条消息NACK时,窗口内所有后续未确认消息都会被连带重发,会产生一定的重复消费开销。
Max_Redeliver_Count(最大重发次数)
- 常规场景建议设置为3~10次,必须搭配死信队列(DMQ)使用,超过重发次数的消息会自动转入死信队列,避免毒消息无限重发堵塞队列。
- 若你的Kafka集群故障恢复时间通常在30分钟以内,可将Solace broker端的重发间隔配置为30秒,
Max_Redeliver_Count设置为60,预留足够的故障恢复窗口,减少人工处理死信的成本。
额外注意事项
- 遇到Kafka全集群宕机这类大范围故障时,建议在消费端接入熔断逻辑,检测到Kafka不可用时暂停消费,避免大量消息反复重发占用Solace broker资源。
- 消息重发会产生重复消费,下游Kafka消费逻辑必须保证幂等性。
内容的提问来源于stack exchange,提问作者karuppusamy
相关产品推荐
相关产品推荐

