|
如需使用最新稳定版本,请使用 Spring Integration 7.0.4! |
JMX 支持
Spring Integration 提供了通道适配器,用于接收和发布 JMX 通知。
您需要将以下依赖项包含到您的项目中:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
<version>6.4.10</version>
</dependency>
compile "org.springframework.integration:spring-integration-jmx:6.4.10"
入站通道适配器允许轮询 JMX MBean 属性值,而出站通道适配器允许调用 JMX MBean 操作。
通知监听通道适配器
通知监听通道适配器需要一个 JMX ObjectName,用于发布该监听器应注册的 MBean 的通知。
一个非常简单的配置可能如下所示:
<int-jmx:notification-listening-channel-adapter id="adapter"
channel="channel"
object-name="example.domain:name=publisher"/>
The notification-listening-channel-adapter registers with an MBeanServer at startup, and the default bean name is mbeanServer, which happens to be the same bean name generated when using Spring's <context:mbean-server/> element.
If you need to use a different name, be sure to include the mbean-server attribute. |
适配器还可以接受对 NotificationFilter 的引用以及一个“回传”对象,以提供随每次通知一起返回的上下文信息。
这两个属性都是可选的。
在 preceding example(前例)的基础上扩展,包含这些属性以及一个明确的 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"/>
The _Notification-listening channel adapter is event-driven and registered with the MBeanServer directly.
It does not require any poller configuration.
|
对于此组件,
当启用 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 提供了两个标准过滤器。
The NamedFieldsMBeanAttributeFilter 允许您指定要包含的属性列表。
The 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 Core 中提供的导出器是正交的。
它注册消息通道和消息处理器,但不会注册自身。
您可以使用标准的 它还有一个有用的操作,如有序关闭托管操作中所讨论的。 |
Spring Integration 4.0 引入了 @EnableIntegrationMBeanExport 注解,以便在 @Configuration 类级别方便地配置一个默认类型的 integrationMbeanExporter Bean(类型为 IntegrationMBeanExporter),并提供多种实用选项。
以下示例展示了如何配置此 Bean:
@Configuration
@EnableIntegration
@EnableIntegrationMBeanExport(server = "mbeanServer", managedComponents = "input")
public class ContextConfiguration {
@Bean
public MBeanServerFactoryBean mbeanServer() {
return new MBeanServerFactoryBean();
}
}
如果您需要提供更多选项或拥有多个 IntegrationMBeanExporter bean(例如用于不同的 MBean Server 或为避免与标准 Spring MBeanExporter 发生冲突——例如通过 @EnableMBeanExport),您可以将 IntegrationMBeanExporter 配置为通用 bean。
MBean 对象名称
应用程序中的所有 MessageChannel、MessageHandler 和 MessageSource 实例均通过 MBean 导出器进行包装,以提供管理和监控功能。
每种组件类型生成的 JMX 对象名称列在下表中:
| 组件类型 | 对象名称 |
|---|---|
消息通道 |
`o.s.i:type=MessageChannel,name=<channelName>` |
消息源 |
`o.s.i:type=MessageSource,name=<channelName>,bean=<source>` |
消息处理器 |
`o.s.i:type=MessageSource,name=<channelName>,bean=<source>` |
源和处理器对象名称中的bean属性取以下表格中的一个值:
| Bean 值 | 描述 |
|---|---|
端点 |
包含端点的 Bean 名称(例如 |
匿名 |
指示封闭端点没有用户指定的 Bean 名称,因此 JMX 名称为输入通道名称。 |
内部 |
对于知名的 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,*`。
这样做还会在VisualVM等工具中将这些bean分组到域下的一个树条目下。
默认命名策略是一个 MetadataNamingStrategy。
导出器会将 default-domain 传播到该对象,以便在 bean 键解析失败时生成一个备用对象名称。
如果您的自定义命名策略是 MetadataNamingStrategy(或其子类),则导出器不会传播 default-domain。
您必须在您的策略 bean 上配置它。 |
从版本 5.1 开始,任何包含 Java 标识符(或点号 .)中不允许的字符的 bean 名称(在对象名称中表示为 name 键),都将被引号括起来。
JMX 改进
版本 4.2 引入了一些重要的改进,代表了框架中 JMX 支持的重大重构。 这些改进显著提升了 JMX 统计数据的收集性能,并提供了更多的控制能力。 然而,在某些特定的(不常见的)场景下,它对用户代码产生了一些影响。 以下将详细说明这些变更,并在必要时给出警告。
- @集成管理资源
-
与
@ManagedResource注解类似,@IntegrationManagedResource将类标记为可导出为 MBean。 然而,仅当应用上下文包含IntegrationMBeanExporter时才会被导出。某些 Spring Integration 类(位于
org.springframework.integration包中)之前使用@ManagedResource注解,现在同时使用@ManagedResource和@IntegrationManagedResource注解。 这是为了向后兼容(见下一项)。 此类 MBean 由任何上下文MBeanServer或IntegrationMBeanExporter导出(但不会两者都导出——如果两个导出器都存在,且该 Bean 匹配managed-components模式,则通过集成导出器导出该 Bean)。 - MBean Exporter Bean 名称模式
-
此前,
managed-components模式仅表示包含匹配。 如果 bean 名称与任一模式匹配,则该 bean 会被包含。 现在,可以通过在模式前添加!来否定该模式。 例如,!thing*, things匹配所有不以thing开头的 bean 名称,但排除things。 模式的评估顺序为从左到右。 第一个匹配(无论是正向还是负向)生效,之后不再应用其他模式。将这种语法添加到模式中会导致一个可能(尽管不太可能)的问题。 如果您有一个名为 "!thing"的 Bean,并且在 MBean 导出器的managed-components模式中包含了!thing,那么它将不再匹配;此时该模式将匹配所有名称不为thing的 Bean。 在这种情况下,您可以使用\对模式中的!进行转义。\!thing模式将匹配名为!thing的 Bean。 - IntegrationMBeanExporter 变更
-
The
IntegrationMBeanExporter不再实现SmartLifecycle。 这意味着start()和stop()操作不再可用于注册和注销 MBean。 MBean 现在在上下文初始化期间注册,并在上下文销毁时注销。
有序关闭管理操作
MBean 导出器允许通过 JMX 操作以有序的方式关闭应用程序。 它旨在在停止 JVM 之前使用。 以下示例展示了如何使用它:
public void stopActiveComponents(long howLong)
其使用和操作在 有序关闭 中描述。