JMX 支持
Spring Integration 提供用于接收和发布 JMX 通知的消息通道适配器。
您需要将此依赖项包含到您的项目中
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
<version>6.3.5</version>
</dependency>
compile "org.springframework.integration:spring-integration-jmx:6.3.5"
入站通道适配器允许轮询 JMX MBean 属性值,出站通道适配器允许调用 JMX MBean 操作。
监听通知的通道适配器
监听通知的通道适配器需要一个 JMX ObjectName
,用于发布此监听器应注册到的通知的 MBean。一个非常简单的配置可能类似于以下内容
<int-jmx:notification-listening-channel-adapter id="adapter"
channel="channel"
object-name="example.domain:name=publisher"/>
notification-listening-channel-adapter 在启动时向 MBeanServer 注册,默认 bean 名称是 mbeanServer ,这恰好与使用 Spring 的 <context:mbean-server/> 元素生成的 bean 名称相同。如果需要使用不同的名称,请务必包含 mbean-server 属性。 |
适配器还可以接受对 NotificationFilter
的引用和一个“回传”对象,以提供一些与每个通知一起返回的上下文。这两个属性都是可选的。将前面的示例扩展到也包含这些属性以及显式的 MBeanServer
bean 名称,将产生以下示例
<int-jmx:notification-listening-channel-adapter id="adapter"
channel="channel"
mbean-server="someServer"
object-name="example.domain:name=somePublisher"
notification-filter="notificationFilter"
handback="myHandback"/>
监听通知的通道适配器是事件驱动的,直接向 MBeanServer
注册。它不需要任何轮询器配置。
仅对于此组件,
启用 DEBUG 级日志记录时,将记录找到的 MBean 的名称。 |
发布通知的通道适配器
发布通知的通道适配器相对简单。它只需要在其配置中包含 JMX 对象名称,如下例所示
<context:mbean-export/>
<int-jmx:notification-publishing-channel-adapter id="adapter"
channel="channel"
object-name="example.domain:name=publisher"/>
它还需要在上下文中存在 MBeanExporter
。这就是前面示例中也显示 <context:mbean-export/>
元素的原因。
当消息发送到此适配器的通道时,通知将根据消息内容创建。如果有效负载是 String
,则将其作为通知的 message
文本传递。任何其他有效负载类型都将作为通知的 userData
传递。
JMX 通知也有一个 type
,它应该是一个用点分隔的 String
。有两种方法可以提供 type
。始终优先考虑与 JmxHeaders.NOTIFICATION_TYPE
密钥关联的消息头值。或者,您可以在配置中提供一个回退 default-notification-type
属性,如下例所示
<context:mbean-export/>
<int-jmx:notification-publishing-channel-adapter id="adapter"
channel="channel"
object-name="example.domain:name=publisher"
default-notification-type="some.default.type"/>
轮询属性的通道适配器
当需要定期检查通过 MBean 作为托管属性提供的一些值时,轮询属性的通道适配器非常有用。您可以以与 Spring Integration 中任何其他轮询适配器相同的方式配置轮询器(或者您可以依赖默认轮询器)。object-name
和 attribute-name
是必需的。还需要 MBeanServer 引用。但是,默认情况下,它会自动检查名为 mbeanServer
的 bean,与前面描述的监听通知的通道适配器相同。以下示例显示了如何使用 XML 配置轮询属性的通道适配器
<int-jmx:attribute-polling-channel-adapter id="adapter"
channel="channel"
object-name="example.domain:name=someService"
attribute-name="InvocationCount">
<int:poller max-messages-per-poll="1" fixed-rate="5000"/>
</int-jmx:attribute-polling-channel-adapter>
树形轮询通道适配器
树形轮询通道适配器查询 JMX MBean 树并发送一条消息,其有效负载是与查询匹配的对象图。默认情况下,MBean 会映射到基元和简单对象,例如 Map
、List
和数组。这样做允许简单地转换为(例如)JSON。还需要 MBeanServer 引用。但是,默认情况下,它会自动检查名为 mbeanServer
的 bean,与前面描述的监听通知的通道适配器相同。以下示例显示了如何使用 XML 配置树形轮询通道适配器
<int-jmx:tree-polling-channel-adapter id="adapter"
channel="channel"
query-name="example.domain:type=*">
<int:poller max-messages-per-poll="1" fixed-rate="5000"/>
</int-jmx:tree-polling-channel-adapter>
前面的示例包含所选 MBean 上的所有属性。您可以通过提供配置了适当过滤器的 MBeanObjectConverter
来过滤属性。您可以使用 converter
属性将转换器作为对 bean 定义的引用提供,也可以使用内部 <bean/>
定义。Spring Integration 提供了一个 DefaultMBeanObjectConverter
,它可以在其构造函数参数中使用 MBeanAttributeFilter
。
Spring Integration 提供两个标准过滤器。NamedFieldsMBeanAttributeFilter
允许您指定要包含的属性列表。NotNamedFieldsMBeanAttributeFilter
允许您指定要排除的属性列表。您也可以实现自己的过滤器。
调用操作的通道适配器
调用操作的通道适配器支持由消息驱动的 MBean 公开的任何托管操作的调用。每次调用都需要调用操作名称和目标 MBean 的对象名称。这两个都必须通过适配器配置或通过 JmxHeaders.OBJECT_NAME
和 JmxHeaders.OPERATION_NAME
消息头显式提供
<int-jmx:operation-invoking-channel-adapter id="adapter"
object-name="example.domain:name=TestBean"
operation-name="ping"/>
然后,适配器只需要能够发现 mbeanServer
bean。如果需要不同的 bean 名称,则使用引用提供 mbean-server
属性。
消息的有效负载将映射到操作的参数(如果有)。具有 String
密钥的 Map
类型有效负载被视为名称/值对,而 List
或数组则作为简单的参数列表传递(没有显式参数名称)。如果操作需要单个参数值,则有效负载可以表示该单个值。此外,如果操作不需要参数,则有效负载将被忽略。
如果要公开一个通道,以便通过不需要包含标头的消息来调用单个常用操作,则最后一个选项效果很好。
调用操作的出站网关
与调用操作的通道适配器类似,Spring Integration 还提供了一个调用操作的出站网关,当处理需要返回值的非 void 操作时可以使用它。返回值作为消息有效负载发送到网关指定的 reply-channel
。以下示例显示了如何使用 XML 配置调用操作的出站网关
<int-jmx:operation-invoking-outbound-gateway request-channel="requestChannel"
reply-channel="replyChannel"
object-name="o.s.i.jmx.config:type=TestBean,name=testBeanGateway"
operation-name="testWithReturn"/>
如果不提供 reply-channel
属性,则回复消息将发送到由 IntegrationMessageHeaderAccessor.REPLY_CHANNEL
标头标识的通道。该标头通常由消息流的入口点自动创建,例如任何网关组件。但是,如果消息流是通过手动创建 Spring Integration 消息并将其直接发送到通道启动的,则必须显式指定消息头或使用 reply-channel
属性。
MBean 导出器
当配置 IntegrationMBeanExporter
时,Spring Integration 组件本身可以作为 MBean 公开。要创建 IntegrationMBeanExporter
的实例,请定义一个 bean 并提供对 MBeanServer
和域名(如果需要)的引用。您可以省略域名,在这种情况下,默认域名是 org.springframework.integration
。以下示例显示了如何声明 IntegrationMBeanExporter
实例和关联的 MBeanServer
实例
<int-jmx:mbean-export id="integrationMBeanExporter"
default-domain="my.company.domain" server="mbeanServer"/>
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true"/>
</bean>
MBean 导出器与 Spring 核心提供的导出器是正交的。它注册消息通道和消息处理器,但不注册自身。您可以使用标准 它还有一个有用的操作,如有序关闭托管操作中所述。 |
Spring Integration 4.0 引入了 @EnableIntegrationMBeanExport
注解,允许在 @Configuration
类级别方便地配置类型为 IntegrationMBeanExporter
的默认 integrationMbeanExporter
bean,并提供多个有用的选项。以下示例显示了如何配置此 bean
@Configuration
@EnableIntegration
@EnableIntegrationMBeanExport(server = "mbeanServer", managedComponents = "input")
public class ContextConfiguration {
@Bean
public MBeanServerFactoryBean mbeanServer() {
return new MBeanServerFactoryBean();
}
}
如果需要提供更多选项或拥有多个 IntegrationMBeanExporter
bean(例如,用于不同的 MBean 服务器或避免与标准 Spring MBeanExporter
冲突——例如通过 @EnableMBeanExport
),则可以将 IntegrationMBeanExporter
配置为通用 bean。
MBean 对象名称
应用程序中的所有 MessageChannel
、MessageHandler
和 MessageSource
实例都由 MBean 导出器包装,以提供管理和监控功能。下表列出了每种组件类型的生成的 JMX 对象名称
组件类型 | 对象名称 |
---|---|
MessageChannel |
`o.s.i:type=MessageChannel,name=<channelName>` |
MessageSource |
`o.s.i:type=MessageSource,name=<channelName>,bean=<source>` |
MessageHandler |
`o.s.i:type=MessageSource,name=<channelName>,bean=<source>` |
源和处理程序的对象名称中的 bean
属性采用下表中的一个值
Bean 值 | 描述 |
---|---|
endpoint |
如果存在,则为封闭端点(例如 |
anonymous |
指示封闭端点没有用户指定的 bean 名称,因此 JMX 名称是输入通道名称。 |
internal |
对于众所周知的 Spring Integration 默认组件 |
处理程序/源 |
以上均不适用。回退到正在监控的对象(处理程序或源)的 |
可以通过在object-name-static-properties
属性中提供对Properties
对象的引用,将自定义元素附加到对象名称。
此外,从Spring Integration 3.0开始,您可以通过设置object-naming-strategy
属性来使用自定义ObjectNamingStrategy
。这样做可以更好地控制MBean的命名,例如将所有集成MBean分组到“Integration”类型下。以下示例显示了一种可能的自定义命名策略实现。
public class Namer implements ObjectNamingStrategy {
private final ObjectNamingStrategy realNamer = new KeyNamingStrategy();
@Override
public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
String actualBeanKey = beanKey.replace("type=", "type=Integration,componentType=");
return realNamer.getObjectName(managedBean, actualBeanKey);
}
}
beanKey
参数是一个包含标准对象名称的String
,该名称以default-domain
开头,并包含任何附加的静态属性。前面的示例将标准的type
部分移到componentType
,并将type
设置为“Integration”,从而能够在一个查询中选择所有Integration MBean:`my.domain:type=Integration,*`。这样做还将这些Bean在一个域下的树条目下分组,例如在VisualVM等工具中。
默认命名策略是MetadataNamingStrategy 。导出器将default-domain 传播到该对象,以便如果bean key解析失败,它可以生成回退对象名称。如果您的自定义命名策略是MetadataNamingStrategy (或其子类),则导出器不会传播default-domain 。您必须在策略bean上配置它。 |
从5.1版本开始,任何bean名称(在对象名称中由name
键表示)如果包含任何在Java标识符(或句点.
)中不允许的字符,都将被引用。
JMX改进
4.2版本引入了一些重要的改进,代表了框架中JMX支持的相当大的改进。这些改进显著提高了JMX统计信息收集的性能,并提供了更多控制。但是,在一些特定(不常见)情况下,它对用户代码有一些影响。这些更改在下面详细说明,必要时会提出警告。
- @IntegrationManagedResource
-
类似于
@ManagedResource
注解,@IntegrationManagedResource
将一个类标记为可以导出为MBean。但是,只有当应用程序上下文具有IntegrationMBeanExporter
时,才会导出它。某些Spring Integration类(在
org.springframework.integration
包中)以前使用@ManagedResource
进行注释,现在同时使用@ManagedResource
和@IntegrationManagedResource
进行注释。这是为了向后兼容性(见下一项)。此类MBean由任何上下文MBeanServer
或IntegrationMBeanExporter
导出(但不是同时导出——如果两个导出器都存在,则如果bean匹配managed-components
模式,则该bean由集成导出器导出)。 - MBean导出器Bean名称模式
-
以前,
managed-components
模式仅包含。如果bean名称与其中一个模式匹配,则将其包含在内。现在,可以通过在模式前添加!
来否定模式。例如,!thing*, things
匹配所有不以thing
开头的bean名称,除了things
。模式从左到右进行评估。第一个匹配(正或负)获胜,然后不再应用其他模式。这种语法添加到模式中会导致一个可能(尽管可能不太可能)的问题。如果您有一个名为 "!thing"
的bean,并且您在MBean导出器的managed-components
模式中包含了!thing
模式,它将不再匹配;该模式现在匹配所有未命名为thing
的bean。在这种情况下,您可以使用\
转义模式中的!
。\!thing
模式匹配名为!thing
的bean。 - IntegrationMBeanExporter更改
-
IntegrationMBeanExporter
不再实现SmartLifecycle
。这意味着start()
和stop()
操作不再可用以注册和注销MBean。MBean现在在上下文初始化期间注册,并在上下文销毁时注销。
有序关闭管理操作
MBean导出器允许JMX操作以有序方式关闭应用程序。它旨在在停止JVM之前使用。以下示例显示了如何使用它。
public void stopActiveComponents(long howLong)
其用途和操作在有序关闭中进行了描述。