使用 AMQ 核心协议 JMS 客户端
用于 AMQ 客户端 2.10
摘要
使开源包含更多
红帽承诺替换我们的代码、文档和网页属性中存在问题的语言。我们从这四个术语开始: master、slave、blacklist 和 whitelist。这些更改将在即将发行的几个发行本中逐渐实施。详情请查看 CTO Chris Wright 信息。
第 1 章 概述
AMQ 核心协议 JMS 是 Java 消息服务(JMS)2.0 客户端,用于发送和接收 Artemis 核心协议消息的消息传递应用程序。
AMQ 核心协议 JMS 是 AMQ 客户端的一部分,这是一套支持多种语言和平台的消息传递库。有关客户端的概述,请参阅 AMQ 客户端概述。有关此发行版本的详情,请参考 AMQ Clients 2.10 发行注记。
AMQ 核心协议 JMS 基于 Apache ActiveMQ Artemis 的 JMS 实施。如需有关 JMS API 的更多信息,请参阅 JMS API 参考 和 JMS 教程。
1.1. 主要特性
- JMS 1.1 和 2.0 兼容
- 用于安全通信的 SSL/TLS
- 自动重新连接和故障转移
- 分布式事务(XA)
- 纯 Java 实施
1.2. 支持的标准和协议
AMQ 核心协议 JMS 支持以下业界认可的标准和网络协议:
- Java Message Service API 版本 2.0
- 传输层安全( TLS)协议的版本 1.0、1.1、1.2 和 1.3,后跟 SSL
- 使用 IPv6的现代 TCP
1.3. 支持的配置
如需当前与 AMQ 内核协议 JMS 支持的配置相关的信息,请参阅红帽客户门户网站中的 Red Hat AMQ 7 支持的配置。
1.4. 术语和概念
本节介绍核心 API 实体,并描述它们如何协同运作。
表 1.1. API 术语
| 实体 | 描述 |
|---|---|
|
| 用于创建连接的入口点。 |
|
| 个网络上两个同级之间的通信通道。它包含会话。 |
|
| 用于生成和使用消息的环境。它包含消息制作者和消费者。 |
|
| 用于将消息发送到目的地的频道。它具有目标目的地。 |
|
| 从目的地接收消息的频道。它具有源目的地。 |
|
| 消息的指定位置,可以是队列,也可以是主题。 |
|
| 存储的消息序列. |
|
| 存储的用于多播分发的消息序列。 |
|
| 特定于应用的信息。 |
AMQ 核心协议 JMS 发送和接收 消息。消息使用消息生产者和消费者 在连接的对等点之间传输 。生产者和消费者通过 会话 建立。通过 连接 建立会话。连接由连接工厂 创建。
发送对等点会创建一个制作者来发送消息。制作者具有在远程同级上标识目标队列或主题 的目的地。接收方创建接收消息的消费者。与制作者一样,消费者也有在远程同级上标识源队列或主题的目的地。
目标是 队列 或 主题。在 JMS 中,队列和主题是包含消息的指定代理实体的客户端显示。
队列实施点对点语义。每条消息仅能被一个使用者看到,消息会在读取后从队列中删除。主题实施发布与订阅语义。每条消息都由多个使用者看到,该消息在读取后可供其他消费者使用。
如需更多信息,请参阅 JMS 指南。
1.5. 文档惯例
sudo 命令
在本文档中,sudo 用于任何需要 root 权限的命令。使用 sudo 时要小心,因为任何更改都可能会影响整个系统。有关 sudo 的详情请参考 使用 sudo 命令。
文件路径
在这个文档中,所有文件路径都对 Linux、UNIX 和类似操作系统有效(例如 /home/andrea)。在 Microsoft Windows 中,您必须使用等效的 Windows 路径(例如 C:\Users\andrea)。
变量文本
本文档包含代码块,它们需要使用特定于环境的值替换。变量文本括在箭头大括号内,样式为圆形单空间。例如,在以下命令中,将 <project-dir> 替换为您的环境的值:
$ cd <project-dir>第 2 章 安装
本章指导您完成在您的环境中安装 AMQ 核心协议 JMS 的步骤。
2.1. 先决条件
- 您必须有 订阅 才能访问 AMQ 发行文件和存储库。
- 要使用 AMQ 核心协议 JMS 构建程序,您必须安装 Apache Maven。
- 要使用 AMQ 核心协议 JMS,您必须安装 Java。
2.2. 使用 Red Hat Maven 存储库
配置您的 Maven 环境,以从红帽 Maven 存储库下载客户端库。
流程
将红帽存储库添加到您的 Maven 设置或 POM 文件。如需示例配置文件,请参阅 第 B.1 节 “使用在线存储库”。
<repository> <id>red-hat-ga</id> <url>https://maven.repository.redhat.com/ga</url> </repository>
将库依赖关系添加到您的 POM 文件。
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>artemis-jms-client</artifactId> <version>2.16.0.redhat-00022</version> </dependency>
该客户端现在在 Maven 项目中可用。
2.3. 安装本地 Maven 存储库
作为在线存储库的替代选择,可以将 AMQ 核心协议 JMS 作为基于文件的 Maven 存储库安装到您的本地文件系统中。
流程
- 使用您的订阅 下载 AMQ Broker 7.8.2 Maven 存储库 .zip 文件。
将文件内容提取到您选择的目录中。
在 Linux 或 UNIX 中,使用
unzip命令提取文件内容。$ unzip amq-broker-7.8.2-maven-repository.zip
在 Windows 上,右键单击 .zip 文件并选择" 提取所有"。
-
配置 Maven,以使用提取的安装目录中
maven-repository目录中的存储库。如需更多信息,请参阅 第 B.2 节 “使用本地存储库”。
2.4. 安装示例
流程
- 使用您的订阅 下载 AMQ Broker 7.8.2 .zip 文件。
将文件内容提取到您选择的目录中。
在 Linux 或 UNIX 中,使用
unzip命令提取文件内容。$ unzip amq-broker-7.8.2.zip
在 Windows 上,右键单击 .zip 文件并选择" 提取所有"。
当您提取 .zip 文件的内容时,将创建一个名为
amq-broker-7.8.2的目录。这是安装的顶级目录,在整个文档中被称为<install-dir>。
第 3 章 入门
本章将引导您完成设置环境并运行简单消息传递程序的步骤。
3.1. 先决条件
3.2. 运行第一个示例
这个示例为名为 exampleQueue 的队列创建使用者和制作者。它发送文本消息,然后接收回消息,将收到的消息打印到控制台。
流程
通过在
<install-dir>/examples/features/standard/queue目录中运行以下命令来使用 Maven 构建示例。$ mvn clean package dependency:copy-dependencies -DincludeScope=runtime -DskipTests
添加
dependency:copy-dependencies会导致依赖项复制到target/dependency目录中。使用
java命令来运行示例。在 Linux 或 UNIX 中:
$ java -cp "target/classes:target/dependency/*" org.apache.activemq.artemis.jms.example.QueueExample
在 Windows 中:
> java -cp "target\classes;target\dependency\*" org.apache.activemq.artemis.jms.example.QueueExample
例如,在 Linux 上运行它会产生以下输出:
$ java -cp "target/classes:target/dependency/*" org.apache.activemq.artemis.jms.example.QueueExample Sent message: This is a text message Received message: This is a text message
这个示例的源代码位于 <install-dir>/examples/features/standard/queue/src 目录中。<install-dir>/examples/features/standard 目录中提供了其他示例。
第 4 章 Configuration
本章介绍了将 AMQ 核心协议 JMS 实施绑定到您的 JMS 应用并设置配置选项的流程。
JMS 使用 Java 命名目录接口(JNDI)来注册和查找 API 实施和其他资源。这可让您编写代码到 JMS API,而不将它与特定的实施关联。
配置选项作为连接 URI 上的查询参数公开。
4.1. 配置 JNDI 初始上下文
JMS 应用使用从 InitialContextFactory 获取的 JNDI InitialContext 对象来查找 JMS 对象,如连接工厂。AMQ 核心协议 JMS 在 org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory 类中提供 InitialContextFactory 的实施。
当 InitialContext 对象被实例化时,InitialContextFactory 实现会被发现:
javax.naming.Context context = new javax.naming.InitialContext();
要查找实施,必须在您的环境中配置 JNDI。实现这一目标的方法有三种:使用 jndi.properties 文件、使用系统属性或使用初始上下文 API。
使用 jndi.properties 文件
创建名为 jndi.properties 的文件,并将其放置在 Java 类路径中。使用键 java.naming.factory.initial 添加属性。
示例:使用 jndi.properties 文件设置 JNDI 初始上下文工厂
java.naming.factory.initial = org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
在基于 Maven 的项目中,jndi.properties 文件放置在 <project-dir>/src/main/resources 目录中。
使用系统属性
设置 java.naming.factory.initial 系统属性。
示例:使用系统属性设置 JNDI 初始上下文工厂
$ java -Djava.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory ...
使用初始上下文 API
使用 JNDI 初始上下文 API 以编程方式设置属性。
示例:以编程方式设置 JNDI 属性
Hashtable<Object, Object> env = new Hashtable<>();
env.put("java.naming.factory.initial", "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
InitialContext context = new InitialContext(env);
请注意,您可以使用同一 API 为连接工厂、队列和主题设置 JNDI 属性。
4.2. 配置连接工厂
JMS 连接工厂是创建连接的入口点。它使用对应用特定配置设置进行编码的连接 URI。
要设置工厂名称和连接 URI,请按照以下格式创建一个属性:您可以将该配置存储在 jndi.properties 文件中,或者设置对应的系统属性。
连接工厂的 JNDI 属性格式
connectionFactory.<lookup-name> = <connection-uri>
例如,这是您可以如何配置一个名为 app1 的工厂:
示例:在 jndi.properties 文件中设置连接工厂
connectionFactory.app1 = tcp://example.net:61616?clientID=backend
然后,您可以使用 JNDI 上下文使用名称 app1 来查找配置的连接工厂:
ConnectionFactory factory = (ConnectionFactory) context.lookup("app1");4.3. 连接 URI
连接配置使用连接 URI。连接 URI 指定远程主机、端口和一组配置选项,这些选项设置为查询参数。有关可用选项的详情请参考 第 5 章 配置选项。
连接 URI 格式
tcp://<host>:<port>[?<option>=<value>[&<option>=<value>...]]
例如,以下连接 URI 通过端口 61616 连接到主机 example.net,并将客户端 ID 设置为 backend :
示例:连接 URI
tcp://example.net:61616?clientID=backend
除了 tcp 外,AMQ 核心协议 JMS 也支持 vm、udp 和 jgroups 方案。这些代表备用传输,并在代理中配置相应的接收器。
故障切换 URI
URI 可以包含多个目标连接 URI。如果到一个目标的初始连接失败,则会尝试另一个目标。它们采用以下形式:
故障转移 URI 格式
(<connection-uri>[,<connection-uri>])[?<option>=<value>[&<option>=<value>...]]
括号之外的选项会应用到所有连接 URI。
4.4. 配置队列和主题名称
JMS 提供使用 JNDI 来查找特定于部署的队列和主题资源的选项。
要在 JNDI 中设置队列和主题名称,请使用以下格式创建属性:将此配置放在 jndi.properties 文件中,或者设置对应的系统属性。
队列和主题的 JNDI 属性格式
queue.<lookup-name> = <queue-name> topic.<lookup-name> = <topic-name>
例如,以下属性为两个特定于部署的资源定义名称 jobs 和 notifications :
示例:在 jndi.properties 文件中设置队列和主题名称
queue.jobs = app1/work-items topic.notifications = app1/updates
然后,您可以根据 JNDI 名称查找资源:
Queue queue = (Queue) context.lookup("jobs");
Topic topic = (Topic) context.lookup("notifications");第 5 章 配置选项
本章列出了 AMQ 核心协议 JMS 的可用配置选项。
JMS 配置选项设置为连接 URI 上的查询参数。如需更多信息,请参阅 第 4.3 节 “连接 URI”。
5.1. 常规选项
- user
- 客户端用于验证连接的用户名。
- password
- 客户端用于验证连接的密码。
- clientID
- 客户端应用到连接的客户端 ID。
- groupID
- 客户端应用到所有生成的消息的组 ID。
- autoGroup
- 如果启用,生成随机组 ID 并将其应用到所有生成的消息。
- preAcknowledge
- 如果启用,请在邮件发送后并在发送完成之前确认消息。这"几乎一次"交付。它默认是禁用的。
- blockOnDurableSend
- 如果启用,在发送非传输的持久消息时,将阻止,直到远程同级确认收到。它会被默认启用。
- blockOnNonDurableSend
- 如果启用,在发送非可传输的不可传输消息时,将阻止,直到远程同级确认接收。它默认是禁用的。
- blockOnAcknowledge
- 如果启用,则在拒绝未翻译的接收消息时,将阻止,直到远程同级确认确认确认。它默认是禁用的。
- callTimeout
- 等待阻止调用完成的时间(毫秒)。默认值为 30000(30 秒)。
- callFailoverTimeout
- 当客户端正在出现故障时,在启动阻止调用前,millisconds 中的时间需要等待。默认值为 30000(30 秒)。
- ackBatchSize
- 在将确认发送到代理之前,客户端可以接收和确认的字节数。默认值为 1048576(1 MiB)。
- dupsOKBatchSize
-
使用
DUPS_OK_ACKNOWLEDGE确认模式时,以确认批处理为单位的大小。默认值为 1048576(1 MiB)。 - transactionBatchSize
- 在交易中收到混乱时,以确认批为单位为单位的大小。默认值为 1048576(1 MiB)。
- cacheDestinations
- 如果启用,缓存目的地查找。它默认是禁用的。
5.2. TCP 选项
- tcpNoDelay
- 如果启用,则不要延迟,也不会缓冲 TCP。它会被默认启用。
- tcpSendBufferSize
- 发送缓冲区大小,以字节为单位。默认值为 32768(32 KiB)。
- tcpReceiveBufferSize
- 接收缓冲区大小(以字节为单位)。默认值为 32768(32 KiB)。
- writeBufferLowWaterMark
- 写入缓冲区在下面变为可写的以字节为单位的限制。默认值为 32768(32 KiB)。
- writeBufferHighWaterMark
- 写入缓冲区变得不可写入的以字节为单位的限制。默认值为 131072(128 KiB)。
5.3. SSL/TLS 选项
- sslEnabled
- 如果启用,使用 SSL/TLS 验证和加密连接。它默认是禁用的。
- keyStorePath
-
到 SSL/TLS 密钥存储的路径。mutual SSL/TLS 身份验证需要密钥存储。如果未设置,则使用
javax.net.ssl.keyStore系统属性的值。 - keyStorePassword
-
SSL/TLS 密钥存储的密码。如果未设置,则使用
javax.net.ssl.keyStorePassword系统属性的值。 - trustStorePath
-
SSL/TLS 信任存储的路径。如果未设置,则使用
javax.net.ssl.trustStore系统属性的值。 - trustStorePassword
-
SSL/TLS 信任存储的密码。如果未设置,则使用
javax.net.ssl.trustStorePassword系统属性的值。 - trustAll
- 如果启用,请隐式信任提供的服务器证书,无论配置的信任存储是什么。它默认是禁用的。
- verifyHost
- 如果启用,验证连接主机名是否与提供的服务器证书匹配。它默认是禁用的。
- enabledCipherSuites
- 要启用的密码套件的逗号分隔列表。如果未设置,则使用 JVM 默认密码。
- enabledProtocols
- 要启用的 SSL/TLS 协议的逗号分隔列表。如果未设置,则使用 JVM 默认协议。
5.4. 故障切换选项
- initialConnectAttempts
- 在第一次成功连接前以及客户端发现代理拓扑之前允许的重新连接次数。默认值为 0,表示只允许一次尝试。
- failoverOnInitialConnection
- 如果启用,则尝试在初始连接失败时连接到备份服务器。它默认是禁用的。
- reconnnectAttempts
- 在将连接报告失败前允许的重新连接次数。默认值为 -1,即没有限制。
- retryInterval
- 重新连接尝试之间的时间(毫秒)。默认值为 2000(2 秒)。
- retryIntervalMultiplier
- 用于增大重试间隔的倍数。默认值为 1.0,即相等的间隔。
- maxRetryInterval
- 重新连接尝试之间的最长时间(毫秒)。默认值为 2000(2 秒)。
- ha
- 如果启用,跟踪 HA 代理拓扑中的更改。URI 中的主机和端口仅用于初始连接。在初始连接后,客户端会接收当前的故障切换端点以及由拓扑更改生成的任何更新。它默认是禁用的。
- connectionTTL
- 如果服务器未发送 ping 数据包,则连接失败的时间以毫秒为单位。默认值为 60000(1 分钟)。-1 会禁用超时。
- confirmationWindowSize
- 命令重播缓冲区的大小(以字节为单位)。这可用于重新连接时自动重新连接会话。默认值为 -1,即没有自动重新附加。
- clientFailureCheckPeriod
- 死连接检查之间的时间(毫秒)。默认值为 30000(30 秒)。-1 禁用检查。
5.5. 流控制选项
如需更多信息,请参阅 第 8 章 流控制。
- consumerWindowSize
- 每个使用者消息的大小(以字节为单位)假定缓冲区。默认值为 1048576(1 MiB)。-1 表示没有限制。0 禁用预取.
- consumerMaxRate
- 每秒消耗的消息数量上限。默认值为 -1,即没有限制。
- producerWindowSize
- 请求的大小,以字节为单位,用于生成更多信息。这限制了一次中的数据总量。默认值为 1048576(1 MiB)。-1 表示没有限制。
- producerMaxRate
- 每秒生成的消息的最大数量。默认值为 -1,即没有限制。
5.6. 负载平衡选项
- useTopologyForLoadBalancing
- 如果启用,使用集群拓扑进行连接负载平衡。它会被默认启用。
- connectionLoadBalancingPolicyClassName
-
连接负载平衡策略的类名称。默认值为
org.apache.activemq.artemis.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy。
5.7. 大消息选项
客户端可以通过为属性 minLargeMessageSize 设置值来启用大型消息支持。任何大于 minLargeMessageSize 的消息都被视为一个大信息。
- minLargeMessageSize
- 消息被视为大消息的最小字节大小。默认值为 102400(100 KiB)。
- compressLargeMessages
如果启用,压缩大型信息,如
minLargeMessageSize定义。它默认是禁用的。注意如果大消息的压缩大小小于
minLargeMessageSize的值,则该消息将作为常规消息发送。因此,它不会写入代理的大消息数据目录。
5.8. 线程选项
- useGlobalPools
-
如果启用,为所有
ConnectionFactory实例使用一个线程池。否则,为每个实例使用单独的池。它会被默认启用。 - threadPoolMaxSize
- 常规线程池中的最大线程数。默认值为 -1,即没有限制。
- scheduledThreadPoolMaxSize
- 线程池中用于调度操作的最大线程数。默认值为 5。
第 6 章 网络连接
6.1. 自动故障切换
客户端可以接收所有 master 和从代理的信息,以便在连接失败时可以重新连接到从代理。然后从代理会在故障转移前自动重新创建每个连接上存在的任何会话和消费者。此功能使您不必在应用程序中手动编码重新连接逻辑。
在从卷上重新创建会话时,它不知道已经发送或确认的消息。故障切换时的任何内部发送或确认也可能丢失。但是,即便没有透明故障转移,也很容易通过将重复检测和重试事务结合使用,保证 一次并仅 一次交付一次(即便在故障的情况下也是如此)。
当客户端没有在可配置的时间段内从代理接收数据包时,客户端会检测到连接失败。如需更多信息,请参阅 第 6.3 节 “检测死连接”。
您有多种方法可将客户端配置为接收关于主从和从设备的信息。种选择是将客户端配置为连接到特定代理,然后接收集群中其他代理的信息。如需更多信息,请参阅 第 6.7 节 “配置静态发现”。但是,最常见的方法是使用 代理发现。有关如何配置代理发现的详情请参考 第 6.6 节 “配置动态发现”。
另外,您可以通过在用于连接到代理的 URI 的查询字符串中添加参数来配置客户端,如下例所示。
connectionFactory.ConnectionFactory=tcp://localhost:61616?ha=true&reconnectAttempts=3
流程
要使用查询字符串配置客户端进行故障转移,请确保正确设置了 URI 的以下组件:
-
URI 的
host:port部分必须指向正确配置了备份的 master 代理。此主机和端口仅用于初始连接。host:port值与实时和备份服务器之间的实际连接故障切换无关。在上例中,localhost:61616用于host:port。 (可选)要使用多个代理作为可能的初始连接,对
host:port条目进行分组,如下例所示:connectionFactory.ConnectionFactory=(tcp://host1:port,tcp://host2:port)?ha=true&reconnectAttempts=3
-
包含 name-value 对
ha=true作为查询字符串的一部分,以确保客户端接收集群中每个 master 和 slave 代理的信息。 -
包含 name-value 对
reconnectAttempts=n,其中n是一个大于 0 的整数。这个参数设置客户端试图重新连接到代理的次数。
只有在 ha=true 和 reconnectAttempts 大于 0 时才会发生故障切换。另外,客户端还必须与 master 代理进行初始连接,以便接收有关其他代理的信息。如果初始连接失败,客户端只能重试来建立它。如需更多信息,请参阅 第 6.1.1 节 “在初始连接中切换失败”。
6.1.1. 在初始连接中切换失败
由于客户端直到第一次连接到 HA 集群后才会收到每个代理的信息,因此有一个时间窗口,客户端只能连接到连接 URI 中包含的代理。因此,如果初始连接期间发生故障,客户端无法切换到其他 master 代理,只能尝试重新建立初始连接。可以为一组重新连接尝试数配置客户端。尝试次数之后,将引发异常。
设置重新连接尝试数
以下示例演示了如何使用 AMQ 核心协议 JMS 客户端将重新连接尝试数设置为 3。默认值为 0,即,只尝试一次。
流程
通过将值传递给 ServerLocator.setInitialConnectAttempts() 来设置重新连接尝试的数量。
ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setInitialConnectAttempts(3);
设置全局重新连接尝试数
另外,您可以为代理配置中的最大重新连接尝试数应用全局值。最大值将应用到所有客户端连接。
流程
通过添加 initial-connect-attempts 配置元素并为生存时间提供值来编辑 <broker-instance-dir>/etc/broker.xml,如下例所示。
<configuration>
<core>
...
<initial-connect-attempts>3</initial-connect-attempts> 1
...
</core>
</configuration>- 1
- 所有连接到代理的客户端最多允许 3 个尝试重新连接。默认值为 -1,它允许客户端无限尝试。
6.1.2. 在故障转移期间处理阻塞调用
当发生故障转移时,客户端正在等待代理的响应继续执行,新创建的会话不知道该调用正在进行中。否则,初始调用可能会永远挂起,等待绝不会发出的响应。为防止这种情况,代理被设计为通过抛出异常来取消阻止任何在故障转移时正在进行中的调用。客户端代码可以捕获这些异常,并在需要时重试任何操作。
使用 AMQ 核心协议 JMS 客户端时,如果未阻塞的方法是调用 commit() 或 prepare(),则会自动回滚事务,代理抛出异常。
6.1.3. 使用事务处理故障转移
使用 AMQ 核心协议 JMS 客户端时,如果会话是事务性的,并且消息已在当前事务中发送或确认,代理无法确定这些消息或者在故障转移过程中丢失了这些消息。因此,事务被标记为回滚。任何后续尝试提交它都会抛出 javax.jms.TransactionRolledBackException。
应注意此规则何时使用 XA。如果使用了两阶段提交并且调用了 prepare(),回滚可能会导致 HeuristicMixedException。因此,提交会引发 XAException.XA_RETRY 异常,它会通知 Transaction Manager 在稍后应重试提交。如果原始提交未发生,则它仍然存在并可提交。如果提交不存在,则假定已提交,但事务管理器可能会记录警告。这个例外的一个副作用是所有非持久性信息都会丢失。为避免此类损失,在使用 XA 时始终使用持久消息。这不是确认问题,因为在调用 prepare() 前,它们会被刷新到代理中。
AMQ 核心协议 JMS 客户端代码必须捕获异常并执行任何必要的客户端侧回滚。不过,不需要回滚会话,因为它已经回滚。然后,用户可以在同一会话中再次重试事务操作。
如果在执行提交调用时发生故障转移,代理会取消阻塞调用,以防止 AMQ 核心协议 JMS 客户端无限期等待响应。因此,在出现故障前,客户端无法确定事务提交是否真正在 master 代理上处理。
为补救这一点,AMQ 核心协议 JMS 客户端可以在事务中启用重复检测,并在未阻塞调用后重试事务操作。如果在故障转移前在 master 代理上成功提交事务,重复检测可确保在代理一侧忽略事务中的任何持久消息。这可防止发送多次消息。
如果会话非事务性,则在故障转移时可能会丢失消息或确认。如果您要为非转换会话 提供一次且仅一次 的保证,请启用重复检测并捕获未阻塞异常。
6.1.4. 收到连接失败通知
JMS 提供了一种标准机制,用于获得异步连接失败通知: java.jms.ExceptionListener。
当连接失败时,代理会始终调用 ExceptionListener 或 SessionFailureListener 实例,无论连接是成功通过、重新连接还是重新附加。您可以通过检查 SessionFailureListener 上在 connectionFailed 中传递的 failedOver 标记来找出是否发生了重新连接或重新附加。另外,您可以检查 javax.jms.JMSException 的错误代码,可以是以下之一:
表 6.1. JMSException 错误代码
| 错误代码 | 描述 |
|---|---|
| 故障切换 | 故障转移已经发生,代理已成功重新附加或重新连接 |
| 断开连接 | 没有发生故障切换,代理断开连接 |
6.2. 应用程序级别的故障切换
在某些情况下,您可能不希望自动客户端故障转移,但更喜欢在故障处理程序中自行编码重新连接逻辑。这称为 应用级别的 故障转移,因为故障转移是在应用级别上处理的。
要在使用 JMS 时实施应用级别的故障转移,请在 JMS 连接中设置 ExceptionListener 类。当检测到连接失败时,代理会调用 ExceptionListener。在 ExceptionListener 中,您应该关闭旧的 JMS 连接。您可能还希望从 JNDI 查找新的连接工厂实例并创建新连接。
6.3. 检测死连接
只要它从代理接收数据,客户端就会认为连接处于活动状态。通过为 client-failure-check-period 属性提供一个值,将客户端配置为检查其连接失败。网络连接的默认检查周期为 30,000 毫秒或 30 秒,而 in-VM 连接的默认值为 -1,这意味着如果未收到任何数据,客户端永远不会从其一侧失败连接。
通常,您可以将检查周期设置为比代理连接时长使用的值小得多,这样可确保客户端能够在临时故障时重新连接。
设置检测已死连接的检查周期
以下示例演示了如何将检查周期设置为 10,000 毫秒。
流程
如果您使用 JNDI,请在 JNDI 上下文环境中设置检查周期(
jndi.properties),例如:java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory connectionFactory.myConnectionFactory=tcp://localhost:61616?clientFailureCheckPeriod=10000
如果没有使用 JNDI,请通过将值传递给
ActiveMQConnectionFactory.setClientFailureCheckPeriod()来直接设置检查周期。ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setClientFailureCheckPeriod(10000);
6.4. 配置生存时间
默认情况下,客户端可以为自己的连接设置实时(TTL)。以下示例演示了如何设置 TTL。
流程
如果您使用 JNDI 来实例化连接工厂,您可以使用
connectionTtl参数在 xml 配置中指定它。java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory connectionFactory.myConnectionFactory=tcp://localhost:61616?connectionTtl=30000
如果没有使用 JNDI,连接 TTL 由
ActiveMQConnectionFactory实例中的ConnectionTTL属性定义。ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setConnectionTTL(30000);
6.5. 关闭连接
客户端应用必须在退出前以受控的方式关闭其资源,以防止发生死机连接。在 Java 中,建议关闭 finally 块中的连接:
Connection jmsConnection = null;
try {
ConnectionFactory jmsConnectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(...);
jmsConnection = jmsConnectionFactory.createConnection();
...use the connection...
}
finally {
if (jmsConnection != null) {
jmsConnection.close();
}
}6.6. 配置动态发现
您可以配置 AMQ 核心协议 JMS,在尝试建立连接时发现代理列表。
如果您在客户端上使用 JNDI 来查找您的 JMS 连接工厂实例,您可以在 JNDI 上下文环境中指定这些参数。通常,参数在名为 jndi.properties 的文件中定义。连接工厂的主机和部分应与代理 broker.xml 配置文件中的对应 broadcast-group 中的 group-address 和 group-port 匹配。以下是配置为连接到代理发现组的 jndi.properties 文件示例。
java.naming.factory.initial = ActiveMQInitialContextFactory connectionFactory.myConnectionFactory=udp://231.7.7.7:9876
当此连接工厂由客户端应用从 JNDI 下载并且从其中创建 JMS 连接时,这些连接将在发现组通过侦听代理发现组配置中指定的多播地址的服务器列表中进行负载均衡。
作为使用 JNDI 的替代方案,您可以在创建 JMS 连接工厂时直接在 Java 代码中指定发现组参数。下面的代码提供了一个如何执行此操作的示例。
final String groupAddress = "231.7.7.7";
final int groupPort = 9876;
DiscoveryGroupConfiguration discoveryGroupConfiguration = new DiscoveryGroupConfiguration();
UDPBroadcastEndpointFactory udpBroadcastEndpointFactory = new UDPBroadcastEndpointFactory();
udpBroadcastEndpointFactory.setGroupAddress(groupAddress).setGroupPort(groupPort);
discoveryGroupConfiguration.setBroadcastEndpointFactory(udpBroadcastEndpointFactory);
ConnectionFactory jmsConnectionFactory = ActiveMQJMSClient.createConnectionFactoryWithHA
(discoveryGroupConfiguration, JMSFactoryType.CF);
Connection jmsConnection1 = jmsConnectionFactory.createConnection();
Connection jmsConnection2 = jmsConnectionFactory.createConnection();
刷新超时可以使用 setter 方法 setRefreshTimeout() 直接在 DiscoveryGroupConfiguration 上设置。默认值为 10000 毫秒。
在首次使用时,连接工厂将确保它在创建此时间之后再创建第一个连接前等待。默认等待时间为 10000 毫秒,但您可以通过将新值传递给 DiscoveryGroupConfiguration.setDiscoveryInitialWaitTimeout() 来更改。
6.7. 配置静态发现
有时,可能无法在您使用的网络上使用 UDP。在这种情况下,您可以使用可能的服务器的初始列表配置连接。这个列表可以是您知道始终可用的一个代理,或者至少有一个代理列表。
这并不表示您必须知道要托管所有服务器的位置。您可以将这些服务器配置为使用可靠的服务器进行连接。连接后,它们的连接详细信息将从服务器传播到客户端。
如果您在客户端上使用 JNDI 来查找您的 JMS 连接工厂实例,您可以在 JNDI 上下文环境中指定这些参数。通常,参数在名为 jndi.properties 的文件中定义。以下是提供静态代理列表而不是使用动态发现的 jndi.properties 文件示例。
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory connectionFactory.myConnectionFactory=(tcp://myhost:61616,tcp://myhost2:61616)
当客户端使用上述连接工厂时,其连接将在括号 () 中定义的代理列表中进行负载均衡。
如果您直接实例化 JMS 连接工厂,您可以在创建 JMS 连接工厂时明确指定连接器列表,如下例所示。
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("host", "myhost");
map.put("port", "61616");
TransportConfiguration broker1 = new TransportConfiguration
(NettyConnectorFactory.class.getName(), map);
HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("host", "myhost2");
map2.put("port", "61617");
TransportConfiguration broker2 = new TransportConfiguration
(NettyConnectorFactory.class.getName(), map2);
ActiveMQConnectionFactory cf = ActiveMQJMSClient.createConnectionFactoryWithHA
(JMSFactoryType.CF, broker1, broker2);6.8. 配置代理连接器
连接器定义客户端如何连接到代理。您可以使用 JMS 连接工厂从客户端配置它们。
Map<String, Object> connectionParams = new HashMap<String, Object>();
connectionParams.put(org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 61617);
TransportConfiguration transportConfiguration =
new TransportConfiguration(
"org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory", connectionParams);
ConnectionFactory connectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
Connection jmsConnection = connectionFactory.createConnection();第 7 章 消息发送
7.1. 写入到流传输的大信息
要写入到大信息,使用 BytesMessage.writeBytes() 方法。以下示例从文件中读取字节并将其写入信息:
示例:编写到流传输的大信息
BytesMessage message = session.createBytesMessage();
File inputFile = new File(inputFilePath);
InputStream inputStream = new FileInputStream(inputFile);
int numRead;
byte[] buffer = new byte[1024];
while ((numRead = inputStream.read(buffer, 0, buffer.length)) != -1) {
message.writeBytes(buffer, 0, numRead);
}
7.2. 从流传输的大消息中读取
要从大消息中读取,请使用 BytesMessage.readBytes() 方法。以下示例从信息中读取字节并将其写入文件:
示例:从流传输的大消息中读取
BytesMessage message = (BytesMessage) consumer.receive();
File outputFile = new File(outputFilePath);
OutputStream outputStream = new FileOutputStream(outputFile);
int numRead;
byte buffer[] = new byte[1024];
for (int pos = 0; pos < message.getBodyLength(); pos += buffer.length) {
numRead = message.readBytes(buffer);
outputStream.write(buffer, 0, numRead);
}
7.3. 使用消息组
消息组是具有以下特征的信息集合:
-
消息组中的消息共享同一组 ID。也就是说,它们具有相同的组标识符属性。对于 JMS 消息,属性是
JMSXGroupID。 - 消息组中的消息始终供同一使用者使用,即使队列中有许多消费者。如果原始消费者关闭,则可以选择另一消费者接收消息组。
如果您希望同一使用者以序列方式处理属性的特定值的所有消息,则消息组很有用。例如,您可能希望订单让同一消费者序列处理任何特定股票购买。为此,您可以创建一个消费者池,然后将库存名称设置为消息属性的值。这可确保特定库存的所有消息始终由同一消费者处理。
设置组 ID
以下示例演示了如何将消息组与 AMQ 核心协议 JMS 一起使用。
流程
如果您使用 JNDI 为您的 JMS 客户端建立 JMS 连接工厂,请添加
groupID参数并提供值。使用此连接工厂发送的所有消息均将属性JMSXGroupID设置为指定的值。java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory connectionFactory.myConnectionFactory=tcp://localhost:61616?groupID=MyGroup
如果您不使用 JNDI,请使用
setStringProperty()方法设置JMSXGroupID属性。Message message = new TextMessage(); message.setStringProperty("JMSXGroupID", "MyGroup"); producer.send(message);
其他资源
有关如何配置和使用消息组的工作示例,请参阅 <install-dir>/examples/features/standard 下的 message-group 和 message-group2。
7.4. 使用重复消息检测
AMQ Broker 包含自动重复的消息检测,用于过滤它收到的任何重复信息,因此您不必对自己的重复检测逻辑进行编码。
要启用重复的消息检测,请为消息属性 _AMQ_DUPL_ID 提供唯一值。代理收到消息时,它会检查 _AMQ_DUPL_ID 是否有值。如果存在,代理会在其内存缓存中检查,以查看它是否收到了具有该值的消息。如果找到具有相同值的消息,则忽略传入的消息。
如果您在事务中发送信息,则不必为事务中的每个信息设置 _AMQ_DUPL_ID,而只需要在其中之一中设置。如果代理检测到事务中任何消息的重复信息,它会忽略整个事务。
设置重复 ID 消息属性
以下示例演示了如何使用 AMQ 核心协议 JMS 设置重复检测属性。请注意,为方便起见,客户端使用常量 org.apache.activemq.artemis.api.core.Message.HDR_DUPLICATE_DETECTION_ID 值作为重复 ID 属性 _AMQ_DUPL_ID。
流程
将 _AMQ_DUPL_ID 的值设置为唯一字符串值。
Message jmsMessage = session.createMessage(); String myUniqueID = "This is my unique id"; message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID);
7.5. 使用消息拦截器
通过 AMQ 核心协议 JMS,您可以拦截进入或退出客户端的数据包,允许您审核数据包或过滤消息。拦截器可以更改它们拦截的数据包。这使得拦截器功能强大,同时也是您应该谨慎使用的功能。
拦截器必须实施 intercept() 方法,该方法返回 boolean 值。如果返回的值是 true,消息数据包将继续。如果返回的值是 false,则进程将被中止,不会调用其他拦截器,也不会进一步处理消息数据包。
消息拦截以透明的方式对主客户端代码发生,除非传出数据包以阻止发送模式发送。在发送传出数据包时,启用阻止并且数据包遇到返回 false 的拦截器时,会将 ActiveMQException 抛给调用者。抛出的异常包含拦截器的名称。
您的拦截器必须实现 org.apache.artemis.activemq.api.core.Interceptor 接口。客户端拦截器类及其依赖项必须添加到客户端的 Java 类路径中,以便能正确实例化和调用。
package com.example;
import org.apache.artemis.activemq.api.core.Interceptor;
import org.apache.activemq.artemis.core.protocol.core.Packet;
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
public class MyInterceptor implements Interceptor {
private final int ACCEPTABLE_SIZE = 1024;
@Override
boolean intercept(Packet packet, RemotingConnection connection) throws ActiveMQException {
int size = packet.getPacketSize();
if (size <= ACCEPTABLE_SIZE) {
System.out.println("This Packet has an acceptable size.");
return true;
}
return false;
}
}第 8 章 流控制
流控制可通过限制他们之间的数据流来防止生产者和消费者变得负担过重。AMQ 核心协议 JMS 允许您为消费者和生产者配置流控制。
消费者流控制
消费者流控制控制代理和客户端之间的数据流,因为客户端会消耗来自代理的消息。在将消息传送给消费者之前,AMQ 核心协议 JMS 默认会缓冲消息。如果没有缓冲区,客户端首先需要从代理请求每个消息,然后才能使用。这种类型的"往返"通信成本很高。客户端上的数据流很重要,因为内存不足的问题会导致用户无法足够快速地处理消息,缓冲区也开始与传入消息溢出。
制作者流控制
与基于消费者窗口的流控制类似,客户端可以限制从生产者发送到代理的数据量,以防止代理被过多的数据所覆盖。对于制作者,窗口大小决定了任意时间可以处于机状态的字节数。
8.1. 设置使用者窗口大小
客户端缓冲区中保存的最大信息大小取决于其 窗口大小。AMQ 核心协议 JMS 的默认窗口大小为 1 MiB,或 1024 * 1024 字节。默认为大多数用例。对于其他情况,找到窗口大小的最佳值可能需要对您的系统进行基准测试。如果您需要更改默认值,AMQ 核心协议 JMS 允许您设置缓冲区窗口大小。
以下示例演示了如何使用 AMQ 核心协议 JMS 设置使用者窗口大小参数。每个示例将使用者窗口大小设置为 300,000 字节。
流程
如果客户端使用 JNDI 来实例化其连接工厂,在连接字符串 URL 中包括
consumerWindowSize参数。将 URL 存储在 JNDI 上下文环境中。以下示例使用jndi.properties文件存储 URL。java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory connectionFactory.myConnectionFactory=tcp://localhost:61616?consumerWindowSize=300000
如果客户端不使用 JNDI 来实例化其连接工厂,请将值传递给
ActiveMQConnectionFactory.setConsumerWindowSize()。ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setConsumerWindowSize(300000);
8.2. 设置制作者窗口大小
窗口大小根据信用额在代理和生产者之间协商,每个字节在窗口中一个得分。随着消息的发送和使用,生产者必须先向代理请求并授予其信用卡,然后才能发送更多消息。生产者和代理之间的信贷交换规范了他们之间的数据流。
以下示例演示了如何使用 AMQ 核心协议 JMS 将制作者窗口大小设置为 1024 字节。
流程
如果客户端使用 JNDI 来实例化其连接工厂,在连接字符串 URL 中包括
producerWindowSize参数。将 URL 存储在 JNDI 上下文环境中。以下示例使用jndi.properties文件存储 URL。java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory java.naming.provider.url=tcp://localhost:61616?producerWindowSize=1024
如果客户端不使用 JNDI 来实例化其连接工厂,请将值传递给
ActiveMQConnectionFactory.setProducerWindowSize()。ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setProducerWindowSize(1024);
8.3. 处理快速消费者
快速消费者可以像使用它们一样快速处理消息。如果您确信消息传递系统中的使用者速度快,请考虑将窗口大小设置为 -1。将窗口大小设置为此值可在客户端上实现未绑定的消息缓冲。不过,请谨慎使用此设置。如果使用者无法在接收消息时尽快处理消息,客户端上的内存可能会溢出。
为快速使用者设置窗口大小
以下示例演示了如何使用消息快速使用者 AMQ 核心协议 JMS 客户端将窗口大小设置为 -1。
流程
如果客户端使用 JNDI 来实例化其连接工厂,在连接字符串 URL 中包括
consumerWindowSize参数。将 URL 存储在 JNDI 上下文环境中。以下示例使用jndi.properties文件存储 URL。java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory connectionFactory.myConnectionFactory=tcp://localhost:61616?consumerWindowSize=-1
如果客户端不使用 JNDI 来实例化其连接工厂,请将值传递给
ActiveMQConnectionFactory.setConsumerWindowSize()。ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setConsumerWindowSize(-1);
8.4. 处理慢速消费者
缓慢的消费者需要花费大量时间来处理每条消息。在这些情况下,不建议在客户端上缓冲消息。相反,消息仍保留在代理中,以供其他消费者使用。关闭缓冲区的一个好处在于,它提供队列中多个使用者之间的确定性分配。要通过禁用客户端缓冲区来处理缓慢的消费者,请将窗口大小设置为 0。
为较慢的用户设置窗口大小
以下示例演示了如何使用 AMQ 核心协议 JMS 客户端(消息使用者较慢)将窗口大小设置为 0。
流程
如果客户端使用 JNDI 来实例化其连接工厂,在连接字符串 URL 中包括
consumerWindowSize参数。将 URL 存储在 JNDI 上下文环境中。以下示例使用jndi.properties文件存储 URL。java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory connectionFactory.myConnectionFactory=tcp://localhost:61616?consumerWindowSize=0
如果客户端不使用 JNDI 来实例化其连接工厂,请将值传递给
ActiveMQConnectionFactory.setConsumerWindowSize()。ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setConsumerWindowSize(0);
其他资源
请参阅 <install-dir>/examples/standard 中的 no-consumer-buffering 示例,它演示了如何在处理慢速消费者时配置代理以防止消费者缓冲。
8.5. 设置消息的消耗率
您可以规范消费者可以消耗消息的速度。也称为 限流,它确保使用者不会以比配置允许的速度更快地消耗消息。
限速流控制可与基于窗口的流控制结合使用。速率限制流控制仅影响客户端每秒可以使用的消息数量,而不影响其缓冲区中消息的数量。通过慢速限制和基于窗口的高限制,客户端的内部缓冲区会快速填充消息。
速率必须是正整数,才能启用此功能,它是每秒消息单位指定的最大所需消息消耗率。将速率设置为 -1 可禁用速率限制流控制。默认值为 -1。
以下示例显示了一个客户端,它将消息使用率限制为每秒 10 条消息。
流程
如果客户端使用 JNDI 来实例化其连接工厂,在连接字符串 URL 中包括
consumerMaxRate参数。将 URL 存储在 JNDI 上下文环境中。以下示例使用jndi.properties文件存储 URL。java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory java.naming.provider.url=tcp://localhost:61616?consumerMaxRate=10
如果客户端不使用 JNDI 来实例化其连接工厂,请将值传递给
ActiveMQConnectionFactory.setConsumerMaxRate()。ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setConsumerMaxRate(10);
其他资源
有关如何限制消费者速率的工作示例,请查看 <install-dir>/examples/standard 中的 consumer-rate-limit 示例。
8.6. 设置消息生产速率
AMQ 核心协议 JMS 还可以限制制作者发送消息的速度。制作者率以每秒消息单位为单位指定。将它设置为 -1(默认值)可禁用速率限制流控制。
以下示例演示了在制作者使用 AMQ Core Protocol JMS 时如何设置发送消息的速率。每个示例将最大速率设置为每秒 10 条消息。
流程
如果客户端使用 JNDI 来实例化其连接工厂,在连接字符串 URL 中包括
producerMaxRate参数。将 URL 存储在 JNDI 上下文环境中。以下示例使用jndi.properties文件存储 URL。java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory java.naming.provider.url=tcp://localhost:61616?producerMaxRate=10
如果客户端不使用 JNDI 来实例化其连接工厂,请将值传递给
ActiveMQConnectionFactory.setProducerMaxRate()。ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactory(...) cf.setProducerMaxRate(10);
其他资源
有关如何限制发送信息速率的工作示例,请查看 <install-dir>/examples/standard 中的 producer-rate-limit 示例。
附录 A. 使用您的订阅
AMQ 通过软件订阅提供。要管理您的订阅,请访问红帽客户门户中的帐户。
A.1. 访问您的帐户
流程
- 转至 access.redhat.com。
- 如果您还没有帐户,请创建一个帐户。
- 登录到您的帐户。
A.2. 激活订阅
流程
- 转至 access.redhat.com。
- 导航到 My Subscriptions。
- 导航到 激活订阅 并输入您的 16 位激活号。
A.3. 下载发行文件
要访问 .zip、.tar.gz 和其他发布文件,请使用客户门户查找要下载的相关文件。如果您使用 RPM 软件包或 Red Hat Maven 存储库,则不需要这一步。
流程
- 打开浏览器并登录红帽客户门户网站 产品下载页面,网址为 access.redhat.com/downloads。
- 查找 INTEGRATION 类别中 的红帽 AMQ 条目。
- 选择所需的 AMQ 产品。此时会打开 Software Downloads 页面。
- 单击组件的 Download 链接。
A.4. 为系统注册软件包
要在 Red Hat Enterprise Linux 上安装此产品的 RPM 软件包,必须注册您的系统。如果您使用下载的发行文件,则不需要这一步。
流程
- 转至 access.redhat.com。
- 进入 Registration Assistant。
- 选择您的操作系统版本,再继续到下一页。
- 使用您的系统终端中列出的命令完成注册。
有关注册您的系统的更多信息,请参阅以下资源之一:
附录 B. 使用红帽 Maven 存储库
本节论述了如何在您的软件中使用红帽提供的 Maven 存储库。
B.1. 使用在线存储库
红帽维护一个中央 Maven 存储库,用于基于 Maven 的项目。如需更多信息,请参阅 存储库欢迎页面。
可以通过两种方式将 Maven 配置为使用 Red Hat 存储库:
将存储库添加到 Maven 设置中
这种配置方法适用于您的用户拥有的所有 Maven 项目,只要您的 POM 文件不覆盖存储库配置并启用包含的配置集。
流程
找到 Maven
settings.xml文件。它通常位于用户主目录的.m2目录中。如果文件不存在,请使用文本编辑器创建该文件。在 Linux 或 UNIX 中:
/home/<username>/.m2/settings.xml在 Windows 中:
C:\Users\<username>\.m2\settings.xml
在
settings.xml文件的profiles元素中添加包含红帽存储库的新配置集,如下例所示:示例:包含 Red Hat 软件仓库的 Maven
settings.xml文件<settings> <profiles> <profile> <id>red-hat</id> <repositories> <repository> <id>red-hat-ga</id> <url>https://maven.repository.redhat.com/ga</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>red-hat-ga</id> <url>https://maven.repository.redhat.com/ga</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> </profiles> <activeProfiles> <activeProfile>red-hat</activeProfile> </activeProfiles> </settings>
有关 Maven 配置的更多信息,请参阅 Maven 设置参考。
在您的 POM 文件中添加软件仓库
要在项目中直接配置存储库,请在 POM 文件的 repositories 元素中添加一个新的条目,如下例所示:
示例:包含 Red Hat 软件仓库的 Maven pom.xml 文件
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>example-app</artifactId>
<version>1.0.0</version>
<repositories>
<repository>
<id>red-hat-ga</id>
<url>https://maven.repository.redhat.com/ga</url>
</repository>
</repositories>
</project>
有关 POM 文件配置的更多信息,请参阅 Maven POM 参考。
B.2. 使用本地存储库
红帽为其部分组件提供基于文件的 Maven 存储库。这些内容作为可下载存档提供,您可以提取到本地文件系统。
要将 Maven 配置为使用本地提取的存储库,请在 Maven 设置或 POM 文件中应用以下 XML:
<repository>
<id>red-hat-local</id>
<url>${repository-url}</url>
</repository>
${repository-url} 必须是包含提取仓库本地文件系统路径的文件 URL。
表 B.1. 本地 Maven 存储库的 URL 示例
| 操作系统 | 文件系统路径 | URL |
|---|---|---|
| Linux 或 UNIX |
|
|
| Windows |
|
|
附录 C. 将 AMQ Broker 与示例搭配使用
AMQ Core Protocol JMS 示例需要一个正在运行的消息代理,其中包含名为 exampleQueue 的队列。使用以下步骤安装和启动代理并定义队列。
C.1. 安装代理
按照 AMQ Broker 入门 以 安装代理 并创建代理 实例 中的内容进行操作。启用匿名访问。
以下步骤将代理实例的位置称为 <broker-instance-dir>。
C.2. 启动代理
流程
使用
artemis run命令启动代理。$ <broker-instance-dir>/bin/artemis run检查控制台输出中是否有启动过程中记录的严重错误。代理日志记录
Server is now live(当它就绪时)。$ example-broker/bin/artemis run __ __ ____ ____ _ /\ | \/ |/ __ \ | _ \ | | / \ | \ / | | | | | |_) |_ __ ___ | | _____ _ __ / /\ \ | |\/| | | | | | _ <| '__/ _ \| |/ / _ \ '__| / ____ \| | | | |__| | | |_) | | | (_) | < __/ | /_/ \_\_| |_|\___\_\ |____/|_| \___/|_|\_\___|_| Red Hat AMQ <version> 2020-06-03 12:12:11,807 INFO [org.apache.activemq.artemis.integration.bootstrap] AMQ101000: Starting ActiveMQ Artemis Server ... 2020-06-03 12:12:12,336 INFO [org.apache.activemq.artemis.core.server] AMQ221007: Server is now live ...
C.3. 创建队列
在新终端中,使用 artemis queue 命令创建名为 exampleQueue 的队列。
$ <broker-instance-dir>/bin/artemis queue create --name exampleQueue --address exampleQueue --auto-create-address --anycast
系统将提示您回答一系列"是"或无问题。对所有设备回答 N。
队列创建后,代理就可与示例程序配合使用。
C.4. 停止代理
运行完示例后,使用 artemis stop 命令停止代理。
$ <broker-instance-dir>/bin/artemis stop2021-08-31 15:45:29 +1000 修订