Apache ActiveMQ Artemis 拥有一个广泛的 管理 API,允许用户修改服务器配置,创建新资源(例如地址和队列),检查这些资源(例如当前队列中保存了多少消息)并与之交互(例如从队列中删除消息)。Apache ActiveMQ Artemis 还允许客户端订阅管理通知。

有多种方法可以访问 Apache ActiveMQ Artemis 管理 API

  • 使用 JMX — JMX 是管理 Java 应用程序的标准方法

  • 使用 Jolokia — Jolokia 通过 HTTP 接口 公开应用程序的 JMX API

  • 使用核心客户端 — 管理操作使用 核心客户端消息 发送到 Apache ActiveMQ Artemis 服务器

  • 使用任何 JMS 客户端 — 管理操作使用 JMS 客户端消息 发送到 Apache ActiveMQ Artemis 服务器

  • Web 控制台 — 一个提供管理 API 图形界面的 Web 应用程序。

虽然有四种不同的方法可以管理 Apache ActiveMQ Artemis,但每个 API 都支持相同的功能。如果可以使用 JMX 管理资源,那么也可以使用核心消息实现相同的结果。

除了这四个管理接口外,还为 ActiveMQ Artemis 的管理员提供了 Web 控制台 和命令行 管理实用程序

选择取决于您的需求、应用程序设置和环境,以确定最适合您的方法。

1. 管理 API

无论您 调用 管理操作的方式如何,管理 API 都是相同的。

对于每个 受管理资源,都存在一个 Java 接口,描述了可以为此类型资源调用哪些操作。

要了解可用的 管理操作,请参阅这些接口的 Javadoc。它们位于 org.apache.activemq.artemis.api.core.management 包中,并且以单词 Control 结尾。

1.1. 服务器管理

ActiveMQServerControl 接口是代理管理的入口点。

  • 列出、创建、部署和销毁队列

    可以使用 getQueueNames() 方法检索已部署队列的列表。

    可以使用管理操作 createQueue()deployQueue()destroyQueue() 创建或销毁队列。

    如果队列已存在,则 createQueue 将失败,而 deployQueue 则不会执行任何操作。

  • 列出和关闭远程连接

    可以使用 listRemoteAddresses() 检索客户端的远程地址。还可以使用 closeConnectionsForAddress() 方法关闭与远程地址关联的连接。

    或者,可以使用 listConnectionIDs() 列出连接 ID,并使用 listSessions() 列出给定连接 ID 的所有会话。

  • 事务启发式操作

    在服务器崩溃的情况下,当服务器重启时,某些事务可能需要手动干预。listPreparedTransactions() 方法列出处于准备状态的事务(事务表示为不透明的 Base64 字符串)。要提交或回滚给定准备好的事务,可以使用 commitPreparedTransaction()rollbackPreparedTransaction() 方法来解决启发式事务。可以使用 listHeuristicCommittedTransactions()listHeuristicRolledBackTransactions 方法列出启发式完成的事务。

  • 启用和重置消息计数器

    可以使用 enableMessageCounters()disableMessageCounters() 方法启用或禁用消息计数器。要重置消息计数器,可以调用 resetAllMessageCounters()resetAllMessageCounterHistories() 方法。

  • 检索服务器配置和属性

    ActiveMQServerControl 通过其所有属性公开 Apache ActiveMQ Artemis 服务器配置(例如,getVersion() 方法检索服务器的版本等)。

  • 列出、创建和销毁核心桥接和转向

    可以使用 getBridgeNames()(分别为 getDivertNames())方法检索已部署的核心桥接(分别为转向)的列表。

    可以使用管理操作 createBridge()destroyBridge()(分别为 createDivert()destroyDivert())创建或销毁核心桥接(分别为转向)。

    可以使用管理操作 updateDivert() 更新转向。

  • 可以停止服务器并强制发生故障转移,并将任何当前附加的客户端连接到其他服务器。

    为此,请使用 forceFailover() 操作。

    由于此方法实际上停止了服务器,因此您可能会收到某种错误,具体取决于您使用哪个管理服务来调用它。

1.2. 地址管理

可以使用 AddressControl 接口管理单个地址。

  • 修改地址的角色和权限

    可以使用 addRole()removeRole() 方法添加或删除与队列关联的角色。可以使用 getRoles() 方法列出与队列关联的所有角色。

  • 暂停和恢复地址

    AddressControl 可以暂停和恢复地址及其绑定到的所有队列。新添加的队列也将被暂停,直到地址恢复。因此,发送到地址的所有消息都将被接收,但不会被传递。恢复后,将再次进行传递。

  • 阻止和取消阻止地址

    AddressControl 可以阻止和取消阻止地址。被阻止的地址不会向现有生产者发布更多信用。新生产者将不会获得任何信用。取消阻止地址后,信用授予将恢复。这样,可以将所有与地址关联的队列排空,以以受控方式使代理静止。

1.3. 队列管理

管理 API 的大部分内容都与队列有关。QueueControl 接口定义了队列管理操作。

大多数队列上的管理操作都采用单个消息 ID(例如删除单个消息)或过滤器(例如使具有给定属性的所有消息过期)。

filter 参数中传递 null 或空字符串表示管理操作将对队列中的 所有消息 执行。

  • 使消息过期、发送到死信地址和移动消息

    可以使用 expireMessages() 方法使队列中的消息过期。如果定义了过期地址,则消息将被发送到该地址,否则将被丢弃。

    还可以使用 sendMessagesToDeadLetterAddress() 方法将消息发送到死信地址。它返回发送到死信地址的消息数量。如果未定义死信地址,则消息将从队列中删除并丢弃。

    还可以使用 moveMessages() 方法将消息从一个队列移动到另一个队列。

  • 列出和删除消息

    可以使用 listMessages() 方法列出队列中的消息,该方法返回一个 Map 数组,每个消息对应一个 Map

    还可以使用 removeMessages() 方法从队列中删除消息,该方法对单个消息 ID 变体返回一个 boolean 值,对过滤器变体返回已删除消息的数量。removeMessages() 方法采用一个 filter 参数来仅删除过滤后的消息。将过滤器设置为空字符串将删除所有消息。

  • 计数消息

    getMessageCount() 方法返回队列中消息的数量。或者,countMessages() 将返回队列中 与给定过滤器匹配 的消息数量。

  • 更改消息优先级

    可以使用 changeMessagesPriority() 方法更改消息优先级,该方法对单个消息 ID 变体返回一个 boolean 值,对过滤器变体返回已更新消息的数量。

  • 消息计数器

    可以使用 listMessageCounter()listMessageCounterHistory() 方法列出队列的消息计数器(请参阅消息计数器部分)。还可以使用 resetMessageCounter() 方法重置单个队列的消息计数器。

  • 检索队列属性

    QueueControl 通过其属性公开队列设置(例如,getFilter() 用于检索队列的过滤器(如果创建时使用了一个过滤器),isDurable() 用于了解队列是否持久等)。

  • 暂停和恢复队列

    QueueControl 可以暂停和恢复底层队列。暂停队列时,它将接收消息,但不会传递消息。恢复后,它将开始传递队列中的消息(如果有)。

  • 禁用和启用队列

    QueueControl 可以禁用和启用底层队列。禁用队列后,将不再有消息路由到该队列。启用后,它将再次开始接收消息路由。

    这在您可能需要禁用消息路由到队列但希望保持消费者处于活动状态以调查问题(而不会导致队列中消息进一步积压)的情况下很有用。

1.4. 其他资源管理

Apache ActiveMQ Artemis 允许启动和停止其远程资源(接收器、转向、桥接等),以便在不完全停止服务器的情况下(例如,如果必须执行其他管理操作,例如解决启发式事务)将服务器下线一段时间。这些资源是

  • 接收器

    可以使用 AcceptorControl 接口上的 start() 或. stop() 方法启动或停止它们。可以使用 AcceptorControl 属性检索接收器参数(请参阅 了解接收器

  • 转向

    可以使用 DivertControl 接口上的 start()stop() 方法启动或停止它们。可以使用 DivertControl 属性检索转向参数(请参阅 转向和拆分消息流

  • 桥接

    可以使用 BridgeControl 接口上的 start()(分别为 stop())方法启动或停止它们。可以使用 BridgeControl 属性检索桥接参数(请参阅 核心桥接

  • 广播组

    可以使用BroadcastGroupControl接口的start()stop()方法启动或停止它们。广播组参数可以使用BroadcastGroupControl属性检索(参见集群)。

  • 集群连接

    可以使用ClusterConnectionControl接口的start()stop()方法启动或停止它们。集群连接参数可以使用ClusterConnectionControl属性检索(参见集群)。

2. 通过JMX管理

Apache ActiveMQ Artemis可以使用JMX管理。

Apache ActiveMQ Artemis使用MBean公开管理API。默认情况下,Apache ActiveMQ Artemis在其资源注册到域org.apache.activemq.artemis。例如,管理地址exampleAddress上任意播队列exampleQueueObjectName

org.apache.activemq.artemis:broker=<brokerName>,component=addresses,address="exampleAddress",subcomponent=queues,routing-type="anycast",queue="exampleQueue"

MBean是

org.apache.activemq.artemis.api.core.management.QueueControl

MBean的ObjectName是使用辅助类org.apache.activemq.artemis.api.core.management.ObjectNameBuilder构建的。ObjectNameBuilder获取ActiveMQServerControl名称的示例用法

brokerName = "0.0.0.0";  // configured e.g. in broker.xml <broker-name> element
objectNameBuilder = ObjectNameBuilder.create(ArtemisResolver.DEFAULT_DOMAIN, brokerName, true);
serverObjectName = objectNameBuilder.getActiveMQServerObjectName()

使用JMX管理Apache ActiveMQ Artemis与使用JMX管理任何Java应用程序相同。可以通过反射或创建MBean代理来完成。

2.1. 配置JMX

默认情况下,JMX已启用以管理Apache ActiveMQ Artemis。可以通过在broker.xml中将jmx-management-enabled设置为false来禁用它。

<jmx-management-enabled>false</jmx-management-enabled>

2.1.1. JMX的基于角色的授权

Artemis默认情况下使用Java虚拟机的Platform MBeanServer。这受到基于角色的授权的保护,该授权利用了代理的JAAS插件支持。

用于限制对MBean及其操作的访问的RBAC可以通过两种方式之一进行配置。通过broker.xml中的安全设置(在broker.xml中的JMX授权中描述),或者通过下面描述的management.xml中的authorization元素。

management.xml中的JMX授权

authorization元素中有3个元素:allowlistdefault-accessrole-access。让我们逐一讨论。

Allowlist包含一个MBean列表,这些MBean将绕过授权,这通常用于控制台运行所需的任何MBean。默认配置是

<allowlist>
   <entry domain="hawtio"/>
</allowlist>

这意味着任何具有域hawtio的MBean都将被允许在没有授权的情况下访问。例如,hawtio:plugin=artemis。您也可以对MBean属性使用通配符,因此以下内容也将匹配。

<allowlist>
   <entry domain="hawtio" key="type=*"/>
</allowlist>

allowlist元素已替换了现在已弃用的whitelist元素。

role-access定义了角色如何映射到特定的MBean及其属性和方法。默认配置如下所示

<role-access>
  <match domain="org.apache.activemq.artemis">
     <access method="list*" roles="view,update,amq"/>
     <access method="get*" roles="view,update,amq"/>
     <access method="is*" roles="view,update,amq"/>
     <access method="set*" roles="update,amq"/>
     <access method="*" roles="amq"/>
  </match>
</role-access>

这包含1个匹配项,并将应用于任何具有域org.apache.activemq.artemis的MBean。对具有此域的任何MBean的任何访问都由access元素控制,这些元素包含一个方法和一组角色。调用的方法将用于选择最接近匹配的方法,并将应用于此方法的角色以进行访问。例如,如果您尝试对具有org.apache.activemq.artemis域的MBean调用名为listMessages的方法,那么这将匹配access,其方法为list*。您也可以通过使用完整的方法名称来明确配置这一点,如下所示

<access method="listMessages" roles="view,update,amq"/>

您还可以通过添加一个用于匹配MBean属性之一的键属性来匹配域内的特定MBean,例如

<match domain="org.apache.activemq.artemis" key="subcomponent=queues">
   <access method="list*" roles="view,update,amq"/>
   <access method="get*" roles="view,update,amq"/>
   <access method="is*" roles="view,update,amq"/>
   <access method="set*" roles="update,amq"/>
   <access method="*" roles="amq"/>
</match>

例如,您可以匹配特定的队列

org.apache.activemq.artemis:broker=<brokerName>,component=addresses,address="exampleAddress",subcomponent=queues,routing-type="anycast",queue="exampleQueue"

通过配置

<match domain="org.apache.activemq.artemis" key="queue=exampleQueue">
   <access method="list*" roles="view,update,amq"/>
   <access method="get*" roles="view,update,amq"/>
   <access method="is*" roles="view,update,amq"/>
   <access method="set*" roles="update,amq"/>
   <access method="*" roles="amq"/>
</match>

您也可以对MBean属性使用通配符,因此以下内容也将匹配,允许对MBean属性进行前缀匹配。

<match domain="org.apache.activemq.artemis" key="queue=example*">
   <access method="list*" roles="view,update,amq"/>
   <access method="get*" roles="view,update,amq"/>
   <access method="is*" roles="view,update,amq"/>
   <access method="set*" roles="update,amq"/>
   <access method="*" roles="amq"/>
</match>

如果有多个匹配项,则精确匹配的优先级高于通配符匹配,而较长的通配符匹配的优先级高于较短的通配符匹配。

对JMX MBean属性的访问被转换为方法调用,因此这些方法通过set*get*is*进行控制。*访问是对未明确匹配的所有其他方法的总称。

default-access元素基本上是对通过role-access配置未处理的每个方法调用的总称。这与match元素具有相同的语义。

2.1.2. broker.xml中的JMX授权

broker.xml中现有的安全设置可用于JMX RBAC。

在安全设置中对匹配项使用viewedit权限提供了一种替代management.xml中授权部分的方法。使用基于地址的单一安全模型,以及可重新加载的配置,简化了操作。

必须使用JVM系统属性配置一个MBeanServer拦截器,该拦截器委托给代理安全管理器,以允许将其添加到JVM中的所有MBeanServer。

这是通过以下系统属性配置的

 java -Djavax.management.builder.initial=org.apache.activemq.artemis.core.server.management.ArtemisRbacMBeanServerBuilder
提供此属性后,必须省略/删除management.xml的授权部分,因为它依赖于另一种MBeanServer拦截器和构建器。

安全设置匹配用于JMX RBAC的地址使用mops.(管理操作的简写)前缀

MBeanServer守护程序将JMX MBean ObjectName映射到一般形式的分层地址

mops<.jmx domain><.type><.component><.name>[.operation]
对于代理域,将省略域。

例如,要为admin角色提供对所有MBean的viewedit权限,请使用以下安全设置

<security-setting match="mops.#">
   <permission type="view" roles="admin"/>
   <permission type="edit" roles="admin"/>
</security-setting>

要向managerRole角色授予对activemq.management地址的view权限,请将目标设置为名为activemq.managementaddress组件,并将.*包括所有操作。

<security-setting match="mops.address.activemq.management.*">
   <permission type="view" roles="managerRole"/>
</security-setting>

为了确保没有用户有权强制使用代理(服务器控制)MBean进行故障转移,请使用以下内容,该内容为broker组件上的特定变异操作定义了空角色集

<security-setting match="mops.broker.forceFailover">
   <permission type="edit" roles=""/>
</security-setting>

2.1.3. 使用JConsole进行本地JMX访问

由于默认情况下启用了授权,因此当以本地进程身份连接时,无法使用JConsole在本地管理Apache ActiveMQ Artemis。这是因为JConsole在以这种方式连接时不会传递任何身份验证信息,这意味着用户因此无法被授权进行任何管理操作。为了使用JConsole,用户要么必须通过完全从management.xml中删除authorization元素来禁用授权,要么通过启用远程访问并提供适当的用户名和密码凭据(接下来讨论)。

2.1.4. 远程JMX访问

默认情况下,出于安全原因,禁用了对Artemis的远程JMX访问。

Artemis有一个JMX代理,允许远程访问JMX MBean。这是通过management.xml配置文件中的connector元素配置的。要启用它,只需添加以下xml

<connector connector-port="1099"/>

这在端口1099上远程公开代理。如果您通过JConsole连接,则可以使用服务URL以远程进程身份连接

service:jmx:rmi:///jndi/rmi://127.0.0.1:1099/jmxrmi

在这种情况下,您也可以提供适当的用户名和密码。

您还可以使用以下方法配置连接器

connector-host

公开代理的主机。

connector-port

公开代理的端口。

rmi-registry-port

RMI注册表绑定的端口。如果未设置,则端口始终是随机的。设置为避免通过防火墙进行的远程JMX连接隧道出现问题。

jmx-realm

用于身份验证的jmx realm,默认为activemq以匹配JAAS配置。

object-name

公开远程连接器的对象名称;默认为connector:name=rmi

secured

连接器是否使用SSL进行保护。

key-store-path

密钥库的位置。

key-store-password

密钥库密码。这可以屏蔽

key-store-provider

提供者;默认情况下为JKS

trust-store-path

信任库的位置。

trust-store-password

信任库密码。这可以屏蔽

trust-store-provider

提供者;默认情况下为JKS

password-codec

要使用的密码编解码器的完全限定类名。有关其工作原理的更多详细信息,请参阅密码屏蔽文档。

需要注意的是,rmi注册表将选择一个IP地址来绑定。如果您的系统上存在多个IP地址/网卡,则可以通过在artemis.profile中添加以下内容来选择要使用的IP地址:-Djava.rmi.server.hostname=localhost

使用默认JVM代理的远程连接默认情况下未启用,因为Artemis通过其自身的配置公开MBeanServer。这样,Artemis就可以通过JMX利用JAAS身份验证层。如果您想公开它,则需要禁用连接器和授权,方法是从management.xml配置中删除它们。有关配置服务器以进行远程管理(必须在artemis.profile中设置系统属性)的信息,请参阅Java Management指南

默认情况下,Apache ActiveMQ Artemis服务器使用JMX域“org.apache.activemq.artemis”。要从同一个MBeanServer管理多个Apache ActiveMQ Artemis服务器,可以通过在broker.xml中设置jmx-domain来为每个Apache ActiveMQ Artemis服务器配置JMX域。

<!-- use a specific JMX domain for ActiveMQ Artemis MBeans -->
<jmx-domain>my.org.apache.activemq</jmx-domain>

2.2. 示例

参见JMX管理示例,其中演示了如何使用远程连接到JMX和MBean代理以管理Apache ActiveMQ Artemis。

2.3. 使用Jolokia公开JMX

默认的代理配置附带了作为Web应用程序部署的Jolokia HTTP代理。Jolokia是一个远程JMX-over-HTTP桥,它公开MBean。有关如何使用它的完整指南,请参阅Jolokia文档

2.3.1. 读取属性

检查代理是否处于活动状态的简单示例是使用类似这样的curl命令

$ curl -s -H "Origin: https://127.0.0.1" -u myUser:myPass https://127.0.0.1:8161/console/jolokia/read/org.apache.activemq.artemis:broker=\"0.0.0.0\"/Active

或者,您可以发送JSON格式的POST请求,而不是使用URL

$ curl -s -H "Origin: https://127.0.0.1" -u myUser:myPass --header "Content-type: application/json" --request POST --data '{"attribute": "Active", "mbean": "org.apache.activemq.artemis:broker=\"0.0.0.0\"", "type": "read"}' https://127.0.0.1:8161/console/jolokia

默认情况下,由于在etc/jolokia-access.xml中配置的CORS检查,因此必须传递Origin标头。

这两个curl命令都会返回类似以下内容(格式化后)

{
  "request": {
    "mbean": "org.apache.activemq.artemis:broker=\"0.0.0.0\"",
    "attribute": "Version",
    "type": "read"
  },
  "value": "true",
  "timestamp": 1663086398,
  "status": 200
}

属性的值包含在value中(即true)。您可以使用像jq这样的工具轻松解析此JSON数据,该工具在大多数Linux发行版中都可用,例如

$ curl -s -H "Origin: https://127.0.0.1" -u myUser:myPass --header "Content-type: application/json" --request POST --data '{"attribute": "Active", "mbean": "org.apache.activemq.artemis:broker=\"0.0.0.0\"", "type": "read"}' https://127.0.0.1:8161/console/jolokia | jq -r '.value'

此命令将简单地返回

true

有关Jolokia的read功能的更多详细信息,请参阅Jolokia文档

2.3.2. 执行操作

除了读取属性之外,下一个最常见的任务是执行操作。例如,您可以使用curl列出与代理的连接,并使用jq解析输出,如下所示

$ curl -s -H "Origin: https://127.0.0.1" -u myUser:myPass "https://127.0.0.1:8161/console/jolokia/exec/org.apache.activemq.artemis:broker=\"0.0.0.0\"/listConnections/\"\"/-1/-1" | jq '.value | fromjson'

或者,您可以发送JSON格式的POST请求,而不是使用URL

$ curl -s -H "Origin: https://127.0.0.1" -u myUser:myPass --header "Content-type: application/json" --request POST --data '{"operation": "listConnections", "mbean": "org.apache.activemq.artemis:broker=\"0.0.0.0\"", "type": "exec", "arguments": [ "", -1, -1 ] }' https://127.0.0.1:8161/console/jolokia | jq '.value | fromjson'

这两个命令都会返回类似以下内容(格式化后)

{
  "data": [
    {
      "connectionID": "bd8d4635",
      "remoteAddress": "127.0.0.1:55754",
      "users": "",
      "creationTime": "Wed Jan 1 12:00:00 CDT 2020",
      "implementation": "RemotingConnectionImpl",
      "protocol": "CORE",
      "clientID": "",
      "localAddress": "tcp:///127.0.0.1:61616",
      "sessionCount": 2
    },
    {
      "connectionID": "2a7ac661",
      "remoteAddress": "127.0.0.1:54394",
      "users": "",
      "creationTime": "Wed Jan 1 12:00:00 CDT 2020",
      "implementation": "OpenWireConnection",
      "protocol": "OPENWIRE",
      "clientID": "ID:myMachine-34439-1727292626395-0:1",
      "localAddress": "tcp:///127.0.0.1:61616",
      "sessionCount": 3
    }
  ],
  "count": 2
}

您也可以利用管理方法选项语法来获得更具体的結果。

$ curl -s -H "Origin: https://127.0.0.1" -u myUser:myPass "https://127.0.0.1:8161/console/jolokia/exec/org.apache.activemq.artemis:broker=\"0.0.0.0\"/listConnections/\{\"field\":\"protocol\",\"operation\":\"EQUALS\",\"value\":\"OPENWIRE\"\}/-1/-1" | jq '.value | fromjson'

或者,您可以发送JSON格式的POST请求,而不是使用URL

$ curl -s -H "Origin: https://127.0.0.1" -u myUser:myPass --header "Content-type: application/json" --request POST --data '{"operation": "listConnections", "mbean": "org.apache.activemq.artemis:broker=\"0.0.0.0\"", "type": "exec", "arguments": [ "{\"field\":\"protocol\",\"operation\":\"EQUALS\",\"value\":\"OPENWIRE\"}", -1, -1 ] }' https://127.0.0.1:8161/console/jolokia | jq '.value | fromjson'

这两个命令都会返回类似以下内容(格式化后)

{
  "data": [
    {
      "connectionID": "2a7ac661",
      "remoteAddress": "127.0.0.1:54394",
      "users": "",
      "creationTime": "Wed Jan 1 12:00:00 CDT 2020",
      "implementation": "OpenWireConnection",
      "protocol": "OPENWIRE",
      "clientID": "ID:myMachine-34439-1727292626395-0:1",
      "localAddress": "tcp:///127.0.0.1:61616",
      "sessionCount": 3
    }
  ],
  "count": 1
}

有关 Jolokia 的exec功能的更多详细信息,请参见Jolokia 文档

2.4. 管理方法选项语法

当有大量此类资源需要管理时,有时可能难以找到特定的资源。例如,如果有 1000 个连接到代理,而您只想管理使用特定客户端 ID 的一个特定连接。一些管理操作支持特殊的 JSON 语法,以便根据以下输入过滤结果

  • field(请参见下面每个管理操作的字段列表)

  • 操作

    • CONTAINS

    • NOT_CONTAINS

    • EQUALS

    • NOT_EQUALS

    • GREATER_THAN

    • LESS_THAN

  • value

  • sortField(可选)

  • sortOrder(可选)

    • asc

    • desc

以下是支持此语法的以及可用字段的方法

listConnections
  • connectionID

  • clientID

  • users

  • protocol

  • sessionCount

  • remoteAddress

  • localAddress

  • sessionID

  • creationTime

  • implementation

  • 示例

    {
      "field": "protocol",
      "operation": "EQUALS",
      "value": "OPENWIRE"
    }
listSessions
  • id

  • connectionID

  • consumerCount

  • producerCount

  • user

  • validatedUser

  • protocol

  • clientID

  • localAddress

  • remoteAddress

  • creationTime

  • 示例

    {
      "field": "remoteAddress",
      "operation": "CONTAINS",
      "value": "127.0.0.1"
    }
listAddresses
  • id

  • name

  • routingTypes

  • producerId

  • queueCount

  • internal

  • 示例

    {
      "field": "name",
      "operation": "CONTAINS",
      "value": "shipping"
    }
listQueues
  • id

  • name

  • consumerID

  • address

  • maxConsumers

  • filter

  • messageCount

  • consumerCount

  • deliveringCount

  • messagesAdded

  • messagesAcked

  • messagesExpired

  • routingType

  • user

  • autoCreated

  • durable

  • paused

  • temporary

  • purgeOnNoConsumers

  • messagesKilled

  • directDeliver

  • lastValue

  • exclusive

  • scheduledCount

  • lastValueKey

  • groupRebalance

  • groupRebalancePauseDispatch

  • groupBuckets

  • groupFirstKey

  • enabled

  • ringSize

  • consumersBeforeDispatch

  • delayBeforeDispatch

  • autoDelete

  • internalQueue

  • 示例

    {
      "field": "consumerCount",
      "operation": "GREATER_THAN",
      "value": "7"
    }
listConsumers
  • idconsumerID

  • sequentialIdsequentialId

  • sessionsessionID

  • connectionconnectionID

  • queuequeueName

  • filter

  • address

  • user

  • validatedUser

  • protocol

  • clientID

  • localAddress

  • remoteAddress

  • queueType

  • browseOnly

  • creationTime

  • messagesInTransitdeliveringCount

  • messagesInTransitSize

  • messagesDelivered

  • messagesDeliveredSize

  • messagesAcknowledged

  • messagesAcknowledgedAwaitingCommit

  • lastDeliveredTime

  • lastAcknowledgedTime

  • status

  • 示例

    {
      "field": "messagesAcknowledged",
      "operation": "LESS_THAN",
      "value": "10"
    }
listProducers
  • id

  • name

  • sessionsessionID

  • connectionID

  • addressdestination

  • user

  • validatedUser

  • protocol

  • clientID

  • localAddress

  • remoteAddress

  • creationTime

  • msgSent

  • msgSizeSent

  • lastProducedMessageID

  • 示例

    {
      "field": "validatedUser",
      "operation": "EQUALS",
      "value": "bob"
    }

2.4.1. 排序

结果可以按任何字段以升序 (asc) 或降序 (desc) 排序。例如,在调用listConnections 时使用以下内容来获取所有最新的 AMQP 连接。

{
  "field": "protocol",
  "operation": "EQUALS",
  "value": "AMQP",
  "sortField": "creationTime",
  "sortOrder": "desc"
}

2.4.2. 分页

这些方法还支持分页。换句话说,结果可以分成组,然后进行迭代。第二个参数是“页码”(即要检查的页码),第三个参数是“页面大小”(即每页返回的结果数)。例如,这就是 Web 控制台显示分页结果的方式。

要禁用分页,请将页码或页面大小(或两者)设置为-1

2.5. JMX 和 Web 控制台

与 Artemis 一起提供的 Web 控制台在幕后使用 Jolokia,Jolokia 又使用 JMX。这将使用在基于角色的 JMX 授权部分中描述的认证配置。这意味着当通过控制台访问 MBean 时,将使用用于登录控制台的凭据以及与其关联的角色。默认情况下,只有拥有amq角色的用户才能访问控制台。这在artemis.profile中通过系统属性-Dhawtio.role=amq进行配置。您可以通过将其更改为-Dhawtio.roles=amq,view,update来配置多个角色。

如果用户没有调用特定操作的正确角色,那么将在控制台中显示授权异常。

2.5.1. ArtemisRbacMBeanServerBuilder 和 ArtemisRbacInvocationHandler

当将 ArtemisRbacMBeanServerBuilder 类配置为系统属性javax.management.builder.initial的值时,将导致 ArtemisRbacInvocationHandler 安装在 JVM 中的每个 JMX MBeanServer 上。ArtemisRbacInvocationHandler 会拦截 MBeanServer 上的所有操作,并选择保护其中一部分操作。

对于受保护的操作,需要viewedit权限才能进行调用。如果当前已认证的主题没有授予这些权限的必需角色,则会抛出安全异常。

对于 MBeanServer 上的查询操作,查询结果将限于具有所需view权限的条目。

3. 使用管理消息 API

ActiveMQ Artemis 中的管理消息 API 是通过将 Core Client 消息发送到一个特殊地址(管理地址)来访问的。

管理消息是具有已知属性的常规 Core Client 消息,服务器需要了解这些属性才能与管理 API 交互

  • 管理资源的名称

  • 管理操作的名称

  • 管理操作的参数

当此类管理消息发送到管理地址时,Apache ActiveMQ Artemis 服务器将处理该消息,提取信息,在管理资源上调用操作,并将管理回复发送到管理消息的回复地址(由ClientMessageImpl.REPLYTO_HEADER_NAME指定)。

可以使用ClientConsumer来使用管理回复,并检索存储在回复主体中的操作结果(如果有)。为了便携性,结果将以JSON字符串形式返回,而不是 Java 序列化(org.apache.activemq.artemis.api.core.management.ManagementHelper可用于将 JSON 字符串转换为 Java 对象)。

可以简化这些步骤,以便更容易地使用 Core 消息调用管理操作

  1. 创建一个ClientRequestor,以便将消息发送到管理地址并接收回复

  2. 创建一个ClientMessage

  3. 使用辅助类org.apache.activemq.artemis.api.core.management.ManagementHelper用管理属性填充消息

  4. 使用ClientRequestor发送消息

  5. 使用辅助类org.apache.activemq.artemis.api.core.management.ManagementHelper从管理回复中检索操作结果。

例如,要找出队列exampleQueue中的消息数

ClientSession session = ...
ClientRequestor requestor = new ClientRequestor(session, "activemq.management");
ClientMessage message = session.createMessage(false);
ManagementHelper.putAttribute(message, "queue.exampleQueue", "messageCount");
session.start();
ClientMessage reply = requestor.request(m);
int count = (Integer) ManagementHelper.getResult(reply);
System.out.println("There are " + count + " messages in exampleQueue");

管理操作名称和参数必须符合management包中定义的 Java 接口。

资源的名称是使用辅助类org.apache.activemq.artemis.api.core.management.ResourceNames构建的,并且非常直观(例如,queue.exampleQueue表示队列exampleQueueQueueControl,或者broker表示ActiveMQServerControl)。

ManagementHelper类只能与 Core JMS 消息一起使用。当使用来自其他 JMS 库的消息调用它时,会抛出异常。

3.1. 配置管理

broker.xml中配置了发送管理消息的管理地址

<management-address>activemq.management</management-address>

默认情况下,地址为activemq.management

管理地址需要一个特殊的用户权限manage,以便能够接收和处理管理消息。这也在 broker.xml 中配置

<!-- users with the admin role will be allowed to manage -->
<!-- Apache ActiveMQ Artemis using management messages    -->
<security-setting match="activemq.management">
   <permission type="manage" roles="admin" />
</security-setting>

3.2. 对管理消息进行细粒度 RBAC

管理地址发送的管理消息内容上有可选的 RBAC。通过将属性management-message-rbac设置为true来启用 RBAC。

需要manage权限才能通过消息执行管理操作。viewedit权限必须与manage权限一起使用。

启用后,可以通过安全设置对发送到管理地址的管理消息内容进行更细粒度的权限配置。

用于 RBAC 的安全设置匹配地址遵循以下一般分层形式:management-rbac-prefix、组件类型、组件名称、操作。这些值是从管理消息头中提取的。

<management-rbac-prefix>.<resource type>.<resource name>.<operation>

不可变操作和属性访问需要view权限,所有其他操作都需要edit权限。

在以下示例中,dataImport角色只能访问队列的 id 属性,这是数据导入命令行工具所需的唯一管理操作。

<security-setting match="mops.queue.*.getID">
   <permission type="view" roles="dataImport" />
   <permission type="manage" roles="dataImport" />
</security-setting>

如果您希望admin角色拥有完全访问权限,请在management-rbac-prefix之后使用通配符,并授予viewedit权限

<security-setting match="mops.#">
   <permission type="view" roles="admin" />
   <permission type="update" roles="admin" />
   <permission type="manage" roles="admin" />
</security-setting>

3.3. 管理示例

请参见管理示例,其中显示了如何使用 JMS 消息来管理 Apache ActiveMQ Artemis 服务器。

4. 管理通知

Apache ActiveMQ Artemis 会发出通知,以告知侦听器有关可能发生的有趣事件(创建新资源、安全违规等)。

可以通过两种不同的方式接收这些通知

  • JMX 通知

  • 通知消息

4.1. JMX 通知

如果启用了 JMX(请参见配置 JMX 部分),可以通过订阅org.apache.activemq.artemis:type=Broker,brokerName=<broker name>,module=Core,serviceType=Server来接收有关资源的通知。

4.2. 通知消息

Apache ActiveMQ Artemis 定义了一个特殊的管理通知地址。可以将队列绑定到此地址,以便客户端将管理通知作为消息接收。

要接收管理通知的客户端必须创建一个绑定到管理通知地址的队列。然后,它可以从其队列中接收通知。

通知消息是常规消息,具有与通知相对应的附加属性(其类型、发生时间、所涉及的资源等)。

由于通知是常规消息,因此可以使用消息选择器来过滤通知,只接收服务器发出的所有通知的子集。

4.2.1. 配置管理通知地址

接收管理通知的管理通知地址在 broker.xml 中配置。

<management-notification-address>activemq.notifications</management-notification-address>

默认情况下,地址为 activemq.notifications

4.2.2. 抑制会话通知

某些消息模式会生成大量的 SESSION_CREATEDSESSION_CLOSED 通知。在集群环境中,这将带来一些计算开销。如果这些通知没有其他用途,可以通过以下方式禁用:

<suppress-session-notifications>true</suppress-session-notifications>

只有在使用 MQTT 客户端的集群中,需要强制执行唯一客户端 ID 利用率时,才需要这些通知。默认值为 false

4.2.3. 接收通知消息

Apache ActiveMQ Artemis 的核心 JMS 客户端可用于接收通知

Topic notificationsTopic = ActiveMQJMSClient.createTopic("activemq.notifications");

Session session = ...
MessageConsumer notificationConsumer = session.createConsumer(notificationsTopic);
notificationConsumer.setMessageListener(new MessageListener() {
   public void onMessage(Message notif) {
    System.out.println("------------------------");
    System.out.println("Received notification:");
    try {
     Enumeration propertyNames = notif.getPropertyNames();
     while (propertyNames.hasMoreElements()) {
      String propertyName = (String)propertyNames.nextElement();
      System.out.format("  %s: %s\n", propertyName, notif.getObjectProperty(propertyName));
     }
    } catch (JMSException e) {
    }
    System.out.println("------------------------");
   }
});

4.3. 例子

请参阅 管理通知示例,该示例展示了如何使用 JMS MessageListener 从 ActiveMQ Artemis 服务器接收管理通知。

4.4. 通知类型和报头

以下是所有不同类型通知以及消息中包含哪些报头的列表。每个通知都包含 _AMQ_NotifType(括号中注明的值)和 _AMQ_NotifTimestamp 报头。时间戳是调用 java.lang.System.currentTimeMillis() 的未格式化结果。

BINDING_ADDED (0)

_AMQ_Binding_Type, _AMQ_Address, _AMQ_ClusterName, _AMQ_RoutingName, _AMQ_Binding_ID, _AMQ_Distance, _AMQ_FilterString

BINDING_REMOVED (1)

_AMQ_Address, _AMQ_ClusterName, _AMQ_RoutingName, _AMQ_Binding_ID, _AMQ_Distance, _AMQ_FilterString

CONSUMER_CREATED (2)

_AMQ_Address, _AMQ_ClusterName, _AMQ_RoutingName, _AMQ_Distance, _AMQ_ConsumerCount, _AMQ_User, _AMQ_ValidatedUser, _AMQ_RemoteAddress, _AMQ_SessionName, _AMQ_FilterString, _AMQ_CertSubjectDN

CONSUMER_CLOSED (3)

_AMQ_Address, _AMQ_ClusterName, _AMQ_RoutingName, _AMQ_Distance, _AMQ_ConsumerCount, _AMQ_User, _AMQ_RemoteAddress, _AMQ_SessionName, _AMQ_FilterString

SECURITY_AUTHENTICATION_VIOLATION (6)

_AMQ_User, _AMQ_CertSubjectDN, _AMQ_RemoteAddress

SECURITY_PERMISSION_VIOLATION (7)

_AMQ_Address, _AMQ_CheckType, _AMQ_User

DISCOVERY_GROUP_STARTED (8)

name

DISCOVERY_GROUP_STOPPED (9)

name

BROADCAST_GROUP_STARTED (10)

name

BROADCAST_GROUP_STOPPED (11)

name

BRIDGE_STARTED (12)

name

BRIDGE_STOPPED (13)

name

CLUSTER_CONNECTION_STARTED (14)

name

CLUSTER_CONNECTION_STOPPED (15)

name

ACCEPTOR_STARTED (16)

factory, id

ACCEPTOR_STOPPED (17)

factory, id

PROPOSAL (18)

_JBM_ProposalGroupId, _JBM_ProposalValue, _AMQ_Binding_Type, _AMQ_Address, _AMQ_Distance

PROPOSAL_RESPONSE (19)

_JBM_ProposalGroupId, _JBM_ProposalValue, _JBM_ProposalAltValue, _AMQ_Binding_Type, _AMQ_Address, _AMQ_Distance

CONSUMER_SLOW (21)

_AMQ_Address, _AMQ_ConsumerCount, _AMQ_RemoteAddress, _AMQ_ConnectionName, _AMQ_ConsumerName, _AMQ_SessionName

ADDRESS_ADDED (22)

_AMQ_Address, _AMQ_Routing_Type

ADDRESS_REMOVED (23)

_AMQ_Address, _AMQ_Routing_Type

CONNECTION_CREATED (24)

_AMQ_ConnectionName, _AMQ_RemoteAddress

CONNECTION_DESTROYED (25)

_AMQ_ConnectionName, _AMQ_RemoteAddress

SESSION_CREATED (26)

_AMQ_ConnectionName, _AMQ_User, _AMQ_SessionName

SESSION_CLOSED (27)

_AMQ_ConnectionName, _AMQ_User, _AMQ_SessionName

MESSAGE_DELIVERED (28)

_AMQ_Address, _AMQ_Routing_Type, _AMQ_RoutingName, _AMQ_ConsumerName, _AMQ_Message_ID

MESSAGE_EXPIRED (29)

_AMQ_Address, _AMQ_Routing_Type, _AMQ_RoutingName, _AMQ_ConsumerName, _AMQ_Message_ID

5. 消息计数器

消息计数器可用于获取队列的历史信息,因为 Apache ActiveMQ Artemis 会保留队列指标的历史记录。

它们可用于显示队列的趋势。例如,使用管理 API,可以定期查询队列中的消息数量。但是,这不足以知道队列是否在使用:消息数量可能保持不变,因为没有人向队列发送或接收消息,或者因为发送到队列的消息数量与从队列中消费的消息数量相同。队列中的消息数量在这两种情况下都保持不变,但其用途却大不相同。

消息计数器提供有关队列的更多信息

count

自服务器启动以来添加到队列中的消息的总数

countDelta

自上次消息计数器更新以来添加到队列中的消息数量

messageCount

队列中的消息当前数量

messageCountDelta

自上次消息计数器更新以来添加到队列/从队列中删除的消息的数量。例如,如果 messageCountDelta 等于 -10,则表示总共有 10 条消息从队列中删除(例如,添加了 2 条消息,删除了 12 条消息)。

lastAddTimestamp

上次将消息添加到队列的时间戳

lastAckTimestamp

上次确认队列中消息的时间戳

updateTimestamp

上次消息计数器更新的时间戳

这些属性还可用于确定其他有意义的数据。例如,要专门了解自上次更新以来消费了多少条消息,只需从 countDelta 中减去 messageCountDelta 即可。

5.1. 配置消息计数器

默认情况下,消息计数器处于禁用状态,因为它可能会对内存产生轻微的负面影响。

要启用消息计数器,可以在 broker.xml 中将其设置为 true

<message-counter-enabled>true</message-counter-enabled>

消息计数器会保留队列指标的历史记录(默认情况下为 10 天),并定期对所有队列进行采样(默认情况下为 10 秒)。如果启用了消息计数器,则应在 broker.xml 中配置这些值以适合您的消息传递用例。

<!-- keep history for a week -->
<message-counter-max-day-history>7</message-counter-max-day-history>
<!-- sample the queues every minute (60000ms) -->
<message-counter-sample-period>60000</message-counter-sample-period>

可以使用管理 API 检索消息计数器。例如,要使用 JMX 检索队列上的消息计数器

// retrieve a connection to Apache ActiveMQ Artemis's MBeanServer
MBeanServerConnection mbsc = ...
QueueControlMBean queueControl = (QueueControl)MBeanServerInvocationHandler.newProxyInstance(mbsc,
   on,
   QueueControl.class,
   false);
// message counters are retrieved as a JSON String
String counters = queueControl.listMessageCounter();
// use the MessageCounterInfo helper class to manipulate message counters more easily
MessageCounterInfo messageCounter = MessageCounterInfo.fromJSON(counters);
System.out.format("%s message(s) in the queue (since last sample: %s)\n",
messageCounter.getMessageCount(),
messageCounter.getMessageCountDelta());

5.2. 例子

请参阅 消息计数器示例,该示例展示了如何使用消息计数器检索队列的信息。