Я настраиваю кластер EAP 7 в автономном режиме. Я подписался на этот учебник и настроил свой кластер.
Затем я начал тестировать систему JMS с помощью простого приложения JMS. Каждый раз, когда я отправляю сообщение JMS, я наблюдаю, что количество сообщений JMS обновляется только на одном из узлов (вместо обоих узлов, показанных в видео). Общее количество отправленных сообщений равно сумме счетчиков от обоих узлов.
Однако, поскольку узлы сгруппированы, я ожидаю, что статистика JMS будет синхронизирована (что показано на видео), поэтому оба узла должны отображать общее количество сообщений, полученных в кластере, а не только часть из них.
Кроме того, при отправке запланированного сообщения, если узел удерживает сообщение, оно блокируется до тех пор, пока мертвый узел не будет перезапущен. Это определенно неприемлемо, поскольку я ожидаю, что запланированное сообщение будет доставлено другим (работающим) узлом.
Все тесты выполняются с использованием стандартного файла standalone-full-ha.xml.
Вот все шаги, чтобы воспроизвести проблему:
<server xmlns = "urn:jboss:domain:5.0" name = "node1">
<cluster password = "${jboss.messaging.cluster.password:CHANGE ME!!}"/>
и замените его на <cluster password = "${jboss.messaging.cluster.password:mypassword}"/>
<jms-queue name = "JMSTest" entries = "java:/jms/queue/test"/>
после <jms-queue name = "DLQ" entries = "java:/jms/queue/DLQ"/>
Разверните тестовое приложение, скопировав файл 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());
}
}
}
веб.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>
Ваше понимание кластера обмена сообщениями в EAP (и видео, на которое вы ссылаетесь) неверно. Если вы отправляете сообщение 1 в кластер обмена сообщениями в EAP, только узел 1 в кластере имеет это сообщение. Сообщения не реплицируются между всеми узлами в кластере. Статистика JMS для каждой ноды в кластере не будет обязательно должна быть синхронизирована.
То, что вы видите, на самом деле является ожидаемым поведением. Кроме того, это то, что продемонстрировано в видео, которое вы указали. На видео клиентское приложение отправляет сообщения 2 при каждом запуске. Одно сообщение отправляется на один узел кластера, а второе сообщение отправляется на другой узел кластера. Вот почему метрика «Добавленные сообщения» на каждом узле увеличивается и кажется синхронизированной. Метрика «Добавленные сообщения» на каждом узле увеличивается на 1 при отправке 2 сообщений (1+1=2). Общее количество сообщений, добавленных в очереди в кластере, можно определить путем суммирования «Добавленных сообщений» с каждого узла в кластере.
Это поведение важно понимать, поскольку оно означает, что если узел в кластере выходит из строя, все сообщения на этом узле становятся недоступными (как вы заметили). Если вы хотите, чтобы сообщения были доступны в случае сбоя узла, вам необходимо настроить пару «живой/резервный». Обратитесь к документация ЕАР для получения более подробной информации о том, как это сделать.