如何配置WildFly Swarm 2018.5.0实现跨服务器消息收发?
配置两台WildFly Swarm 2018.5.0服务器实现跨节点消息收发
看起来你已经把单节点的JMS收发跑通了,现在要跨两台服务器实现消息传递,核心是让发送端作为远程客户端连接到消费端的ActiveMQ服务。下面我给你分两台服务器的project-default.yaml配置,还有必要的代码调整细节:
第一台:消息发送端服务器配置
发送端不需要自行启动ActiveMQ服务器,只需配置远程连接工厂,连接到消费端的MQ服务即可。它的project-default.yaml配置如下:
swarm: messaging-activemq: remote-connections: consumer-server: # 自定义远程连接名称 host: 消费端服务器IP # 替换为实际消费端IP,例如192.168.1.100 port: 5445 # WildFly Swarm默认远程JMS端口 connection-factories: remote-jms-connection-factory: # 远程连接工厂,代码中会用到该名称 remote: consumer-server # 关联上方定义的远程连接 logging: pattern-formatters: LOG_FORMATTER: pattern: "%p [%c] %s%e%n" periodic-rotating-file-handlers: FILE: file: path: pathtolog/swarm-sender.log suffix: .yyyy-MM-dd named-formatter: LOG_FORMATTER level: ALL root-logger: handlers: - FILE
发送端代码调整:需要指定注入远程连接工厂的JMSContext,修改MyResource.java:
import javax.annotation.Resource; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.jms.JMSConnectionFactory; import javax.jms.JMSContext; import javax.jms.Topic; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import java.util.logging.Level; import java.util.logging.Logger; @ApplicationScoped @Path("/") public class MyResource { Logger LOG = Logger.getLogger(MyResource.class.getName()); public static final String MY_TOPIC = "/jms/topic/my-topic"; // 注入远程连接工厂对应的JMSContext @Inject @JMSConnectionFactory("java:jboss/exported/jms/remoteConnectionFactory") private JMSContext context; @Resource(lookup = MY_TOPIC) private Topic topic; @GET @Produces("text/plain") public String get() { LOG.log(Level.INFO, "Send Message Hello JMS! to remote server"); context.createProducer().send(topic, "Hello Remote JMS!"); return "sent to remote!"; } }
第二台:消息消费端服务器配置
消费端需要启动ActiveMQ服务器,并配置允许远程连接,同时导出连接工厂供发送端访问。它的project-default.yaml配置如下:
swarm: messaging-activemq: servers: default: jms-queues: my-queue: {} jms-topics: my-topic: {} bindings: netty-connector: socket-binding: messaging # 绑定默认远程端口5445 connection-factories: remote-connection-factory: connectors: - netty-connector entries: - java:jboss/exported/jms/remoteConnectionFactory # 必须导出该JNDI,供远程客户端访问 logging: pattern-formatters: LOG_FORMATTER: pattern: "%p [%c] %s%e%n" periodic-rotating-file-handlers: FILE: file: path: pathtolog/swarm-consumer.log suffix: .yyyy-MM-dd named-formatter: LOG_FORMATTER level: ALL root-logger: handlers: - FILE
消费端代码微调:你的MyTopicMDB.java基本没问题,建议把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; import java.util.logging.Level; import java.util.logging.Logger; @MessageDriven(name = "MyTopicMDB", activationConfig = { @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = MyResource.MY_TOPIC), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), }) public class MyTopicMDB implements MessageListener { Logger LOG = Logger.getLogger(MyTopicMDB.class.getName()); @Override public void onMessage(Message message) { try { String msg = ((TextMessage) message).getText(); LOG.log(Level.INFO, "received remote Message: " + msg); System.out.println("received from remote: " + msg); } catch (JMSException e) { LOG.log(Level.SEVERE, "Error processing message", e); e.printStackTrace(); } } }
注意事项
- 确保两台服务器网络互通,消费端的5445端口未被防火墙拦截
- WildFly Swarm 2018.5.0默认远程JMS端口为5445,若消费端修改过端口,需同步调整发送端配置
- 发送端的JNDI lookup路径必须与消费端导出的一致,
java:jboss/exported/jms/remoteConnectionFactory是标准远程连接工厂路径 - 先启动消费端服务器,再启动发送端,调用发送端的REST接口即可验证跨节点消息收发
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

