legacy-knowledge-base
公開されました Sep. 10, 2025

ConfigurationModelListener は両方のノードで実行されます。

written-by

Sorin Pop

How To articles are not official guidelines or officially supported documentation. They are community-contributed content and may not always reflect the latest updates to Liferay DXP. We welcome your feedback to improve How To articles!

While we make every effort to ensure this Knowledge Base is accurate, it may not always reflect the most recent updates or official guidelines.We appreciate your understanding and encourage you to reach out with any feedback or concerns.

legacy-article

learn-legacy-article-disclaimer-text

問題

  • ConfigurationModelListenerを実装したモデルリスナーを使って、システム設定の変更を追跡するモジュールを開発した。 すべてが正常に機能しているが、このモジュールが両方のノードで実行されるという問題がある。 通常、ノード1でリクエストが発生すると、対応するアクションがノード1で行われる。 しかし、このシナリオでは、ノード1とノード2の両方で実行される。

    再現の手順
    1. 2 ノードのクラスタをセットアップする。
    2. ノードの1つで、コントロールパネル > システム設定 > セキュリティ > 監査にアクセスし、有効のチェックボックスをオフにして保存します。 (この設定の初期保存を行うだけ)
    3. アタッチされたPoCモジュールを両方のノードにデプロイする。 (Liferay-configlistener-clusterIssue.zip)
    4.
    結果:両方のノードで出力され、両方のノードで呼び出しが発生していることがわかる。
    期待されること:デプロイ可能なJARを呼び出すと、クラスタ化されたサーバーの一方のノードでのみログが出力されるはずである:期待されるのは、デプロイ可能なJARを呼び出すと、クラスタ化されたサーバーの1つのノードにのみログが出力されることです。

環境

  • 7.4

解像度

  • 私たちのチームは ConfigurationModelListenerの再設計に取り組んでいます。 現在の設計は、コンフィギュレーションの検証のみを目的としており、クラスタ全体で実行することは想定していない。 この再設計には時間がかかりますので、ConfigurationModelListener を使用して、次のような代替案を提案します:

    import org.osgi.service.cm.ConfigurationEvent; 
    import org.osgi.service.cm.ConfigurationListener;
    import org.osgi.service.component.annotations.Component;

    @Component(service = ConfigurationListener.class)
    public class TracingConfigurationListener implements ConfigurationListener {
    @Override
    public void configurationEvent(ConfigurationEvent configurationEvent) {
    System.out.println("############Configuration Event : " + configurationEvent.getType() + " for " + configurationEvent.getPid());
    }
    }


    この解決策は、 ConfigurationModelListenerの代わりに ConfigurationListener 作成し、 、設定イベントをリッスンすることに基づいています。 configurationEvent メソッドのみを実装する必要があります

    先に提供したPoCでは、クラス GenericConfigurationListenerが 作成さ れ、メソッド onBeforeSaveが実装されています 。 私たちの提案では、次のことが必要だ:
    1. ConfigurationModelListener の代わりに ConfigurationListener を実装するようにクラスを適応する。
    2. onBeforeSave のロジックを、新たに必要なメソッド configurationEventに実装する。
    3. configurationEvent.getPid() がリッスンしたいコンフィギュレーション(com.liferay.portal.security.audit.configuration.AuditConfiguration)と等しいことを確認します。
    4. 必要な種類の configurationEvent (ConfigurationEvent.CM_UPDATED ConfigurationEvent.CM_DELETED)のロジックだけを適用する必要があります。

    物事を明確にするために、例えば私たちのクラスを見てみましょう。 https://github.com/liferay/liferay-portal/blob/88cf28caf54d71b332b6fd1bc2bb07ed29b847a7/modules/apps/portal-security/portal-security-ldap-impl/src/main/java/com/liferay/portal/security/ldap/internal/configuration/LDAPConfigurationListener.java を見てください。 を実装しています。.

    また、もしあなたのコードが各ノード上で実行される必要があるのであれば、それらを別のクラスに抽出することができます。 Clusterable アノテーションか ClusterExecutorUtil を使うことができます: https://help.liferay.com/hc/en-us/articles/360018154832-Liferay-s-Clustering-API

    要約すると
    • ConfigurationModelListener ロジックが変更され、おそらくクラスタ内で実行されなくなります。
    • コンフィギュレーションの変更をリッスンしたい場合は、(再設計されることを考慮した)現在のアプローチを使用するか、上記の私たちのアプローチに従うことができます。
    • 設定変更に耳を傾けたら、 @Clusterable アノテーションまたは ClusterExecutorUtilを使って好きなコードを実行できます。

追加情報

did-this-article-resolve-your-issue

legacy-knowledge-base