Message Bus
ご覧のページは、お客様の利便性のために一部機械翻訳されています。また、ドキュメントは頻繁に更新が加えられており、翻訳は未完成の部分が含まれることをご了承ください。最新情報は都度公開されておりますため、必ず英語版をご参照ください。翻訳に問題がある場合は、 こちら までご連絡ください。

メッセージングパフォーマンスの調整

Liferay DXP 2023.Q3/Portal GA92 以前 サポート対象外

重要

このチュートリアルで説明するメッセージング API は、Liferay DXP 2023.Q3/Portal GA92 以降では利用できません。

メッセージングのパフォーマンスは、送信先で調整されます。 パフォーマンスは、送信先の種類、メッセージリスナーが必要とする処理量、およびメッセージを処理するために利用可能なスレッドプールによって異なります。

目的地の種類は以下の3つです。

並行目的地

  • ここで送信されたメッセージはキューに入れられます。
  • スレッドプールのワーカースレッドは、登録されたメッセージリスナーにメッセージを配信します。1つのメッセージリスナーにつきメッセージごとに1つのワーカースレッドがあります。 スレッドは、同じメッセージを宛先のメッセージリスナーに同時に配信します。

シリアル宛先

  • ここで送信されたメッセージはキューに入れられます。
  • スレッドプールのワーカースレッドは、登録されたメッセージリスナーにメッセージを配信します(メッセージごとに1つのワーカースレッド)。

同期宛先

  • ここで送信されるメッセージは、メッセージリスナーに直接配信されます。
  • メッセージを送信するスレッドは、すべてのメッセージリスナーにもメッセージを配信します。

適切な送信先タイプを使用することで、さまざまな方法でメッセージを送信できます。

宛先タイプの互換性

以下は、各宛先タイプと 非同期メッセージングデフォルト同期メッセージング、および 直接同期メッセージング との互換性です。

宛先タイプ非同期メッセージングデフォルトの同期メッセージング直接同期メッセージング
パラレル
シリアル
同期

ここではまず、あるプロジェクトのメッセージングパフォーマンスを検証することから始めます。 次に、APIを使用して宛先の統計情報を取得し、宛先を設定します。 最後に、サンプル送信先の設定を再構成し、サンプルを再実行して、統計情報を確認します。

サンプルプロジェクトにおけるメッセージングの監視

このサンプルプロジェクトでは、Gogoシェルコマンドを使用して、宛先を作成し、メッセージリスナーを登録し、宛先の統計情報を一覧表示します。

Liferay の新しいインスタンスを起動するには、次のコマンドを実行します。

docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.132-ga132

http://localhost:8080 で Liferay にサインインしてください。 メールアドレス test@liferay.com とパスワード test を使用してください。 プロンプトが表示されたら、パスワードを learn に変更してください。

次に、以下の手順に従ってください。

  1. サンプルをダウンロードして解凍してください。

    curl https://resources.learn.liferay.com/examples/liferay-w3r2.zip -O
    
    unzip liferay-w3r2.zip
    
  2. サンプルプロジェクトのモジュールをビルドしてデプロイします。

    cd liferay-w3r2
    
    ./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
    
    注記

    このコマンドは、モジュール JAR を Docker コンテナ上の /opt/liferay/osgi/modules にコピーすることと同じです。

  3. Dockerコンテナコンソールは、モジュールの起動を確認し、宛先構成を報告します。

    com.acme.w3r2.charlie.impl_1.0.0 [1390]
    com.acme.w3r2.able.impl_1.0.0 [1388]
    [W3R2AbleMessagingConfigurator:27] {_destinationName=acme/w3r2_able,
    _destinationType=serial, _maximumQueueSize=2147483647,
    _rejectedExecutionHandler=null, _workersCoreSize=2, _workersMaxSize=5}
    com.acme.w3r2.baker.impl_1.0.0 [1389] を開始しました
    
  4. ブラウザで http://localhost:8080 にアクセスして Liferay インスタンスを開き、認証情報を使用してサインインしてください。

  5. スクリプトコンソール を開きます。

  6. スクリプト欄に、以下のGroovyコードを実行してメッセージを送信してください。

    import com.liferay.portal.kernel.messaging.*;
    
    MessageBusUtil.sendMessage(
        "acme/w3r2_able",
        new Message() {
            {
                setPayload("foo");
            }
    });
    
  7. W3R2BakerMessageListenerManager のメッセージリスナーがメッセージを受信したことを確認してください。

    [acme/w3r2_able-2][W3R2BakerMessageListenerManager:30] メッセージペイロード foo
    を受信しました [acme/w3r2_able-2][W3R2BakerMessageListenerManager:30] メッセージペイロード foo
    を受信しました [acme/w3r2_able-2][W3R2BakerMessageListenerManager:30] メッセージペイロード foo
    を受信しました [acme/w3r2_able-2][W3R2BakerMessageListenerManager:30] メッセージペイロード foo
    を受信しました [acme/w3r2_able-2][W3R2BakerMessageListenerManager:30] メッセージペイロード foo を受信しました
    
  8. Gogoシェル を開きます。

  9. Gogoシェルコマンドフィールドで w3r2:listDestinationStats コマンドを実行して、宛先の統計情報を取得します。

    w3r2:listDestinationStats
    
  10. acme/w3r2_able 宛先の 10 個のリスナーと送信されたメッセージ数を確認します。

    [pipe-w3r2:listDestinationStats][W3R2CharlieOSGiCommands:29] acme/w3r2_able
    アクティブスレッド数 0、現在のスレッド数 1、最大スレッド数 1、最大
    スレッドプールサイズ 1、メッセージリスナー数 10、最小スレッドプールサイズ 1、保留中の
    メッセージ数 0、送信済みメッセージ数 1
    

この例の3つのモジュールは、宛先を設定し、10個のメッセージリスナーを登録し、宛先の統計情報を一覧表示するためのGogoシェルコマンドを提供します。

W3R2AbleMessagingConfiguratorw3r2-able-impl でアクティブ化されると、 acme/w3r2_able 宛先を構成し、 DestinationConfigurationtoString() の値をログに記録します。

@Activate
private void _activate(BundleContext bundleContext) {
	DestinationConfiguration destinationConfiguration =
		DestinationConfiguration.createSerialDestinationConfiguration(
			"acme/w3r2_able");

	if (_log.isInfoEnabled()) {
		_log.info(destinationConfiguration.toString());
	}

	Destination destination = _destinationFactory.createDestination(
		destinationConfiguration);

	_serviceRegistration = bundleContext.registerService(
		Destination.class, destination,
		MapUtil.singletonDictionary(
			"destination.name", destination.getName()));
}

w3r2-charlie-implモジュール内のW3R2CharlieOSGiCommands は、同モジュールが提供する Gogo シェルコマンド「w3r2:listDestinationStats」を使用して、宛先統計情報をログに記録します。 W3R2CharlieOSGiCommandslistDestinationStats() メソッドが宛先統計情報を取得する方法を調べます。

@Component(
	property = {
		"osgi.command.function=listDestinationStats", "osgi.command.scope=w3r2"
	},
	service = W3R2CharlieOSGiCommands.class
)
public class W3R2CharlieOSGiCommands {

	public void listDestinationStats() {
		if (_log.isInfoEnabled()) {
			Destination destination = _messageBus.getDestination(
				"acme/w3r2_able");

			DestinationStatistics destinationStatistics =
				destination.getDestinationStatistics();

			_log.info(
				StringBundler.concat(
					"acme/w3r2_able アクティブ スレッド カウント "、
					destinationStatistics.getActiveThreadCount()、
					"、 現在のスレッド カウント "、
					destinationStatistics.getCurrentThreadCount()、
					"、最大スレッド数 "、
					destinationStatistics.getLargestThreadCount()、
					"、最大スレッドプールサイズ "、
					destinationStatistics.getMaxThreadPoolSize()、
					"、メッセージリスナー数 "、
					destination.getMessageListenerCount()、
					"、最小スレッドプールサイズ "、
					destinationStatistics.getMinThreadPoolSize()、
					"、保留中のメッセージ数 "、
					destinationStatistics.getPendingMessageCount()、
					"、送信メッセージ数 "、
					destinationStatistics.getSentMessageCount()));
		}
	}

	private static final Log _log = LogFactoryUtil.getLog(
		W3R2CharlieOSGiCommands.class);

	@Reference
	private MessageBus _messageBus;

}

listDestinationStats() メソッドは、 _messageBus インスタンスを使用して Destination を取得し、次に宛先から DestinationStatistics インスタンスを取得します。 宛先は、最新の統計情報で DestinationStatistics オブジェクトを設定します。 このメソッドは、以下の宛先情報をログに記録します。

  • アクティブなスレッド数
  • 現在のスレッド数
  • 最大スレッド数
  • 最大スレッドプールサイズ
  • メッセージリスナー数
  • 最小(開始)スレッドプールサイズ
  • 保留中のメッセージ数
  • 送信されたメッセージ数

この同じAPIを使用して、メッセージの送信先を監視することもできます。

メッセージングの監視

メッセージングAPIは、送信先の設定を考慮した上で、送信先におけるメッセージングのパフォーマンスを監視することを可能にします。 以下の表は、宛先設定とメッセージング統計にアクセスするためのAPIメソッドを示しています。

宛先設定:

宛先設定APIメソッド
宛先タイプDestination#getDestinationType()
最大スレッドプールサイズDestinationConfiguration#getWorkersMaxSize() および DestinationStatistic#getMaxThreadPoolSize()
最小スレッドプールサイズDestinationConfiguration#getWorkersCoreSize() および DestinationStatistic#getMinThreadPoolSize()
メッセージキューのサイズDestinationConfiguration#getMaximumQueueSize()

目的地統計:

宛先統計APIメソッド
メッセージリスナー数Destination#getMessageListenerCount()
保留中のメッセージの数DestinationStatistics#getPendingMessageCount()
送信されたメッセージ数DestinationStatistics#getSentMessageCount()
現在のスレッド数DestinationStatistics#getCurrentThreadCount()
アクティブなスレッド数DestinationStatistics#getActiveThreadCount()
最大スレッド数DestinationStatistics#getLargestThreadCount()

旅行先の統計データは、その場所の環境を考慮に入れて理解するようにしてください。

宛先統計を調べた上で、宛先を再設定することでパフォーマンスを改善できる可能性があります。

宛先タイプの変更

シリアル宛先を使用している場合で、メッセージが一部のメッセージリスナーに十分な速さで届かない場合は、最大スレッドプールサイズを増やす(次で説明します)か、並列宛先タイプに切り替えてみてください。 メッセージバスは、スレッドプールからのスレッドを使用して、並列の宛先メッセージリスナーを同時に処理します。

現在の DestinationConfiguration を目的のタイプのいずれかに置き換えることで、宛先タイプを切り替えることができます。 適切な DestinationConfiguration メソッドを使用して、新しい並列または直列の DestinationConfiguration を作成します。

  • createParallelDestinationConfiguration(String)
  • createSerialDestinationConfiguration(String)

詳細については、 サンプル宛先の再設定 を参照してください。

メッセージキューとスレッドプールの設定

各シリアルおよびパラレル宛先には、メッセージキューと専用のスレッドプールが備わっています。

キューが満杯のときにメッセージが到着した場合、宛先の RejectedExecutionHandler がメッセージを処理します。 デフォルトのハンドラはメッセージを破棄し、警告をログに記録します。 デフォルトの最大メッセージキューサイズはJavaの最大整数値ですが、必要に応じて小さくすることもできます。

メッセージバスは、宛先のスレッドプールからメッセージリスナー処理スレッドを取得します。 プールには開始サイズと最大サイズがある。

これらの DestinationConfiguration メソッドを使用すると、最大メッセージキューサイズ、拒否された実行ハンドラ、スレッドプールの開始サイズ (コアサイズ)、およびスレッドプールの最大サイズを変更できます。

  • setMaximumQueueSize(int maximumQueueSize)
  • setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler)
  • setWorkersCoreSize(int workersCoreSize)
  • setWorkersMaxSize(int workersMaxSize)

次に、サンプル宛先を再設定します。

サンプル宛先を再構成する

ここでは、例の acme/w3r2_able 宛先を以下の設定で再構成します。

  • 宛先タイプ:parallel
  • 開始スレッドプールサイズ:10
  • 最大スレッドプールサイズ:20

手順は以下のとおりです。

  1. DestinationConfiguration を、 W3R2AbleMessagingConfigurator_activate(BundleContext) メソッドをこのコードに置き換えることで、別の を使用してください。

    @Activate
    private void _activate(BundleContext bundleContext) {
        DestinationConfiguration destinationConfiguration =
            DestinationConfiguration.createParallelDestinationConfiguration(
                "acme/w3r2_able");
    
        destinationConfiguration.setWorkersCoreSize(10);
        destinationConfiguration.setWorkersMaxSize(20);
    
        if (_log.isInfoEnabled()) {
            _log.info(destinationConfiguration.toString());
        }
    
        Destination destination = _destinationFactory.createDestination(
            destinationConfiguration);
    
        _serviceRegistration = bundleContext.registerService(
            Destination.class, destination,
            MapUtil.singletonDictionary(
                "destination.name", destination.getName()));
    }
    
  2. モジュールを再デプロイしてください。

    ./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
    
  3. Dockerコンテナコンソールは、 w3r2-able-impl モジュールの起動を確認し、宛先構成を報告します。

    com.acme.w3r2.able.impl_1.0.0 [1388]
    [W3R2AbleMessagingConfigurator:27] {_destinationName=acme/w3r2_able,
    _destinationType=parallel, _maximumQueueSize=2147483647,
    _rejectedExecutionHandler=null, _workersCoreSize=10, _workersMaxSize=20}
    
  4. このGogoシェルコマンドを実行して、メッセージリスナーモジュール(Acme W3R2 Baker実装)のIDを取得します。

    lb | grep W3R2
    

    各行は、対応するモジュールのID番号で始まります。

    1388|アクティブ | 10|Acme W3R2 Able実装 (1.0.0)|1.0.0
    1389|アクティブ | 10|Acme W3R2 Baker実装 (1.0.0)|1.0.0
    1390|アクティブ | 10|Acme W3R2 Charlie実装 (1.0.0)|1.0.0
    
  5. 以下のGogoシェルコマンドを使用してメッセージリスナーモジュールを再起動し、メッセージリスナーを宛先置換にバインドします。 番号をモジュールのIDに置き換えてください。

    停留所1389
    
    開始 1389
    
  6. スクリプトコンソールで以下のGroovyコードを再度実行して、別のメッセージを送信してください。

    import com.liferay.portal.kernel.messaging.*;
    
    MessageBusUtil.sendMessage(
        "acme/w3r2_able",
        new Message() {
            {
                setPayload("foo");
            }
    });
    
  7. Gogoシェルで w3r2:listDestinationStats コマンドを実行して、宛先の統計情報を取得します。

    w3r2:listDestinationStats
    

このようなログメッセージが表示されれば、新しい設定が正しく適用されたことが確認できます。

[pipe-w3r2:listDestinationStats][W3R2CharlieOSGiCommands:29] acme/w3r2_able
アクティブスレッド数 0、現在のスレッド数 10、最大スレッド数 10、最大
スレッドプールサイズ 20、メッセージリスナー数 10、最小スレッドプールサイズ 10、
保留中のメッセージ数 0、送信済みメッセージ数 2

これで、宛先でのメッセージングを監視し、宛先設定を調整する方法がわかりました。 パフォーマンスを最適化するために、さまざまな設定をテストできます。