EAP 7 JMS-кластер не синхронизирован.Запланированное сообщение JMS заблокировано, когда узел не работает - PullRequest
0 голосов
/ 13 июня 2019

Я устанавливаю кластер EAP 7 в автономном режиме. Я следовал этому учебнику и настроил свой кластер.

Затем я начал тестировать систему JMS с помощью простого приложения JMS. Каждый раз, когда я отправляю сообщение JMS, я наблюдаю, что счетчик сообщений JMS обновляется только в одном из узлов (вместо обоих узлов, показанных в видео). Общее количество отправленных сообщений равно сумме отсчетов с обоих узлов.

Однако, поскольку узлы сгруппированы, я ожидаю, что статистика JMS будет синхронизирована (что показано на видео), поэтому оба узла должны отображать общее количество сообщений, полученных в кластере, а не только их часть.

Кроме того, при отправке запланированного сообщения, если узел, содержащий сообщение, умирает, сообщение блокируется до перезапуска мертвого узла. Это определенно недопустимо, так как я ожидаю, что запланированное сообщение будет доставлено другим (работающим) узлом.

Все тесты выполняются с использованием standalone-full-ha.xml по умолчанию

Вот все шаги, чтобы воспроизвести проблему:

Настройка среды

  1. Загрузите eap7.1 / 7.2 или wildfly12 / 14 и разархивируйте в каталог
  2. переименуйте каталог в my-dir-node1
  3. скопировать ваш-dir-node1 в my-dir-node2
  4. Обновление конфигурации
    1. перейдите в my-dir-node1 / standalone и скопируйте standalone-full-ha.xml в standalone-full-ha-test.xml
    2. edit my-dir-node1 / standalone / standalone-full-ha-test.xml
    3. добавить имя = "узел1" к корневому элементу: <server xmlns="urn:jboss:domain:5.0" name="node1">
    4. найдите <cluster password="${jboss.messaging.cluster.password:CHANGE ME!!}"/> и замените его на <cluster password="${jboss.messaging.cluster.password:mypassword}"/>
    5. добавить <jms-queue name="JMSTest" entries="java:/jms/queue/test"/> после <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>
    6. Перейдите в my-dir-node2 / standalone и повторите вышеуказанные шаги. убедитесь, что вы называете его сервером "node2" вместо "node1"

Разверните тестовое приложение, скопировав test-jms.war в my-dir-node1 / standalone / deploy и your-dir-node2 / standalone / deploy

содержимое моего тестового приложения

<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.jms.*" %>
<%@ page import="java.util.logging.Logger" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%

    Logger logger = Logger.getLogger("JMSSender");
    InitialContext initialContext = new InitialContext();
    ConnectionFactory factory = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
    Destination destination = (Destination)initialContext.lookup("java:/jms/queue/test");
    Connection connection = factory.createConnection();
    Session session1 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageProducer messageProducer = session1.createProducer(destination);

    String body = request.getParameter("message");

    if (body == null)
        body = "Hello World!";

    TextMessage message = session1.createTextMessage(body);

    String delay = request.getParameter("delay");

    if (delay != null)
        message.setJMSDeliveryTime(System.currentTimeMillis() + Integer.parseInt(delay));

    messageProducer.send(message);

    logger.info("Send message: " + body);
%>
<html>
  <head>
    <title>Test JMS Sender</title>
  </head>
  <body>
  <h1>Message</h1>
  <p><strong><%=body%></strong></p>
  <p>Add ?message=xxx to the url to change the message.</p>
  <p>Add ?delay=xxx to the url to schedule a delivery at a later time. The unit of delay is in millisecond. ie: 1 second = 1000 </p>
  </body>
</html>

JMS-приемник:

import org.apache.log4j.Logger;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(mappedName = "testQueue", activationConfig =  {
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
        , @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
        , @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/queue/test")
})
public class JMSReceiver implements MessageListener {

    // Logger for the class
    private static Logger logger = Logger.getLogger(JMSReceiver.class.getName());

    @Override
    public void onMessage(Message message) {
        TextMessage t = (TextMessage) message;
        try {
            logger.info(t.getText());
        } catch (JMSException e) {
            logger.info(e.getMessage());
        }
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

1 Ответ

0 голосов
/ 17 июня 2019

Ваше понимание кластера обмена сообщениями в EAP (и видео, которое вы связали) неверно. Если вы отправляете сообщение 1 в кластер обмена сообщениями в EAP, то это сообщение есть только у узла 1 в кластере. Сообщения не реплицируются между всеми узлами в кластере. Статистика JMS для каждого узла в кластере не обязательно будет синхронизированной.

То, что вы видите, на самом деле является ожидаемым поведением. Кроме того, это то, что демонстрируется в видео, которое вы связали. В видео клиентское приложение отправляет 2 сообщений при каждом запуске. Одно сообщение отправляется на один узел кластера, а второе - на другой узел кластера. Вот почему показатель «Сообщения добавлен» на каждом узле увеличивается и выглядит синхронизированным. Показатель «Сообщения добавлен» на каждом узле увеличивается на 1 при отправке 2 сообщений (1 + 1 = 2). Общее количество сообщений, добавленных в очереди в кластере, можно определить, суммируя «Сообщения, добавленные» от каждого узла в кластере.

Это поведение важно понимать, поскольку оно означает, что если узел в кластере выходит из строя, то все сообщения на этом узле становятся недоступными (как вы заметили). Если вы хотите, чтобы сообщения были доступны в случае сбоя узла, вам необходимо настроить пару «живое / резервное копирование». Обратитесь к документации EAP для получения более подробной информации о том, как этого добиться.

...