JMX 支援
Spring Integration 提供通道介面卡,用於接收和釋出 JMX 通知。
專案需要此依賴項
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
<version>7.0.0</version>
</dependency>
compile "org.springframework.integration:spring-integration-jmx:7.0.0"
入站通道介面卡允許輪詢 JMX MBean 屬性值,而出站通道介面卡允許呼叫 JMX MBean 操作。
通知監聽通道介面卡
通知監聽通道介面卡需要 JMX `ObjectName`,用於釋出通知的 MBean,此監聽器應註冊到該 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 的 ` |
該介面卡還可以接受對 `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`。它不需要任何輪詢器配置。
|
對於此元件,`object-name` 屬性可以包含物件名稱模式,例如 `org.something:type=MyType,name=*`。在這種情況下,介面卡會從所有物件名稱與模式匹配的 MBean 接收通知。此外,`object-name` 屬性可以包含一個 SpEL 引用,指向一個物件名稱模式的 `
當啟用 DEBUG 級別日誌記錄時,會記錄找到的 MBean 的名稱。 |
通知釋出通道介面卡
通知釋出通道介面卡相對簡單。它只需要配置中的 JMX 物件名稱,如下例所示:
<context:mbean-export/>
<int-jmx:notification-publishing-channel-adapter id="adapter"
channel="channel"
object-name="example.domain:name=publisher"/>
它還需要在上下文中存在一個 `MBeanExporter`。這就是為什麼在前面的示例中也顯示了 `
當訊息傳送到此介面卡的通道時,通知會從訊息內容建立。如果有效負載是 `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 樹,併發送一個訊息,其有效負載是與查詢匹配的物件圖。預設情況下,MBeans 對映到基本型別和簡單物件,例如 `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 定義的引用,或者您可以使用內部 `
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 還提供了一個操作調用出站閘道器,當處理需要返回值而非空操作時,您可以使用它。返回值作為訊息有效負載傳送到閘道器指定的 `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` 屬性,則回覆訊息將傳送到由 `MessageHeaders.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 Server 或避免與標準 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 |
如果存在,則為 enclosing endpoint 的 bean 名稱(例如 ` |
匿名 |
表示 enclosing endpoint 沒有使用者指定的 bean 名稱,因此 JMX 名稱是輸入通道名稱。 |
內部 |
對於眾所周知的 Spring Integration 預設元件 |
handler/source |
以上都不是。回退到被監控物件(處理器或源)的 `toString()` 方法 |
您可以透過在 `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”,從而可以在一次查詢中選擇所有整合 MBean:`my.domain:type=Integration,*`。這樣做還將 bean 分組到域下的一個樹條目中,例如在 VisualVM 等工具中。
| 預設命名策略是 `MetadataNamingStrategy`。匯出器將 `default-domain` 傳播到該物件,以便在解析 bean 鍵失敗時生成備用物件名稱。如果您的自定義命名策略是 `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` 模式匹配,則由整合匯出器匯出)。
- MBean 匯出器 Bean 名稱模式
-
以前,`managed-components` 模式只包含。如果 bean 名稱匹配其中一個模式,它就會被包含。現在,可以透過在其前面加上 `!` 來否定模式。例如,`!thing*, things` 匹配所有不以 `thing` 開頭但包含 `things` 的 bean 名稱。模式從左到右評估。第一個匹配(正向或反向)獲勝,然後不再應用其他模式。
此語法新增到模式中會導致一個可能的(儘管可能不太可能)問題。如果您有一個名為 `"!thing"` 的 bean,並且在 MBean 匯出器的 `managed-components` 模式中包含一個模式 `!thing`,它將不再匹配;該模式現在匹配所有不名為 `thing` 的 bean。在這種情況下,您可以在模式中用 `\` 轉義 `!`。`\!thing` 模式匹配名為 `!thing` 的 bean。 - IntegrationMBeanExporter 更改
-
`IntegrationMBeanExporter` 不再實現 `SmartLifecycle`。這意味著 `start()` 和 `stop()` 操作不再可用於註冊和登出 MBean。MBean 現在在上下文初始化期間註冊,並在上下文銷燬時登出。
有序關閉託管操作
MBean 匯出器允許 JMX 操作以有序的方式關閉應用程式。它旨在在停止 JVM 之前使用。其使用和操作在有序關閉中描述。