【问题标题】:Is there a way to programmatically delete an ActiveMQ Job Schedule?有没有办法以编程方式删除 ActiveMQ 作业计划?
【发布时间】:2020-12-28 21:19:04
【问题描述】:

我正在尝试删除 ActiveMQ 中的计划作业,但到目前为止还没有成功。

使用NMS APIAmqpnetlite 与消息一起创建计划(openwire lib 除外,因为该库未更新且不能在 netstandard/netcore 上使用)

用于使用 NMS 创建计划的示例代码,与 AMQP 库相同:

var factory = new Apache.NMS.ActiveMQ.ConnectionFactory(brokerUri);
IConnection connection = factory.CreateConnection(user, password);
connection.Start();

ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
IDestination dest = session.GetQueue(destination);
IMessageProducer producer = session.CreateProducer(dest);
producer.DeliveryMode = MsgDeliveryMode.NonPersistent;

var msg = session.CreateTextMessage("Sample text message");
msg.Properties.SetString("AMQ_SCHEDULED_CRON", "* * * * *");
producer.Send(msg);
connection.Close();

这部分在浏览器控制台中产生以下结果,这就是我愿意删除的:

我读过this other question and answer,也读过active mq system constants,但日程安排不会被删除。还尝试浏览文档,但到目前为止找不到任何有用的东西

ActiveMQ 是否甚至支持以编程方式管理计划? AMQP 解决方案会很棒,但 NMS 也很受欢迎。

【问题讨论】:

    标签: activemq nms apache-nms amqp.netlite


    【解决方案1】:

    您可以通过 STOMP、AMQP 或仅从 JMS 客户端管理 ActiveMQ 中的计划作业。我已经written about this before 展示了如何使用 ActiveMQ Java 客户端进行操作,但原理是相同的。您可以发送设置了特定标头的消息,这些标头将对预定的消息进行操作。

    要浏览预定消息的集合,您需要执行以下操作:

        Connection connection = createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
        // Create the Browse Destination and the Reply To location
        Destination requestBrowse = session.createTopic(ScheduledMessage.AMQ_SCHEDULER_MANAGEMENT_DESTINATION);
        Destination browseDest = session.createTemporaryQueue();
    
        // Create the "Browser"
        MessageConsumer browser = session.createConsumer(browseDest);
    
        connection.start();
    
        // Send the browse request
        MessageProducer producer = session.createProducer(requestBrowse);
        Message request = session.createMessage();
        request.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
                                  ScheduledMessage.AMQ_SCHEDULER_ACTION_BROWSE);
        request.setJMSReplyTo(browseDest);
        producer.send(request);
    
        Message scheduled = browser.receive(5000);
        while (scheduled != null) {
            // Do something clever...
        }
    

    返回的消息包含有关先前添加的实际计划消息作业的信息。获取作业 ID 允许您完全取消所述消息的传递。

    要删除使用 Java 客户端、AMQP 客户端或其他协议客户端安排的预定消息发送,您需要执行以下操作:

        Message remove = session.createMessage();
        remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULER_ACTION,
                ScheduledMessage.AMQ_SCHEDULER_ACTION_REMOVE);
        remove.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID,
                scheduled.getStringProperty(ScheduledMessage.AMQ_SCHEDULED_ID));
        producer.send(remove);
    

    使用调度程序时可以使用的完整消息属性值集记录在here 中,在 AMQP 中只需使用每个字符串文字作为应用程序属性值,使用作业 ID 设置为远程,或NMS 客户端它只是一个字符串键消息属性,其中包含您要删除的作业 ID。

    在通过 AMQP 执行此操作时有一个警告,那就是您需要确保代理正在使用 JMS 转换器 ?transport.transformer=jms"查看 ActiveMQ 5 的 AMQP documentation

    【讨论】:

    • 感谢您的回答,我已经添加了指向其他答案的链接,也请阅读博客。那么,我从哪里得到这个:scheduled.getStringProperty(...)
    • 我已经从链接文章中剪切并粘贴了代码,您应该真正阅读它,详细解释这一点。
    • 啊,现在我看到了混乱。我正在尝试删除“计划作业”,而不是消息
    • 这正是它的作用,删除你之前创建的计划作业。
    • ok 将把它翻译成 C# 并尝试一下。我以为它只是删除了一条消息。
    【解决方案2】:

    接受的答案有效且正确。原来scheduledMessage.NMSMessageId 没有持有调度程序ID。

    如果有兴趣,这里是干净的 C# 源代码:

    var factory = new Apache.NMS.ActiveMQ.ConnectionFactory(brokerUri);
    IConnection connection = factory.CreateConnection(userName, password);
    
    var session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
    var requestBrowse = session.GetTopic("ActiveMQ.Scheduler.Management");
    var queue = session.GetQueue(queueName);
    var consumer = session.CreateConsumer(queue);
    
    connection.Start();
    
    var producer = session.CreateProducer(requestBrowse);
    var scheduledMessage = consumer.Receive(TimeSpan.FromSeconds(10));
    if (scheduledMessage != null)
    {
        // do check with persistent storage, if schedule is canceled, remove it:
        var remove = session.CreateMessage();
        // get prop names from : http://activemq.apache.org/maven/apidocs/constant-values.htm
        remove.Properties["AMQ_SCHEDULER_ACTION"] = "REMOVE";
        remove.Properties["scheduledJobId"] = scheduledMessage.Properties.GetString("scheduledJobId");
        producer.Send(remove);
    }
    
    producer.Close();
    session.Close();
    connection.Close();
    
    

    流程是这样的:从某个队列中获取消息,如果满足某些条件,则完全放弃调度。

    【讨论】:

    • NMSMessageID 是承载数据的消息的代理或发送者分配的 ID,并且永远不会映射到调度程序本身内部的 ID
    猜你喜欢
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2011-04-27
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    相关资源
    最近更新 更多