使用ActiveMQ Artemis发送AMQ消息。

huangapple go评论78阅读模式
英文:

Send AMQ Message using ActiveMQ Artemis

问题

你想要将消息发送到 WildFly 服务器上的 ActiveMQ Artemis 实例,并且在配置 standalone-full.xml 时遇到问题。你使用了 jboss/wildfly Docker 镜像,将 netty 端口暴露为 5445

以下是你的翻译:

  • 你尝试创建一个简单的测试案例,以将消息发送到 ActiveMQ Artemis 实例。
  • 执行时,客户端出现 javax.jms.JMSException: Cannot send, channel has already failed: tcp://127.0.0.1:5445 错误。
  • 服务器上出现 AMQ214013: Failed to decode packet: java.lang.IllegalArgumentException: AMQ219032: Invalid type: 1 错误。
  • 你尝试在 这篇帖子 中查找解决方案,但未找到有用的解决方法。
  • 你想知道在配置 ActiveMQ 实例时是否有遗漏,以及如何使用 Java 代码进行测试。

请告诉我,你需要进一步的帮助或解释吗?

英文:

I want to send a message to an ActiveMQ Artemis instance on a WildFly server. I am using this tutorial in trying to configure the standalone-full.xml. I am using the jboss/wildfly docker image and am exposing the below netty port: 5445.

Standalone configuration:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:10.0">
    <server name="default">
        <security enabled="true"/>
        <security-setting name="#">
            <role name="SuperUser" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
        </security-setting>
        <address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10" redistribution-delay="1000"/>
        <http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/>
        <http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
            <param name="batch-delay" value="50"/>
        </http-connector>
        <in-vm-connector name="in-vm" server-id="0"/>
        <remote-connector name="netty" socket-binding="messaging"/>
        <remote-acceptor name="netty" socket-binding="messaging"/>

        <http-acceptor name="http-acceptor" http-listener="default"/>
        <http-acceptor name="http-acceptor-throughput" http-listener="default">
            <param name="batch-delay" value="50"/>
            <param name="direct-deliver" value="false"/>
        </http-acceptor>
        <in-vm-acceptor name="in-vm" server-id="0"/>

        <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
        <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>
        <jms-queue name="JoeIsCool" entries="java:/jms/queue/JoeIsCool"/>

        <connection-factory name="InVmConnectionFactory" connectors="in-vm" entries="java:/ConnectionFactory"/>
        <connection-factory name="RemoteConnectionFactory" ha="true" block-on-acknowledge="true" reconnect-attempts="-1" connectors="netty" entries="java:jboss/exported/jms/RemoteConnectionFactory"/>
        <pooled-connection-factory name="activemq-ra" transaction="xa" connectors="in-vm" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory"/>
    </server>
</subsystem>


<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">

    ...
    <socket-binding name="messaging" port="5445"/>
    ...

</socket-binding-group>

I tried to create a simple test case that would send a message to the ActiveMQ Artemis instance:

public void sendAmqMessage() throws Exception {
    final ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("admin", "secretPassoword", "tcp://localhost:5445");
    final Connection connection = connectionFactory.createConnection();
    connection.start();
    final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    final Destination destination = session.createQueue("JoeIsCool");
    final MessageProducer producer = session.createProducer(destination);
    final TextMessage message =
    session.createTextMessage("Hello !!! Welcome to the world of ActiveMQ.");
    producer.send(message);
    connection.close();
}

Upon execution, I get this error on my client:

javax.jms.JMSException: Cannot send, channel has already failed: tcp://127.0.0.1:5445

I get this error on my server:

(Thread-1 (activemq-netty-threads)) AMQ214013: Failed to decode packet: java.lang.IllegalArgumentException: AMQ219032: Invalid type: 1

I tried to follow this post in answering my own question but was unable to find a useful solution.

What am I missing in configuring the ActiveMQ instance, and how can I test it with Java code?

答案1

得分: 2

在你的 sendAmqMessage 方法中,你创建了一个 javax.jms.ConnectionFactory 实例,如下所示:

final ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("admin", "secretPassoword", "tcp://localhost:5445");

这个 ActiveMQConnectionFactory 是来自 ActiveMQ 5.x 客户端,并使用了 OpenWire 协议,而你的 standalone-full.xml 中的 remote-acceptor 不理解这个协议,因此会出现有关解码传入备份的错误。

正如你正在遵循的文档所建议的,不要直接实例化 ConnectionFactory,而是应该在 JNDI 中查找它,像这样:

final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
env.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
InitialContext remotingCtx = new InitialContext(env);
final ConnectionFactory connectionFactory = (ConnectionFactory) remotingCtx.lookup("jms/RemoteConnectionFactory");

另外,请确保你使用了正确的依赖,即:

<dependencies>
  <dependency>
    <groupId>org.wildfly</groupId>
    <artifactId>wildfly-jms-client-bom</artifactId>
    <type>pom</type>
  </dependency>
</dependencies>

以这种方式使用 JNDI 还可以允许你从你的 standalone-full.xml 中移除以下内容:

<remote-connector name="netty" socket-binding="messaging"/>
<remote-acceptor name="netty" socket-binding="messaging"/>

以及这个:

<socket-binding name="messaging" port="5445"/>

你实际上只需要在默认的 standalone-full.xml 中定义资源。

英文:

In your sendAmqMessage method you're creating a javax.jms.ConnectionFactory instance like so:

final ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(&quot;admin&quot;, &quot;secretPassoword&quot;, &quot;tcp://localhost:5445&quot;);

This ActiveMQConnectionFactory is from the ActiveMQ 5.x client and uses the OpenWire protocol which the remote-acceptor in your standalone-full.xml doesn't understand, hence the error about failing to decode the incoming backup.

As the documentation you're following suggests, instead of instantiating the ConnectionFactory directly you should simply look it up in JNDI like so:

final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, &quot;org.jboss.naming.remote.client.InitialContextFactory&quot;);
env.put(Context.PROVIDER_URL, &quot;http-remoting://localhost:8080&quot;);
InitialContext remotingCtx = new InitialContext(env);
final ConnectionFactory connectionFactory = (ConnectionFactory) remotingCtx.lookup(&quot;jms/RemoteConnectionFactory&quot;);

Also, make sure you're using the correct dependency, i.e.:

&lt;dependencies&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.wildfly&lt;/groupId&gt;
    &lt;artifactId&gt;wildfly-jms-client-bom&lt;/artifactId&gt;
    &lt;type&gt;pom&lt;/type&gt;
  &lt;/dependency&gt;
&lt;/dependencies&gt;

Using JNDI this way will also allow you to remove this from your standalone-full.xml:

&lt;remote-connector name=&quot;netty&quot; socket-binding=&quot;messaging&quot;/&gt;
&lt;remote-acceptor name=&quot;netty&quot; socket-binding=&quot;messaging&quot;/&gt;

As well as this:

&lt;socket-binding name=&quot;messaging&quot; port=&quot;5445&quot;/&gt;

You really only need the resources defined in the default standalone-full.xml.

huangapple
  • 本文由 发表于 2020年8月11日 20:08:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63357799.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定