Как правильно настроить Spring, чтобы правильно закрыть сеанс ActiveMQ или соединение? - PullRequest
2 голосов
/ 02 июля 2019

ActiveMQ Producer

Производитель Java использует пул соединений Spring для управления 100 MQ-соединениями. Каждое соединение MQ может открыть 500 сеансов по умолчанию.

После создания 50000 сообщений используются все соединения и сеансы.

  • Будет очень медленно получать новое соединение из пула пружинных соединений (сначала получите соединение из пула, а затем создайте новый сеанс).
  • И для закрытия соединения потребуется много времени.
  • А сервер ActiveMQ будет использовать много памяти.

Я хочу знать:

  • Как удалить или повторно использовать сеансы, созданные соединением?
  • Когда закрывать соединение mq?

Я пробовал эти параметры: idleTimeout + expiryTimeout + timeBetweenExpirationCheckMillis, но:

  • Когда система очень занята в течение длительного времени. Вся система будет все медленнее и медленнее. ActiveMQ будет использовать все больше и больше памяти.
  • Когда система очень занята, затем внезапно простаивает, а затем внезапно становится очень занятой. timeBetweenExpirationCheckMillis не достаточно быстро, чтобы закрыть все соединения. Пул соединений попытается закрыть все соединения с тайм-аутом (idleTimeout или expiryTimeout), а затем откроет новое соединение. Вся система зависнет на 10-20 минут.

Я попытался отключить постоянство kahadb, не работает.

Update1: конфигурация пула соединений ActiveMQ

<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
  <property name="brokerURL" value="failover:(tcp://activemq:61616)" />
</bean>

<bean id="connectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
  <property name="connectionFactory" ref="targetConnectionFactory" />
  <property name="maxConnections" value="100" />
  <property name="idleTimeout" value="30000" />
  <property name="expiryTimeout" value="60000" />
  <property name="maximumActiveSessionPerConnection" value="500" />
  <property name="timeBetweenExpirationCheckMillis" value="30000" />
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="receiveTimeout" value="10000"/>
</bean>

Обновление 2: тестовый код

package just.a.test;

import javax.jms.Destination;
import net.sf.json.JSONObject;
import org.springframework.jms.core.JmsTemplate;

@Component
public final class TestHandlerImpl{

    @Autowired
    private JmsTemplate jmsTemplate;

    @Autowired
    private Destination testQueue;

    public void sendMessage(File binaryFile){
            //read file, get one msg
            JSONObject msg = processBinaryFile(binaryFile);

            //send msg to queue
            sendMessageToQueue(testQueue, msg.toString());
        }
    }

    protected void sendMessageToQueue(Destination destination, final String msg) {
        //this code will get one connection from pool
        //create a new session
        //and send the message
        jmsTemplate.send(destination, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(msg);
            }
        });
    }
}

Update3:

Теперь мне нужно изменить activemq-all.jar и common-pool.jar, чтобы вся система была стабильной. Что я не считаю правильным.

...