Apache ActiveMQ Artemis реализует многопротокольный брокер сообщений с поддержкой STOMP, AMQP, MQTT и собственного Core-протокола. В связке с веб-клиентами наиболее часто используется STOMP поверх WebSocket, где клиентская сторона реализуется через STOMP.js.
Общая схема выглядит следующим образом:
Ключевой момент заключается в том, что STOMP в Artemis не является нативным протоколом маршрутизации сообщений, а транслируется в внутреннюю модель адресов и очередей брокера.
Для работы STOMP через WebSocket в Artemis необходимо включить
соответствующий acceptor в broker.xml.
Основной пример конфигурации:
<acceptors>
<acceptor name="stomp-websocket">
tcp://0.0.0.0:61613?protocols=STOMP;ws.stompPort=61614
</acceptor>
</acceptors>
Дополнительно можно разделить WebSocket-слой:
<acceptor name="stomp-ws">
tcp://0.0.0.0:61613?protocols=STOMP
</acceptor>
<acceptor name="stomp-ws-websocket">
tcp://0.0.0.0:61614?protocols=STOMP;useWebSockets=true
</acceptor>
protocols=STOMP — включение STOMPuseWebSockets=true — активация WebSocket
транспортаws.stompPort — порт для WebSocket подключенияtcp://0.0.0.0 — биндинг на все интерфейсыApache ActiveMQ Artemis использует концепцию address → queue mapping.
STOMP-клиент не работает напрямую с очередями Artemis, он использует:
STOMP.js использует WebSocket как транспортный уровень.
Пример подключения:
import { Client } from '@stomp/stompjs';
const client = new Client({
brokerURL: 'ws://localhost:61614/stomp',
reconnectDelay: 5000,
heartbeatIncoming: 4000,
heartbeatOutgoing: 4000,
});
Artemis поддерживает простую файловую модель пользователей:
etc/login.config и
etc/artemis-users.properties:
admin = admin
user = password
В STOMP.js:
const client = new Client({
brokerURL: 'ws://localhost:61614/stomp',
connectHeaders: {
login: 'user',
passcode: 'password'
}
});
client.onConn ect = () => {
client.subscribe('/queue/orders', (message) => {
console.log('Order:', message.body);
message.ack();
}, {
ack: 'client-individual'
});
};
client.subscribe('/topic/notifications', (message) => {
console.log('Notification:', message.body);
});
Artemis поддерживает несколько режимов ACK:
autoclientclient-individualmessage.ack();
message.ack();
Разница заключается в том, что индивидуальный ACK подтверждает каждое сообщение отдельно, предотвращая повторную доставку при частичных ошибках обработки.
client.publish({
destination: '/queue/orders',
body: JSON.stringify({
orderId: 123,
status: 'created'
}),
headers: {
persistent: 'true'
}
});
Apache ActiveMQ Artemis поддерживает сохранение сообщений в журнал (journal storage).
В STOMP можно управлять поведением через заголовки:
persistent: truepriority: 0–9expiration: timestampПример:
client.publish({
destination: '/queue/orders',
body: 'Important message',
headers: {
persistent: 'true',
priority: '9',
expiration: Date.now() + 60000
}
});
STOMP.js позволяет контролировать живость соединения:
const client = new Client({
brokerURL: 'ws://localhost:61614/stomp',
heartbeatIncoming: 10000,
heartbeatOutgoing: 10000
});
Artemis отвечает heartbeat-фреймами, предотвращая разрыв idle-соединений через прокси и балансировщики.
Artemis поддерживает транзакционную модель STOMP.
client.begin();
client.publish({
destination: '/queue/orders',
body: 'tx message'
});
client.commit();
Rollback:
client.abort();
Транзакции позволяют группировать отправку сообщений как атомарную операцию.
Artemis ограничивает скорость доставки через:
STOMP.js косвенно участвует через настройки подписки:
client.subscribe('/queue/orders', callback, {
'prefetch-size': '50'
});
Для топиков можно использовать durable subscriptions:
client.subscribe('/topic/events', callback, {
durable: 'true',
'client-id': 'app-1',
id: 'sub-1'
});
Artemis сохраняет состояние подписки и доставляет сообщения после переподключения.
STOMP destination трансформируется в internal address:
/queue/orders → address orders, queue
orders/topic/events → address events, multicast
queue setArtemis использует routing type:
Это влияет на поведение доставки независимо от STOMP клиента.
STOMP.js предоставляет события жизненного цикла:
client.onStompEr ror = (frame) => {
console.error('Broker error', frame.headers['message']);
};
client.onWebSocketCl ose = () => {
console.log('Connection closed');
};
Artemis может отправлять ERROR frame при:
Artemis управляет доступом через role-based security:
<security-setting match="queue.orders">
<permission type="send" roles="user"/>
<permission type="consume" roles="user"/>
</security-setting>
STOMP клиент наследует ограничения брокера, и попытка подписки без прав приводит к ERROR frame.
Ключевые практики:
WebSocket acceptor в Artemis работает как транспортная обертка:
При разрыве WebSocket Artemis автоматически освобождает consumer и может сохранить state durable subscription.
Эта цепочка обеспечивает сквозную доставку сообщений от браузера до брокера с контролируемой надежностью и масштабированием.