代码之家  ›  专栏  ›  技术社区  ›  Neer1009

如何在spring中设置DefaultMessageListenerContainer中的持久订户?

  •  0
  • Neer1009  · 技术社区  · 6 年前

    消息的生产者没有将消息作为持久消息发送,当我试图通过MessageListener使用消息时,如果发生任何异常(运行时),它将重试特定次数(默认为AMQ端的6次)并且消息将丢失。

    我的代码是这样的:-

    @Configuration
    @PropertySource("classpath:application.properties")
    public class ActiveMqJmsConfig {
    
    @Autowired
    private AbcMessageListener abcMessageListener;
    
    public DefaultMessageListenerContainer purchaseMsgListenerforAMQ(
        @Qualifier("AMQConnectionFactory") ConnectionFactory amqConFactory) {
    
        LOG.info("Message listener for purchases from AMQ : Starting");
        DefaultMessageListenerContainer defaultMessageListenerContainer =
            new DefaultMessageListenerContainer();
    
        defaultMessageListenerContainer.setConnectionFactory(amqConFactory);
    
        defaultMessageListenerContainer.setMaxConcurrentConsumers(4);
    
        defaultMessageListenerContainer
            .setDestinationName(purchaseReceivingQueueName);
    
        defaultMessageListenerContainer
            .setMessageListener(abcMessageListener);
    
        defaultMessageListenerContainer.setSessionTransacted(true);
    
        return defaultMessageListenerContainer;
    }
    
     @Bean
    @Qualifier(value = "AMQConnectionFactory")
    public ConnectionFactory activeMQConnectionFactory() {
    
        ActiveMQConnectionFactory amqConnectionFactory =
            new ActiveMQConnectionFactory();
    
        amqConnectionFactory
            .setBrokerURL(System.getProperty(tcp://localhost:61616));
        amqConnectionFactory
            .setUserName(System.getProperty(admin));
        amqConnectionFactory
            .setPassword(System.getProperty(admin));
    
        return amqConnectionFactory;
    
    }
    
    }
    
    @Component
    public class AbcMessageListener implements MessageListener {
     @Override
    public void onMessage(Message msg) {
    //CODE implementation
    }
    
    }
    

    问题:-通过在连接级别(connection.setclientid(“String”)设置客户端id,即使消息不是持久的,我们也可以订阅为持久订户。通过这样做,如果应用程序抛出运行时异常,在一定次数的重试尝试之后,将为队列创建DLQ,并将消息移动到DLQ。

    但在DefaultMessageListenerContainer中,连接不向客户端公开。我想它是由类本身作为一个池来维护的。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Gary Russell    6 年前

    您可以改为在容器上设置客户端id:

    /**
     * Specify the JMS client ID for a shared Connection created and used
     * by this container.
     * <p>Note that client IDs need to be unique among all active Connections
     * of the underlying JMS provider. Furthermore, a client ID can only be
     * assigned if the original ConnectionFactory hasn't already assigned one.
     * @see javax.jms.Connection#setClientID
     * @see #setConnectionFactory
     */
    public void setClientId(@Nullable String clientId) {
        this.clientId = clientId;
    }
    

    /**
     * Set the name of a durable subscription to create. This method switches
     * to pub-sub domain mode and activates subscription durability as well.
     * <p>The durable subscription name needs to be unique within this client's
     * JMS client id. Default is the class name of the specified message listener.
     * <p>Note: Only 1 concurrent consumer (which is the default of this
     * message listener container) is allowed for each durable subscription,
     * except for a shared durable subscription (which requires JMS 2.0).
     * @see #setPubSubDomain
     * @see #setSubscriptionDurable
     * @see #setSubscriptionShared
     * @see #setClientId
     * @see #setMessageListener
     */
    public void setDurableSubscriptionName(@Nullable String durableSubscriptionName) {
        this.subscriptionName = durableSubscriptionName;
        this.subscriptionDurable = (durableSubscriptionName != null);
    }
    
    推荐文章