搜索

7.24. 资源适配器

download PDF

Jakarta Connectors 资源适配器可让您的应用程序与任何消息传递供应商通信。它配置 Jakarta EE 组件(如 MDB 和其他 Jakarta Enterprise Beans)如何发送或接收消息。

7.24.1. 部署 IBM MQ 资源适配器

IBM MQ 是 IBM 提供的消息传递导向中间件(MOM)产品,允许分布式系统上的应用程序相互通信。这可以通过使用消息和消息队列来实现。IBM MQ 负责将消息发送到消息队列,并使用消息通道将数据传送到其他队列管理器。有关 IBM MQ 的更多信息,请参阅 IBM 产品网站上的 IBM MQ

概述

IBM MQ 可以配置为 JBoss EAP 8.0 的外部 Java 消息服务供应商。本节介绍在 JBoss EAP 中部署和配置 IBM MQ 资源适配器的步骤。此部署和配置可以通过管理 CLI 工具或基于 Web 的管理控制台来完成。有关 IBM MQ 支持的配置,请参阅 JBoss EAP 支持的配置。

注意

在配置 IBM MQ 资源适配器后,您必须重启系统才能使配置更改生效。

JBoss EAP 8.0 是一个 Jakarta EE 10 实现,因此用于所有 EE API 的软件包已从 javax 改为 jakarta,这需要 Jakarta EE 10 兼容资源适配器。如果您在 JBoss EAP 7.x 或更早版本中使用 IBM MQ 资源适配器,则必须使用 wmq.jakarta.jakarta.rar,使用这个 jakarta 命名空间的 IBM MQ 资源适配器。

  • wmq.jmsra.rar 删除和取消部署以前的资源适配器配置,并使用 wmq.jakarta.jmsra.rar
  • 根据本节中介绍的步骤,部署 wmq.jakarta.jmsra.rar 并配置。

先决条件

开始之前,您必须验证 IBM MQ 资源适配器的版本并了解其配置属性。

  • IBM MQ 资源适配器作为名为 wmq.jakarta.jmsra.rar 的资源存档(RAR)文件提供。您可以从 /opt/mqm/java/lib/jca/ wmq.jakarta.jmsra.rar 获取 wmq.jakarta.jmsra.rar 文件。如需有关 JBoss EAP 的每个发行版本支持 的特定版本的信息,请参阅 JBoss EAP 支持的配置。
  • 您必须知道以下 IBM MQ 配置值。有关这些值的详情,请参阅 IBM MQ 产品文档。

    • MQ_QUEUE_MANAGER: IBM MQ 队列管理器的名称
    • MQ_HOST_NAME :用于连接 IBM MQ 队列管理器的主机名
    • MQ_CHANNEL_NAME :用于连接到 IBM MQ 队列管理器的服务器频道
    • MQ_QUEUE_NAME :目标队列的名称
    • MQ_TOPIC_NAME :目标主题的名称
    • MQ_PORT :用于连接 IBM MQ 队列管理器的端口
    • MQ_CLIENT :传输类型
  • 对于出站连接,还必须熟悉以下配置值:

    • MQ_CONNECTIONFACTORY_NAME :将提供远程系统连接的连接工厂实例的名称

流程

以下是 IBM 提供的默认配置,可能随时更改。如需更多信息,请参阅 IBM MQ 文档。

  1. 首先,通过将 wmq.jakarta.jmsra.rar 文件复制到 EAP_HOME/standalone/deployments/ 目录中来手动部署资源适配器。
  2. 接下来,使用管理 CLI 添加资源适配器并进行配置。

    /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar:add(archive=wmq.jakarta.jmsra.rar, transaction-support=XATransaction)

    请注意,transaction-support 元素被设置为 XATransaction。在使用事务时,请务必提供 XA 恢复数据源的安全域,如下例所示。

    /subsystem=resource-adapters/resource-adapter=test/connection-definitions=test:write-attribute(name=recovery-security-domain,value=myDomain)

    有关 XA 恢复的更多信息,请参阅 JBoss EAP 7.4 配置指南中的配置 XA 恢复

    对于非事务部署,将 transaction-support 的值改为 NoTransaction

    /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar:add(archive=wmq.jakarta.jmsra.rar, transaction-support=NoTransaction)
  3. 现在创建了资源适配器,您可以在其中添加必要的配置元素。

    1. 为队列添加 admin-object 并配置其属性。

      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=queue-ao:add(class-name=com.ibm.mq.jakarta.connector.outbound.MQQueueProxy, jndi-name=java:jboss/MQ_QUEUE_NAME)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=queue-ao/config-properties=baseQueueName:add(value=MQ_QUEUE_NAME)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=queue-ao/config-properties=baseQueueManagerName:add(value=MQ_QUEUE_MANAGER)
    2. 为主题添加 admin-object 并配置其属性。

      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=topic-ao:add(class-name=com.ibm.mq.jakarta.connector.outbound.MQTopicProxy, jndi-name=java:jboss/MQ_TOPIC_NAME)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=topic-ao/config-properties=baseTopicName:add(value=MQ_TOPIC_NAME)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=topic-ao/config-properties=brokerPubQueueManager:add(value=MQ_QUEUE_MANAGER)
    3. 为受管连接工厂添加连接定义并配置其属性。

      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd:add(class-name=com.ibm.mq.jakarta.connector.outbound.ManagedConnectionFactoryImpl, jndi-name=java:jboss/MQ_CONNECTIONFACTORY_NAME, tracking=false)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=hostName:add(value=MQ_HOST_NAME)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=port:add(value=MQ_PORT)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=channel:add(value=MQ_CHANNEL_NAME)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=transportType:add(value=MQ_CLIENT)
      
      /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=queueManager:add(value=MQ_QUEUE_MANAGER)
  4. 如果要将 JBoss EAP 中的 EJB3 消息传递系统的默认提供程序从 JBoss EAP 8.0 消息改为 IBM MQ,请使用管理 CLI 修改 ejb3 子系统,如下所示:

    /subsystem=ejb3:write-attribute(name=default-resource-adapter-name,value=wmq.jakarta.jmsra.rar)
  5. 在 MDB 代码中配置 @ActivationConfigProperty@ResourceAdapter 注释,如下所示:

    @MessageDriven(name="IbmMqMdb", activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType",propertyValue = "jakarta.jms.Queue"),
        @ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "false"),
        @ActivationConfigProperty(propertyName = "hostName", propertyValue = "MQ_HOST_NAME"),
        @ActivationConfigProperty(propertyName = "port", propertyValue = "MQ_PORT"),
        @ActivationConfigProperty(propertyName = "channel", propertyValue = "MQ_CHANNEL_NAME"),
        @ActivationConfigProperty(propertyName = "queueManager", propertyValue = "MQ_QUEUE_MANAGER"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "MQ_QUEUE_NAME"),
        @ActivationConfigProperty(propertyName = "transportType", propertyValue = "MQ_CLIENT")
    })
    
    @ResourceAdapter(value = "wmq.jakarta.jmsra-VERSION.rar")
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public class IbmMqMdb implements MessageListener {
    }

    务必将 @ResourceAdapter 值中的 VERSION 替换为 RAR 名称中的实际版本。

  6. 激活资源适配器:

    /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar:activate()

7.24.1.1. IBM MQ 资源适配器的限制和已知问题

下表列出了 IBM MQ 资源适配器的已知问题。版本列中的复选标记(mvapich)表示问题是该资源适配器的版本有问题。

表 7.2. IBM MQ 资源适配器的已知问题
JIRA问题描述IBM MQ 9

JBEAP-503

IBM MQ 资源适配器返回 Queue.toString ()QueueBrowser.getQueue ().toString () 方法的不同 String 值。队列com.ibm.mq.connector.outbound.MQQueueProxy 类的实例,它与 com.ibm.mq.jms.MQQueue 类不同,后者由 QueueBrowser.htmlQueueBrowser.getQueue () 方法返回。这些类包含 toString () 方法的不同实现。请注意,您无法依赖这些 toString () 方法返回相同的值。

JBEAP-511, JBEAP-550, JBEAP-3686

以下限制适用于 IBM MQ 的消息属性名称。

  • 在部署描述符的 activation-config 部分中,您无法使用特殊字符(如 _& amp; 或 | )配置 destinationName 属性。使用这些字符会导致 MDB 部署失败,并显示 com.ibm.msg.client.jms.DetailedInvalidDestinationException 异常。
  • 在部署描述符的 activation-config 部分中,您不能使用 java:/ 前缀配置 destinationName 属性。使用此前缀会导致 MDB 部署失败,并显示 com.ibm.msg.client.jms.DetailedInvalidDestinationException 异常。
  • 属性不能以"JMS"或"usr.JMS"开头,因为它们保留供 IBM MQ JMS 类使用。IBM 知识库网站上有例外说明。

有关消息属性名称 限制的完整列表,请参阅 IBM 知识库网站上的 Property 名称 限制。

JBEAP-549

使用 @ActivationConfigProperty 注释为 MDB 指定 destination 属性值时,您必须使用所有大写字母。例如:

@ActivationConfigProperty(propertyName = "destination", propertyValue = "QUEUE")

JBEAP-624

如果使用 IBM MQ 资源适配器在 Jakarta EE 部署中使用 @JMSConnectionFactoryDefinition 注解创建连接工厂,您必须指定 resourceAdapter 属性。否则,部署将失败。

@JMSConnectionFactoryDefinition(
    name = "java:/jms/WMQConnectionFactory",
    interfaceName = "javax.jms.ConnectionFactory",
    resourceAdapter = "wmq.jmsra",
    properties = {
        "channel=<channel>",
        "hostName=<hostname_wmq_broker>",
        "transportType=<transport_type>",
        "queueManager=<queue_manager>"
    }
)

JBEAP-2339

IBM MQ 资源适配器可以从队列和主题读取消息,即使在连接启动前也是如此。这意味着消费者可以在连接启动前使用消息。要避免遇到这个问题,请使用远程 IBM MQ 代理使用 external-context 而不是 IBM MQ 资源适配器创建的连接工厂。

JBEAP-3685

设置了 <transaction-support>XATransaction</transaction-support > 后,一个 JMSContext 始终为 JMSContext.SESSION_TRANSACTED,无论是使用注入还是手动创建。

在以下代码示例中,@JMSSessionMode (JMSContext.DUPS_OK_ACKNOWLEDGE) 被忽略,JMSContext 仍然保持在 JMSContext.SESSION_TRANSACTED

@Inject
@JMSConnectionFactory("jms/CF")
@JMSPasswordCredential(userName="myusername", password="mypassword")
@JMSSessionMode(JMSContext.DUPS_OK_ACKNOWLEDGE)
transient JMSContext context3;

JBEAP-14633

根据 JMS 规范,QueueSession 接口无法用于创建特定于 publish/subscribe 域的对象,以及从 Session 继承的特定方法应抛出 javax.jms.IllegalStateException。一个这样的方法是 QueueSession.createTemporaryTopic ()。IBM MQ 资源适配器不抛出 javax.jms.IllegalStateException,而是抛出 java.lang.NullPointerException

JBEAP-14634

MQTopicProxy.getTopicName () 返回不同的主题名称,而不是由 IBM MQ 代理设置。例如,如果主题名称被设置为 topic://MYTOPIC?XMSC_WMQ_BROKER_PUBQ_QMGR=QM,则 MQTopicProxy 返回 topic://MYTOPIC

JBEAP-14636

JMSContext 的默认 autoStart 设置为 false,这意味着在创建消费者时不自动启动 JMSContext 使用的底层连接。此设置应默认为 true

JBEAP-14640

当使用无效凭证时,IBM MQ 资源适配器会抛出 DetailedJMSException 而不是 JMSSecurityException,并将以下错误记录到服务器控制台。

WARN  [org.jboss.jca.core.connectionmanager.pool.strategy.PoolByCri] (EJB default - 7) IJ000604: Throwable while attempting to get a new connection: null: com.ibm.mq.connector.DetailedResourceException: MQJCA1011: Failed to allocate a JMS connection., error code: MQJCA1011 An internal error caused an attempt to allocate a connection to fail. See the linked exception for details of the failure.

以下是可能导致此问题的代码示例。

QueueConnection qc = queueConnectionFactory.createQueueConnection("invalidUserName", "invalidPassword");

JBEAP-14642

由于 MQMessageProducer.send (Destination destination, Message message)MQMessageProducer.send (Destination destination, Message message, int deliveryMode, int priority, CompletionListener completionListener) 方法中的资源适配器的无效类 cast 转换,并将以下错误消息记录到服务器控制台。

SVR-ERROR: Expected JMSException, received com.ibm.mq.connector.outbound.MQQueueProxy cannot be cast to com.ibm.mq.jms.MQDestination

这是因为队列或主题查找中使用的 JNDI 名称是 com.ibm.mq.connector.outbound.MQQueueProxy/MQTopicProxy

JBEAP-14643

JMSProducer 接口上的 setDeliveryDelay (expDeliveryDelay) 方法不会改变设置。调用此方法后,它保留在默认设置 0。

JBEAP-14670

如果在 UserTransaction.begin () 之前创建的 QueueSession 上完成工作,则该工作不被视为事务的一部分。这意味着,使用此会话发送到队列的任何消息都不会由 UserTransaction.commit () 提交,在 UserTransaction.rollback () 后,消息将保留在队列中。

JBEAP-14675

如果您关闭连接,然后立即使用相同的 clientID 创建 JMSContext,IBM MQ 资源适配器会间歇性将以下错误记录到服务器控制台。

ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /jmsServlet-1.0-SNAPSHOT/: com.ibm.msg.client.jms.DetailedJMSRuntimeException: MQJCA0002: An exception occurred in the IBM MQ layer. See the linked exception for details.
A call to IBM MQ classes for Java(tm) caused an exception to be thrown.

当与同一 clientID 的连接关闭后创建新的 JMSContext 时,不会出现这个问题。

JBEAP-15535

如果有状态会话 bean 会尝试在容器管理事务(CMT)中发送消息到主题,则消息发送会失败,并显示以下信息:

SVR-ERROR: com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ2007: Failed to send a message to destination 'MDB_NAME TOPIC_NAME'

堆栈追踪显示由以下异常导致的:

com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2072' ('MQRC_SYNCPOINT_NOT_AVAILABLE')
 

JBEAP-25561

当消息通过 JMSReplyTo 标头集发送到目的地时,会在到达 IBM MQ 9 代理后修改该消息。因此,响应的回复消息会被定向到修改后的 JMS_REPLY 标头中定义的目的地。

例如,如果 JMSReplyTo 标头被设置为队列,名称为 queue:///MYQUEUE,使用标头 message.setJMSReplyTo (queue); 并发送到名为 QM 的队列管理器的 IBM MQ 9.3 代理,其名称更改为 queue://QM/MYQUEUE

7.24.2. 删除 Apache Log4j 版本 1 API

从 JBoss EAP 8 开始,停止了对 Apache Log4j 版本 1 API 的支持。任何未打包 log4j.jarlog4j 配置的应用程序都必须更新。

影响:

日志消息将不再基于 logging 子系统进行路由。如果应用程序没有打包 log4j.jar,且以下任何语句都为 true,则需要迁移更改:

  • 如果您在部署中使用 log4j,且没有包含 log4j 配置文件,则必须迁移到新的日志 facade 或向部署中添加 log4j 配置。
  • 如果您在部署中使用 log4j.xmllog4j.propertiesjboss-log4j.xml 文件,且没有打包应用程序中的 log4j.jar。如果它是一个 jboss-log4j.xml 文件,您必须将该文件重命名为 log4j.xml
  • 如果您在 custom-handler 中的 JBoss EAP Logging 子系统中使用 log4j v1 附加器,它将不再被支持。
  • 如果应用类导入类,如 org.apache.log4j.Logger
  • 如果应用程序包含 jboss-deployment-structure.xml 或在 MANIFEST . MF 中指定依赖项,则需要删除这些依赖项。 

迁移:

  • 更新应用类以使用 Apache Log4jv2 类,或使用 JBoss EAP 8 提供的其他日志记录 API 之一。
  • org.apache.log4j.Logger (log4j v1) 类更改为 org.apache.logging.log4j.Logger (log4j v2)
  • 如果应用程序软件包 log4j.propertieslog4j.xmljboss-log4j.xml,您必须:

    • 在 JBoss EAP 配置中配置日志。
    • 在应用程序中配置 logging.properties,因为应用程序不支持 log4jv2 配置文件。

或者

  • 在应用中打包 Apache Log4j 版本 1 JAR,而不是根据 Logging API 的 JBoss EAP 8 打包。您还可以通过 logging 子系统上的 jboss-deployment-structure.xml exclude-subsystems 从应用程序中排除 JBoss Logging API。

额外详情:

为特定部署禁用隐式日志记录依赖项
  • 在应用程序的 jboss-deployment-structure.xml 中,配置 exclude-subsystems 以排除 logging 子系统,例如:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
  <deployment>
    <exclude-subsystems>
      <subsystem name="logging"/>
    </exclude-subsystems>
  </deployment>
</jboss-deployment-structure>
  • 如果应用程序是 EAR 文件,并且有一个名为 example.war 的子部署,则 jboss-deployment-structure.xml 文件位于 EAR 文件位置 / META-INF/jboss-deployment-structure.xml,在子部署中声明它将排除该子系统,例如:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
  <sub-deployment name="example.war">
    <exclude-subsystems>
      <subsystem name="logging"/>
    </exclude-subsystems>
  </sub-deployment>
</jboss-deployment-structure>
为所有部署禁用隐式日志记录依赖项

要使日志记录 API 默认对部署不可用,请使用以下 CLI 命令将 add-logging-api-dependencies 设置为 false

/subsystem=logging:write-attribute(name="add-logging-api-dependencies", value="false")

要将 JBoss 模块和日志记录 API 设置为依赖项,请修改 jboss-deployment-structure.xmlMANIFEST.MF 配置文件:

<subsystem xmlns="urn:jboss:domain:logging:8.0">
    <add-logging-api-dependencies value="false"/>
  ...
</subsystem>
注意

如果应用程序软件包了 Apache Log4j v1 JARs 和 log4j 配置,则应用不再由 EAP 管理。* 应用程序不应该尝试因为意外结果写入 server.log,因为应该将日志框架写入特定的日志文件。

如需更多信息,请参阅 JBoss EAP 8.0 中不再提供 Apache Log4j 版本 1

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.