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 的 `` 元素時生成的 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`。它不需要任何輪詢器配置。

對於此元件,`object-name` 屬性可以包含物件名稱模式,例如 `org.something:type=MyType,name=*`。在這種情況下,介面卡會從所有物件名稱與模式匹配的 MBean 接收通知。此外,`object-name` 屬性可以包含一個 SpEL 引用,指向一個物件名稱模式的 ``,如下例所示:

<jmx:notification-listening-channel-adapter id="manyNotificationsAdapter"
    channel="manyNotificationsChannel"
    object-name="#{patterns}"/>

<util:list id="patterns">
    <value>org.foo:type=Foo,name=*</value>
    <value>org.foo:type=Bar,name=*</value>
</util:list>

當啟用 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 提供了一個 `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 還提供了一個操作調用出站閘道器,當處理需要返回值而非空操作時,您可以使用它。返回值作為訊息有效負載傳送到閘道器指定的 `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 中的某些其他元件)。匯出器附加了一些度量指標,例如處理器的數量和佇列中訊息的數量。

它還有一個有用的操作,如有序關閉託管操作中所述。

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 物件名稱:

表1. MBean 物件名稱
元件型別 物件名稱

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` 屬性採用下表中的值之一:

表2. 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 之前使用。其使用和操作在有序關閉中描述。

© . This site is unofficial and not affiliated with VMware.