我正在运行 WildFly 26.1 并添加了
messaging-activemq
子系统。我想对其进行配置,以便可以通过 https
传输附加远程客户端并来回发送 JMS 消息。我配置 WildFly 的方式似乎工作正常,但是当我尝试附加我的客户端时,我总是遇到异常:
[01-17 16:06:36] [] Failed to connect to server xx.xxx.xx.227:443
javax.jms.JMSException: Failed to create session factory
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:882)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:299)
at com.tpt.common.jmsproxyclient.JMSProxyClient.connect(JMSProxyClient.java:282)
at com.tpt.gelly.ConnectionNegotiator.establishConnection(ConnectionNegotiator.java:886)
at com.tpt.gelly.ConnectionNegotiator.negotiateConnection(ConnectionNegotiator.java:1224)
at com.tpt.gelly.Client.login(Client.java:1254)
at com.tpt.gelly.Client$MultiLoginRunnable.runTraditional(Client.java:1190)
at com.tpt.gelly.Client$MultiLoginRunnable.run(Client.java:1135)
at com.tpt.ui.common.TPRunnable.run(TPRunnable.java:48)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
Caused by: ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ219007: Cannot connect to server(s). Tried with all available servers.]
at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:708)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:880)
... 13 more
如果客户端尝试通过
http
连接,一切正常,但我无法弄清楚通过 https
建立连接需要什么。我想知道如何正确配置 ActiveMQ Artemis 和 Undertow,以及必须在客户端应用程序中设置哪些属性才能通过 https
建立连接。我还想知道在哪里可以找到一些有关 ActiveMQ Artemis 和 Undertow 配置以及 ActiveMQ Artemis 客户端连接器属性的好文档。
我正在使用的 ActiveMQ Artemis 连接器和接受器的 WildFly standalone.xml
配置是:
<subsystem xmlns="urn:jboss:domain:messaging-activemq:13.1">
<server name="default">
<!-- HTTPS connector/acceptor/factory -->
<http-connector name="https-connector" socket-binding="https" endpoint="https-acceptor">
<param name="sslEnabled" value="true"/>
</http-connector>
<http-acceptor name="https-acceptor" http-listener="https"/>
<connection-factory name="HttpsRemoteConnectionFactory" entries="java:jboss/exported/jms/HttpsRemoteConnectionFactory" connectors="https-connector"/>
<!-- HTTPS throughput connector/acceptor -->
<http-connector name="https-connector-throughput" socket-binding="https" endpoint="https-acceptor-throughput">
<param name="batch-delay" value="50"/>
<param name="sslEnabled" value="true"/>
</http-connector>
<http-acceptor name="https-acceptor-throughput" http-listener="https">
<param name="batch-delay" value="50"/>
<param name="direct-deliver" value="false"/>
</http-acceptor>
</server>
</subsystem>
同一文件中 http
和
https
的 Undertow 配置为:
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" ssl-context="smsSSC" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<http-invoker http-authentication-factory="application-http-authentication"/>
</host>
</server>
</subsystem>
尝试远程连接的客户端代码如下。我不使用 JNDI,因为我们不想在外部打开另一个端口。属性名称常量来自 org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants
Map<String, Object> params = new HashMap<>();
params.put(HTTP_UPGRADE_ENDPOINT_PROP_NAME, "https-acceptor");
params.put(ACTIVEMQ_SERVER_NAME, "default");
params.put(HTTP_UPGRADE_ENABLED_PROP_NAME, true);
params.put(PORT_PROP_NAME, 443);
params.put(HOST_PROP_NAME, "host");
params.put(SSL_ENABLED_PROP_NAME, true);
TransportConfiguration transport = new TransportConfiguration("org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory", params);
return ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transport);
我不知道这是否与问题有关,但是 https
socket-binding
在 WildFly 配置中是
8443
,我们使用
sbin/iptables
将端口
443
重新路由到
8443
,然后使用
8443
:阻止
/sbin/iptables\
进行外部访问
/sbin/iptables -t nat -A PREROUTING -p tcp --dport https -j REDIRECT --to-port 8443
# any iptables cmds with 'mark' are to keep the local port closed outside
/sbin/iptables -t mangle -A PREROUTING -p tcp --dport 8443 -j MARK --set-mark 1
/sbin/ip6tables -t mangle -A PREROUTING -p tcp --dport 8443 -j MARK --set-mark 1
<http-connector name="https-connector" socket-binding="https" endpoint="https-acceptor">
<param name="enabled-protocols" value="TLSv1.2"/>
<param name="keyStoreType" value="JKS"/>
<param name="trustStorePassword" value="artemisexample"/>
<param name="verify-host" value="false"/>
<param name="keyStorePassword" value="artemisexample"/>
<param name="trustStorePath" value="${some_path}/cacerts"/>
<param name="trustStoreType" value="PKCS12"/>
<param name="ssl-enabled" value="true"/>
<param name="keyStorePath" value="${some_path}/artemis.example.keystore"/>
</http-connector>
这是 WildFly 到 https 接受器的示例连接器 ^^,配置简单:
<http-acceptor name="https-acceptor" http-listener="undertow-https"/>
和
<https-listener name="undertow-https" socket-binding="https" ssl-context="server-ssl-context"/>
这看起来非常接近你正在做的事情