Распределение нагрузки Spring JMS с одним производителем и одним Concumer - PullRequest
0 голосов
/ 13 июня 2018

Я так долго исследовал балансировку нагрузки JMS.Мы можем создать несколько производителей и несколько потребителей для балансировки нагрузки JMS-сообщений.Но я хочу понять, как мы можем сбалансировать JMS-сообщения с одним производителем и одним потребителем.Я не могу добавить больше зависимостей в мой проект, такой как Apache Camel.

@Configuration
@EnableJms
@ComponentScan({"com.jmsloadbalance.jms"})
@Bean
public class JmsConfig {
public JmsTemplate getJmsTemplate() {
    JmsTemplate template = new JmsTemplate();
    template.setConnectionFactory(connectionFactory());
    template.setDefaultDestination(new ActiveMQQueue("default.topic");
    template.setExplicitQosEnabled(true);
    template.setDeliveryPersistent(false);
    template.setTimeToLive(60000);
    template.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
    template.setMessageConverter(getMessageConverter());
    return template;
}

@Bean
public DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    factory.setPubSubDomain(false);
    factory.setDestinationResolver(new DynamicDestinationResolver());
    factory.setConcurrency("1");
    factory.setMessageConverter(getMessageConverter());
    return factory;
}

private ActiveMQConnectionFactory connectionFactory() {
    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
    factory.setBrokerURL("vm://localhost");
    return factory;
}

private MessageConverter getMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTypeIdPropertyName("JMSType");
    return converter;
}
}

Это мой класс JmsConfig, где я не могу вносить большие изменения в конфигурацию, например, вводить больше JMSTemplate или больше ConnectionFactory.Мой производитель выглядит ниже

@Service("accountJmsProducer")
public class AccountJmsProducer {

private static Logger LOG = Logger.getLogger(AccountJmsProducer.class);

@Autowired
private JmsTemplate template;

private Destination destination;

public Account create(Account account) {
    if (this.destination == null) {
        this.destination = new ActiveMQQueue("account.create");
    }
    template.convertAndSend(destination, account);
    return null;
}
}

Мой потребитель выглядит ниже:

@Service("accountJmsConsumer")
public class AccountJmsConsumer {

private static final Logger LOG = Logger.getLogger(AccountJmsConsumer.class);

@Autowired
@Qualifier("accountService")
private AccountService accountService;

private Account lastReceived;

@JmsListener(containerFactory = "defaultJmsListenerContainerFactory", destination = "account.create")
public Account create(Account account) {
    LOG.warn("Received " + account);
    setLastReceived(account);
    return accountService.create(account);
}
public synchronized Account getLastReceived() {
    return lastReceived;
}
public synchronized void setLastReceived(Account lastReceived) {
    this.lastReceived = lastReceived;
}
}

1 Ответ

0 голосов
/ 13 июня 2018

Непонятно, что вы подразумеваете под балансировкой нагрузки, когда есть один потребитель, но на основании вашего комментария к моему комментарию на ваш вопрос:

Пока пункт назначения является очередью (не темой), и этоподразумевается, поскольку у вас есть factory.setPubSubDomain(false), то это будет просто работать.Это часть контракта JMS.Если в одной очереди несколько потребителей, сообщения будут распределены между этими потребителями;только один потребитель получит конкретное сообщение.

Если доставка не удалась, она может или не может быть доставлена ​​одному и тому же потребителю.

Большинство брокеров (включая ActiveMQ) предлагают своего родаМеханизм предварительной выборки.IIRC, с ActiveMQ это 1000 по умолчанию.Если у вас меньше сообщений, чем один, то один потребитель может быть бездействующим;если это так, уменьшите предварительную выборку, чтобы настроить распределение.

...