JMX サポート

Spring Integration は、JMX 通知を受信および公開するためのチャネルアダプターを提供します。

この依存関係をプロジェクトに含める必要があります。

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-jmx</artifactId>
    <version>6.4.1</version>
</dependency>
compile "org.springframework.integration:spring-integration-jmx:6.4.1"

受信チャネルアダプターは JMX MBean 属性値のポーリングを許可し、発信チャネルアダプターは JMX MBean 操作の呼び出しを許可します。

通知リスニングチャネルアダプター

通知リスニングチャネルアダプターには、このリスナーを登録する通知を発行する MBean の JMX ObjectName が必要です。非常に単純な構成は、次のようになります。

<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"/>

_Notification-listening チャネルアダプターはイベント駆動型であり、MBeanServer に直接登録されます。ポーラー構成は必要ありません。

このコンポーネントの場合のみ、object-name 属性にはオブジェクト名パターンを含めることができます(たとえば、「org.something:type = MyType、name = *」)。その場合、アダプターは、パターンに一致するオブジェクト名を持つすべての MBean から通知を受け取ります。さらに、次の例に示すように、object-name 属性には、オブジェクト名パターンの <util:list> への 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 がコンテキストに存在する必要があります。そのため、前の例で <context:mbean-export/> 要素も示されています。

このアダプターのチャネルにメッセージが送信されると、メッセージのコンテンツから通知が作成されます。ペイロードが String である場合、通知の message テキストとして渡されます。その他のペイロード型は、通知の userData として渡されます。

JMX 通知には type もあり、ドット区切りの String である必要があります。type を提供するには 2 つの方法があります。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 は MapList、配列などのプリミティブおよび単純なオブジェクトにマップされます。そうすることで、(たとえば) 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 は、コンストラクター引数で MBeanAttributeFilter を取ることができる DefaultMBeanObjectConverter を提供します。

Spring Integration は 2 つの標準フィルターを提供します。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 -typed ペイロードは名前 / 値のペアとして扱われますが、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 エクスポーター

Spring Integration コンポーネントは、IntegrationMBeanExporter の構成時に 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 コアで提供されるものと直交しています。メッセージチャネルとメッセージハンドラーを登録しますが、それ自体は登録しません。標準の <context:mbean-export/> タグを使用して、エクスポーター自体(および Spring Integration の他の特定のコンポーネント)を公開できます。エクスポータには、ハンドラーの数やキューに入れられたメッセージの数など、いくつかのメトリクスが関連付けられています。

正常なシャットダウン管理操作で説明したように、便利な操作もあります。

Spring Integration 4.0 は、@Configuration クラスレベルでいくつかの便利なオプションを備えた型 IntegrationMBeanExporter のデフォルト integrationMbeanExporter Bean の便利な設定を可能にする @EnableIntegrationMBeanExport アノテーションを導入しました。次の例は、この Bean を構成する方法を示しています。

@Configuration
@EnableIntegration
@EnableIntegrationMBeanExport(server = "mbeanServer", managedComponents = "input")
public class ContextConfiguration {

	@Bean
	public MBeanServerFactoryBean mbeanServer() {
		return new MBeanServerFactoryBean();
	}
}

より多くのオプションを提供したり、複数の IntegrationMBeanExporter Bean が必要な場合(異なる MBean サーバー用、または @EnableMBeanExport などを介して標準 Spring MBeanExporter との競合を避けるため)、IntegrationMBeanExporter を汎用 Bean として構成できます。

MBean オブジェクト名

アプリケーション内のすべての MessageChannelMessageHandlerMessageSource インスタンスは、管理および監視機能を提供するために 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 ObjectName パーツ
Bean 値 説明

endpoint

囲んでいるエンドポイントの Bean 名(例: <service-activator>)(ある場合)

anonymous

囲んでいるエンドポイントにユーザー指定の Bean 名がなかったことを示すため、JMX 名は入力チャネル名です。

internal

よく知られている Spring Integration のデフォルトコンポーネント

ハンドラー / ソース

上記のどれでもない。監視されているオブジェクトの toString() メソッドにフォールバックします (ハンドラーまたはソース)

object-name-static-properties 属性で Properties オブジェクトへの参照を提供することにより、オブジェクト名にカスタム要素を追加できます。

また、Spring Integration 3.0 以降、object-naming-strategy 属性を設定することにより、カスタム ObjectNamingStrategy (Javadoc) を使用できます。そうすることで、すべての統合 MBean を「統合」型にグループ化するなど、MBean の命名をより詳細に制御できます。次の例は、1 つの可能なカスタム命名戦略の実装を示しています。

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 を「統合」に設定して、1 つのクエリですべての統合 MBean を選択できるようにします: `my.domain:type=Integration,*`。そうすることで、VisualVM などのツールのドメインにある 1 つのツリーエントリに Bean をグループ化することもできます。

デフォルトの命名戦略は MetadataNamingStrategy (Javadoc) です。エクスポーターは、default-domain をそのオブジェクトに伝搬して、Bean キーの解析が失敗した場合にフォールバックオブジェクト名を生成できるようにします。カスタム命名戦略が MetadataNamingStrategy (またはそのサブクラス)の場合、エクスポーターは default-domain を伝搬しません。戦略 Bean で設定する必要があります。

バージョン 5.1 以降、Java 識別子 (またはピリオド .) で許可されていない文字が含まれている場合、Bean 名 (オブジェクト名の name キーで表される) は引用符で囲まれます。

JMX の改善

バージョン 4.2 はいくつかの重要な改善を導入し、フレームワークでの JMX サポートのかなり大きなオーバーホールを表します。これらにより、JMX 統計収集のパフォーマンスが大幅に向上し、その制御が大幅に向上しました。ただし、いくつかの特定の(珍しい)状況では、ユーザーコードにいくつかの影響があります。これらの変更の詳細を以下に示しますが、必要な場合は注意してください。

@IntegrationManagedResource

@ManagedResource アノテーションと同様に、@IntegrationManagedResource はクラスを MBean としてエクスポートする資格があるものとしてマークします。ただし、アプリケーションコンテキストに IntegrationMBeanExporter がある場合にのみエクスポートされます。

以前に @ManagedResource でアノテーションが付けられていた特定の Spring Integration クラス(org.springframework.integration 内)パッケージには、@ManagedResource と @IntegrationManagedResource の両方でアノテーションが付けられるようになりました。これは下位互換性のためです(次の項目を参照)。このような MBean は、任意のコンテキスト MBeanServer または IntegrationMBeanExporter によってエクスポートされます(両方ではありません。両方のエクスポーターが存在する場合、Bean が managed-components パターンと一致すると、Bean は統合エクスポーターによってエクスポートされます)。

MBean エクスポーター Bean の名前パターン

以前は、managed-components パターンは包括的のみでした。Bean 名がパターンの 1 つと一致した場合、その名前が含まれます。これで、パターンの前に ! を付けることで、パターンを無効にすることができます。例: !thing*, things は、things を除き、thing で始まらないすべての Bean 名に一致します。パターンは左から右に評価されます。最初の一致(正または負)が勝ち、それ以降のパターンは適用されません。

この構文をパターンに追加すると、1 つの可能性のある(おそらくありそうもない)問題が発生します。"!thing" という名前の Bean があり、MBean エクスポーターの managed-components パターンに !thing のパターンを含めた場合、一致しなくなります。パターンは thing という名前ではないすべての Bean に一致するようになりました。この場合、\ を使用して、パターン内の ! をエスケープできます。\!thing パターンは、!thing という名前の Bean と一致します。
IntegrationMBeanExporter の変更

IntegrationMBeanExporter は SmartLifecycle を実装しなくなりました。これは、MBean の登録および登録解除に start() および stop() 操作が使用できなくなったことを意味します。MBean は、コンテキストの初期化中に登録され、コンテキストが破棄されると登録解除されます。

正常なシャットダウン管理操作

MBean エクスポータを使用すると、JMX 操作でアプリケーションを正常にシャットダウンできます。これは、JVM を停止する前に使用することを目的としています。次の例は、その使用方法を示しています。

public void stopActiveComponents(long howLong)

その使用と操作は正常なシャットダウンで説明されています。