设置最大消费者数jms安慰

时间:2019-04-05 09:35:26

标签: java spring jms solace

我正在尝试使用solace作为代理,使用jms设置主题终结点的最大使用者数,因此,为了增加负载,可以在cloudfoundry中启动该应用程序的多个实例,并且多个订阅者可以使用同一主题的消息

我尝试了以下设置的多种组合(setConcurrency(), setConcurrentConsumers(), setMaxConcurrentConsumers(),(20为任意高数字)。从文档中判断,我绝对需要使用setMaxConcurrentConsumers()并将其设置为适当的高值。

当我部署应用程序时,将创建主题端点,但是当我查看solace管理界面时,最大消费者数始终为1(如此处所示:Queues -> Topic Endpoints -> select endpoint -> Configured Limit),即使它应该是20。因此第二个使用者无法连接。我不想在每次部署应用程序时手动进行设置。

Screenshot of my solace management interface

import javax.jms.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;

@Configuration
public class ProducerConfiguration {

    private static final Log logger = LogFactory.getLog(SolaceController.class);

    @Value("${durable_subscription}")
    private String subscriptionName;

    @Value("${topic_name}")
    private String topic_name;

    @Autowired
    private ConnectionFactory connectionFactory;

    @Bean
    public JmsTemplate jmsTemplate() {
        CachingConnectionFactory ccf = new CachingConnectionFactory(connectionFactory);
        JmsTemplate jmst = new JmsTemplate(ccf);
        jmst.setPubSubDomain(true);
        return jmst;
    }

    @Bean
    public Session configureSession(ConnectionFactory connectionFactory) throws JMSException {
        return connectionFactory.createConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
    }


    private TextMessage lastReceivedMessage;

    public class SimpleMessageListener implements MessageListener {
        @Override
        public void onMessage(Message message) {

            if (message instanceof TextMessage) {
                lastReceivedMessage = (TextMessage) message;
                try {
                    logger.info("Received message : " + lastReceivedMessage.getText());
                } catch (JMSException e) {
                    logger.error("Error getting text of the received TextMessage: " + e);
                }
            } else {
                logger.error("Received message that was not a TextMessage: " + message);
            }
        }
    }

    @Bean
    public DefaultMessageListenerContainer orderMessageListenerContainer() {

        DefaultMessageListenerContainer lc = new DefaultMessageListenerContainer();
        lc.setConnectionFactory(connectionFactory);
        lc.setDestinationName(topic_name);
        lc.setMessageListener(new SimpleMessageListener());
        lc.setDurableSubscriptionName(subscriptionName);
        lc.setPubSubDomain(true);

        //tried multiple combinations here, also setting only setMaxConcurrentConsumers
        lc.setConcurrency("2-20");
        lc.setConcurrentConsumers(20);
        lc.setMaxConcurrentConsumers(20);

        lc.setSubscriptionDurable(true);
        lc.initialize();
        lc.start();
        return lc;
    }
}

2 个答案:

答案 0 :(得分:1)

对于您的用例,我认为您的使用者陷入了队列。参见https://solace.com/blog/topic-subscription-queues/

“ ...,而多个使用者可以绑定到队列 耐用的终结点仅限于单个主题订阅。队列允许多个主题订阅以及主题通配符。”

如果您不想更改发布者,则可以尝试“队列上的主题订阅”。也就是说,可以将队列配置为侦听主题。然后您的消费者将从该队列中获取消息。

答案 1 :(得分:1)

您需要创建一个非独占的队列/端点。

默认情况下,您创建的队列是互斥队列/端点,这意味着任何时间都只能绑定一个订阅者。

创建这种队列/端点的最简单方法是通过Solace CLI。

要在JMS程序中创建非独占队列,您必须进入Solace特定的JMS实现,如下所示:

    if (queueName != null) {
        EndpointProperties props = new EndpointProperties();
        props.setAccessType(EndpointProperties.ACCESSTYPE_NONEXCLUSIVE);

        try {
            ((SolConnection)connection).getProperties().getJCSMPSession()
                .provision(JCSMPFactory.onlyInstance().createQueue(queueName), props, 0L);
        } catch (Exception e) {
            e.printStackTrace();
        }

        queue = session.createQueue(queueName);
    }