【发布时间】:2021-01-26 15:02:46
【问题描述】:
我们通过提供clientId 和订阅者名称以编程方式使用createDurableSubscriber 创建了IBM MQ AMQP TOPIC 订阅者。
我们启动程序,使其订阅 TOPIC 并停止程序。然后将消息发送到主题并再次启动接收程序,但我们无法接收发送的消息并且丢失了在持久订阅的情况下不应该发生的消息..
当订阅者使用 mqsc 命令DISPLAY TOPIC、DISPLAY TPSTATUS、DISPLAY TPSTATUS SUB、DISPLAY SUB SUBID 连接时,我们可以看到 amqp 主题及其持久订阅,但在订阅者程序停止时看不到。我们已经定义了属性DEFPSIST(YES) 并且客户端(生产者到主题)正在发送持久消息。
由于我们在订阅者的持久队列中看不到消息,消息去了哪里?是否取决于到期属性?
连接时为我们的订阅者输出DISPLAY SUB SUBID。
AMQ8096: WebSphere MQ subscription inquired.
SUBID("hex sub id")
SUB(:private:CLINET01:TOPIC01) TOPICSTR(TOPIC01)
TOPICOBJ(SYSTEM.BASE.TOPIC) DISTYPE(RESOLVED)
DEST(SYSTEM.MANAGED.DURABLE.5F6B5C2524FB9AED)
DESTQMGR(qm.name) PUBAPPID( )
SELECTOR( ) SELTYPE(NONE)
USERDATA(010)
PUBACCT(***************************************************)
DESTCORL(***************************************************)
DESTCLAS(MANAGED) DURABLE(YES)
EXPIRY(0) PSPROP(MSGPROP)
PUBPRTY(ASPUB) REQONLY(NO)
SUBSCOPE(ALL) SUBLEVEL(1)
SUBTYPE(API) VARUSER(FIXED)
WSCHEMA(TOPIC) SUBUSER(mqm)
CRDATE(2020-09-28) CRTIME(04:14:09)
ALTDATE(2020-09-28) ALTTIME(04:14:09)
订阅者 ID 具有私有(不知道为什么)和客户端 ID,但没有订阅者名称,即 sub4
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Topic;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import java.lang.String;
import javax.jms.Destination;
import javax.naming.Context;
import org.apache.qpid.jms.JmsConnectionFactory;
import javax.jms.DeliveryMode;
import javax.naming.InitialContext;
import javax.jms.Message;
public class AMQPQueueExample1 implements Runnable {
private static final int DELIVERY_MODE = DeliveryMode.PERSISTENT;
public void run(){
try{
Connection connection = null;
Context context = new InitialContext();
ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("myFactoryLookup");
connection = connectionFactory.createConnection();
connection.setClientID("123");//("WHATS_MY_PURPOSE3"); // Why do we need clientID while publishing the TOPIC from consumer / publisher
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic priceTopic = (Topic) context.lookup("myTopicLookup1");
MessageConsumer subscriber1 = session.createDurableSubscriber(priceTopic,"sub420"); //"sub3");
System.out.println("TOPIC "+priceTopic);
connection.start();
while(true){
TextMessage message1 = (TextMessage) subscriber1.receive(1000);
if(message1!=null)
System.out.println("Subscriber 1 received : " + message1.getText());
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
AMQPQueueExample1 amp=new AMQPQueueExample1();
Thread thread = new Thread(amp);
thread.start();
}
}
值取自上下文工厂和提供程序 url 的 jndi.properties 文件。
【问题讨论】:
-
如果可以看到订阅,并且在程序运行时被视为 DURABLE(YES),但在程序停止时不存在,这表明程序正常结束并关闭删除订阅。你没有展示你的代码是什么样子的,所以没有它就不能进一步评论。看看你的订阅者程序在关闭时做了什么——它是否删除了持久订阅?如果是这样,您所描述的正是预期会发生的情况。
-
感谢您的快速回复...这正是我检查的内容,因为程序是由其他人编写的...而且正如我所看到的..我们基本上不会在程序中取消订阅持久订阅者我们没有删除订阅...我已编辑问题以显示 runmqsc 命令的响应 DISPLAY SUB SUBID(id)
-
IBM MQ 4 位版本为 8.0.0.5
-
@MoragHughson 我们的到期时间为 0 ...应该是 UNLIMITED 以及如何在创建订阅之后或创建订阅时将其更改为 UNLIMITED
-
@JoshMc 我们的 EXPIRY 是 0 ...应该是 UNLIMITED 以及如何在创建订阅之后或创建订阅时将其更改为 UNLIMITED
标签: java ibm-mq publish-subscribe amqp jms-topic