ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server JMSのプログラミング
11gリリース1 (10.3.6)
B61629-04
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

13 拡張パブリッシュ/サブスクライブ・アプリクーションの開発

この章では、高可用性(HA)アプリケーションの設計に必要な、高度なWebLogic JMSのパブリッシュとサブスクライブ(pub/sub)の概念および共通分散トピック(UDT)の機能について説明します。

拡張高可用性の概念の概要

次の項では、WebLogic Serverの高可用性の機能および概念について説明します。


注意:

すべてのトポロジ変更の可能性を明示的に処理するよりは、WebLogic Server MDBまたはOracle SOA JMSアダプタを活用するアプリケーションを設計することをお薦めします。

WebLogicメッセージングの高可用性機能

OracleのWebLogicメッセージングでは、次の機能を使用して高可用性(HA)および拡張性を提供します。

  • 第9章「分散宛先の使用」

  • 『Oracle WebLogic Server JMSの構成と管理』のJMS関連サービスの移行に関する項

  • 『Oracle WebLogic Serverクラスタの使用』のサーバー全体の移行に関する項

分散宛先によって、JMSグループの物理的な宛先は、クライアントへの単一の論理的な宛先にアクセスできるようになります。通常、分散宛先を使用するアプリケーションでは、WebLogic JMSがクラスタ内の分散宛先のメンバー宛先間のロード・バランシングおよびフェイルオーバーを提供するため、可用性と拡張性がより高くなっています。自動サービス移行(ASM)およびサーバー全体移行(WSM)によって、サービス・セット(JMSサーバーと宛先を含む)または新規ロケーションにおけるWebLogic Server全体のインスタンスのいずれかを再起動できるようになります。これらの移行機能は、分散宛先の各メンバーに対する高可用性を提供します。

このようなテクノロジの本質は、次に示すようにJMSシステムのトポロジがクライアント・アプリケーションにとって不明である可能性を示します。

  • 分散宛先のスケーリングに従ったクラスタのスケーリングは、アプリケーションによって定義されたコンシューマ数を超える場合があります。

  • トポロジは、サーバーまたはサービスの障害発生時に動的に変更される可能性があります。

通常、トポロジの変更は、ローカル上またはリモートWebLogic Serverインスタンス上のいずれかでMDBを使用して透過的に処理されます。ただし、他のクライアント・タイプを使用するとき、特にJMS宛先をホストしているサーバーに対してアプリケーションがリモートである場合、このようなトポロジの変更はアプリケーションによって明示的に処理される必要があります。

レプリケートされた分散トピック使用時のアプリケーション設計の制限

WebLogic Server 10.3.4.0以前の共通分散トピックを実装するアプリケーションでは、次の制限によって制約を受けていました。

  • メッセージは常に分散トピック全体にわたって転送および重複されます。つまり、クラスタ化アプリケーションが各メッセージのコピーを正確に1つ取得するような保証処理および/またはパラレル処理のいずれかには、重要な構成、コーディング、およびメッセージ・ホップを追加する必要があることを示します。

  • 1回に1つのみのコンシューマが、XA以外のMDBに限定される場合(サブスクリプションの全処理がスレッド・プールを持つ同一のサーバー上で行われる必要がある場合)を除き、所定のサブスクリプションでメッセージを処理できます。これによって大半の顧客は、単一スレッド式処理ではなく、単一サブスクリプションのトピック・メッセージをラウンドロビン方式で分散処理またはパラレル処理するように意図するアプリケーション・アーキテクチャを設計しなくても済みます。

  • MDBは、同一クラスタに配置される分散トピック上で恒久サブスクリプションのみを直接サポートします。

  • MDB以外のアプリケーションの場合、分散トピック用に作成された永続サブスクライバは、分散トピック(DT)メンバー上でのみ作成でき、永続サブスクリプションはそのメンバー上でのみ存在できます。サブスクリプションをホストしているメンバーがダウンする場合、どのサブスクライバに対してもサブスクリプションが利用できなくなります(そのため、定義ごとに「可用性が高い」状態にはなりません)。

  • サブスクライバを分散トピック・メンバーに確保すると、分散キューに対して実行される調整と同様に、トポロジの変更に対する自動調整が阻害されます。

拡張トピック機能

WebLogic Server 10.3.4.0以降では、パーティション化された分散トピックは、サブスクリプションを共有する機能および複数接続に同一クライアントIDの使用を許可する機能が組み合され、パラレル処理と分散キューに似たHA機能を備えた次のアプリケーション設計パターンを提供しています。

  • インスタンスごとに1つのコピー: アプリケーションの各インスタンスは、トピックにパブリッシュされる各メッセージのコピーを1つ取得します。

  • アプリケーションごとに1つのコピー: 各アプリケーションが全体として(つまり、アプリケーションのすべてのインスタンスを合せて)、トピックにパブリッシュされる各メッセージのコピーを1つ取得します。つまり、各インスタンスはトピックに送信されるメッセージのサブセットのみを取得します。


注意:

WebLogic ServerのMDBを活用するアプリケーションを設計することをお薦めします。高可用性と拡張性の向上にメッセージドリブンBeanを使用するアプリケーションを設計・実装する方法の詳細は、『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』のJMSトピックを使用したMDBの構成およびデプロイに関する項を参照してください。

高可用性用拡張メッセージング機能

アプリケーションが「インスタンスごとに1つのコピー」および「アプリケーションごとに1つのコピー」の設計パターンを達成する仕組みを理解するためには、次の新しく変更された機能を理解する必要があります。

共有サブスクリプションおよびクライアントIDポリシー

WebLogic Server 10.3.4.0以前では、恒久/非恒久に関係なく1つのサブスクリプションは、所定の時間に単一のサブスクライバ・インスタンスによってのみアクセスできました。各サブスクライバは、サブスクリプションの確立後にトピックに送信されるすべてのメッセージを受信し、各サブスクリプションのメッセージは1つのコンシューマによって連続して処理されます。

今回のWebLogic Serverリリースでは、複数のサブスクライバは(恒久/非恒久に関係なく)1つのサブスクリプションを共有できます。メッセージは、同一のサブスクリプションを共有する複数のコンシューマ間に配信され、並列に処理されます。サブスクリプションの共有は、同一の宛先インスタンス上またはDTの同一メンバー・インスタンス上でのみ行われます。『Oracle WebLogic Server JMSの構成と管理』の共有サブスクリプションの構成に関する項を参照してください。

サブスクリプションを共有するため、恒久/非恒久に関係なくサブスクリプションは、接続ファクトリまたは接続に設定されたクライアントIDを持つ必要があります。WebLogic Server 10.3.4.0以前では、クライアントIDは所定の時間に1つの接続によって排他的に使用されていました。今回のWebLogic Serverのリリースでは、この制限が緩和されており、クライアントIDの制限使用または無制限使用のための新しいクライアントIDポリシーが採用されています。デフォルトのポリシーである「制限」では、1つのクライアントIDのみが1つの接続によって使用されます。「制限なし」ポリシーでは、複数の接続が同一のクライアントIDを使用できるようになります。詳細は、「恒久サブスクリプションの共有が機能する仕組み」を参照してください。

サブスクリプション・キーとは

サブスクリプション・キーは、サブスクリプションを一意に識別するために使用されます。非恒久サブスクリプションの場合、キーはクライアントIDおよびクライアントIDポリシーから構成されます。恒久サブスクリプションの場合、キーはクライアントID、クライアントIDポリシー、およびサブスクリプション名から構成されます。

共有サブスクリプションの構成

共有サブスクリプションを構成するには、接続ファクトリ上にサブスクリプション共有ポリシー属性を構成する必要があります。サブスクリプション共有ポリシーを「共有可能」に設定すると、接続ファクトリを使用して作成されたサブスクライバは、サブスクライバが同一の接続ファクトリまたは異なる接続ファクトリのどちらを使用して作成されたかに関係なく、サブスクリプションを他のサブスクライバと共有できるようになります。コンシューマは、同一のクライアントIDおよびクライアントIDポリシーを持つ場合にかぎり、非恒久サブスクリプションを共有できます。コンシューマは、同一のクライアントID、クライアントIDポリシー、およびサブスクリプション名を持つ場合にかぎり、恒久サブスクリプションを共有できます。次を参照してください。

非恒久サブスクリプションの共有が機能する仕組み

複数の非恒久サブスクライバ間でサブスクリプションを共有するため、サブスクライバは、サブスクリプションを識別するために使用されるクライアントIDを持つ必要があります。サブスクリプションの共有を意図するすべてのサブスクライバは、接続上で同一のサブスクリプション・キー(ClientIDおよびClientIDPolicy)を持つ必要があります。サブスクリプション共有ポリシーがSHARABLEに設定されていても、ClientIDConnection上に設定されていない場合、そのサブスクリプションは共有サブスクリプションではありません。

サブスクリプション・キーを使用して作成される最初のサブスクライバが、サブスクリプションを作成します。同一のサブスクリプション・キーを使用して連続作成されたすべてのサブスクライバは、すべてのサブスクリプションの詳細(セレクタ、noLocalオプション、および物理的な宛先など)が一致する場合、最初のサブスクライバによって作成されたサブスクリプションを共有します。例:

  • サブスクリプションがセレクタとnoLocalオプションを使用して作成される場合、同一のサブスクリプション・キーを使用していてもセレクタ、noLocal、または物理的な宛先が異なるサブスクライバの作成呼出しは、異なるサブスクリプションとして処理されます。

  • EXCLUSIVEサブスクライバによってClientIDが使用される場合、同一のClientID、セレクタ、およびnoLocalオプションを使用する現在または後続のサブスクライバは、異なるサブスクリプションとして処理されます。


    注意:

    サブスクライバが同一の接続インスタンスまたはUNRESTRICTEDのクライアントIDポリシーを使用する接続を使用して作成される場合にかぎり、同一のClientIDを持つことが可能です。

非恒久サブスクリプション用の共有サブスクリプション・ポリシーが決定される仕組み

特定の非恒久サブスクリプション用のサブスクリプション共有ポリシーは、サブスクリプション上の最初のアクティブ・サブスクライバによって動的に決定され、サブスクリプションの存続期間中は変更されません。サブスクリプション用のサブスクリプション共有ポリシーを変更しようと試行しても、javax.jms.JMSExceptionを拡張するInvalidSubscriptionSharingExceptionがスローされます。例:

  • 非恒久サブスクリプションが宛先上にEXCLUSIVEサブスクライバを持ち、サブスクリプションがEXCLUSIVEの場合、同一の宛先上のサブスクリプションを使用して追加サブスクライバを作成しようと試行しても、未作成のサブスクライバがEXCLUSIVEまたはSHARABLEかどうかに関係なく、InvalidSubscriptionSharingExceptionがスローされて失敗します。

  • サブスクリプションがSHARABLEポリシーを使用するアクティブ・サブスクライバを持ち、サブスクリプションがSHARABLEの場合、サブスクリプション上で新しいEXCLUSIVEサブスクライバを作成しようと試行しても、InvalidSubscriptionSharingExceptionがスローされて失敗します。

非恒久サブスクリプションが終了する仕組み

同一のサブスクリプションを共有するすべてのサブスクライバがクローズされると、該当するサブスクリプションはクリーンアップされます。具体的には、共有サブスクリプション上の最後のサブスクライバ・コンシューマがclose()を呼び出すと、サブスクリプションおよび関連付けられたすべてのJMSリソースがクリーンアップされます。

共有サブスクリプションまたは排他的サブスクリプションかどうかに関係なく、非恒久サブスクリプションを示すランタイムMBeanはありません。適切なJMSConsumerRuntimeMBeanを使用して個別のサブスクライバを監視することは可能です。

恒久サブスクリプションの共有が機能する仕組み

以前のリリースでは、サブスクリプション・キー(<ClientID, SubscriptionName>)はクラスタ内のサブスクリプションを一意で識別していました。クラスタ内では、サブスクリプションは、クラスタ内にある単一の宛先インスタンスまたはDTの単一メンバー上にのみ存在できました。このWebLogic Serverリリースでは、サブスクリプション・キーは<ClientID, ClientIDPolicy, SubscriptionName>になります。同一のサブスクリプション・キーを使用するすべての永続サブスクライバは、通常トピックをサブスクライブする場合、または分散トピックの同一メンバーをサブスクライブする場合に、同一のサブスクリプションを共有します。同一のサブスクリプション・キーを使用する複数のサブスクリプションは、複数の分散宛先メンバーの宛先上に存在できます。

特定のサブスクリプション・キーを使用して作成される最初のサブスクライバが、サブスクリプションを作成します。同一のサブスクリプション・キーを使用して連続作成されたすべてのサブスクライバは、すべてのサブスクリプションの詳細(セレクタ、noLocalオプション、および物理的な宛先など)が一致し、かつ同一の物理的な宛先上にある場合、最初のサブスクライバによって作成されたサブスクリプションを共有します。

サブスクリプションがセレクタとnoLocalオプションを使用して作成される場合、異なるセレクタとnoLocalオプションと同一のサブスクリプション・キーを使用して同一の物理的な宛先上で作成されたサブスクライバは、次のとおりになります。

  • この既存サブスクリプションを使用するアクティブ・サブスクライバが存在しない場合、既存の恒久サブスクリプションを置換し、恒久サブスクリプション用に保存されるすべての保留メッセージをクリーンアップします。

  • 異なるセレクタまたはnoLocalオプションと同一のサブスクリプション・キーを使用するアクティブ・サブスクライバが存在する場合、InvalidSubscriptionSharingExceptionをスローします。

恒久サブスクリプション用の共有サブスクリプション・ポリシーが決定される仕組み

特定の恒久サブスクリプション用サブスクリプション共有ポリシーは、サブスクリプション上の最初のアクティブ・サブスクライバによって動的に決定され、すべての現在のサブスクライバが終了し、新規サブスクライバが異なるポリシーに接続しないかぎり、変更されません。すでにアクティブ・サブスクライバを持つサブスクリプションのポリシーを変更しようと試行しても、InvalidSubscriptionSharingExceptionがスローされます。例:

  • 恒久サブスクリプションがEXCLUSIVEサブスクライバを持ち、サブスクリプション共有ポリシーがEXCLUSIVEの場合、サブスクリプション上で追加サブスクライバを作成しようと試行しても、未作成のサブスクライバがEXCLUSIVEまたはSHARABLEかどうかに関係なく、InvalidSubscriptionSharingExceptionがスローされます。

  • 恒久サブスクリプションがSHARABLEポリシーを使用するアクティブ・サブスクライバを持ち、サブスクリプション共有ポリシーがSHARABLEの場合、サブスクリプション上で新しいEXCLUSIVEサブスクライバを作成しようと試行しても、InvalidSubscriptionSharingExceptionがスローされます。既存の恒久サブスクリプション上でサブスクリプション共有ポリシーを変更しても、サブスクリプション上にすでに存在するメッセージは一切削除されません。


注意:

既存の恒久サブスクリプション上でサブスクリプション共有ポリシーを変更しても、サブスクリプション上にすでに存在するメッセージは一切削除されません。

恒久サブスクリプションのサブスクライブを解除する方法

サブスクリプションのサブスクライブを解除する前に、サブスクリプション用のクライアントIDポリシーを考慮する必要があります。

  • RESTRICTEDの値を持つクライアントIDポリシーを使用するアプリケーションは、標準のSession.unsubscribe(String name) APIを使用して恒久サブスクリプションのサブスクライブを解除します。


注意:

WebLogic Server 10.3.4.0以前では、すべてのクライアントIDはデフォルトでRESTRICTEDになっています。所定のクライアントIDは、WLS JMSクラスタで所定の時間に1つの接続によってのみ使用できました。

  • UNRESTRICTEDの値を持つクライアントIDポリシーを使用するアプリケーションは、サブスクリプション名およびトピックまたはDTメンバー・オブジェクトを提供することによって、WLSession.unsubscribe(String name, Topic topic)拡張を使用して、恒久サブスクリプションのサブスクライブを解除します。

恒久サブスクライバのサブスクライブ解除時に考慮する点

次の項では、サブスクライブを解除する方法または例外をスローするシナリオを避ける方法について説明します。

  • サブスクリプション上にアクティブ・コンシューマが存在する場合、unsubscribe()への呼出しはJMSExceptionをスローします。

  • サブスクリプション上にアクティブ・コンシューマが存在しない場合、unsubscribe()への呼出しは、サブスクリプション・キー<ClientID, ClientIDPolicy, SubscriptionName>によって識別される一致する恒久サブスクリプションを削除します。

  • 恒久サブスクリプションのunsubscribe()は、スタンドアロン・トピックごとまたはDTメンバーごとに実行されます。

  • RESTRICTEDのクライアントIDを持つ接続を使用して作成されたサブスクリプションは、同一のRESTRICTEDのクライアントIDを使用する接続からのみクリーンアップされます。

  • UNRESTRICTEDのクライアントIDを持つ接続を使用して作成されたサブスクリプションは、同一のUNRESTRICTEDのクライアントIDを使用する接続からのみクリーンアップされます。

  • WebLogic JMSが、unsubscribe呼出しと同一のクライアントIDとClientIDPolicyを使用して作成されたトピック上で一致するサブスクリプションを検出しない場合、InvalidDestinationExceptionがスローされます。

  • UNRESTRICTEDのクライアントIDを持つunsubscribe呼出しが、DTを指定する場合またはいかなるトピックも指定しない場合、InvalidDestinationExceptionがスローされます。

  • .NetおよびCのAPIメッセージング・アプリケーションは、WebLogic Server 10.3.4.0以降でデプロイされる接続ファクトリ上でクライアントIDポリシーおよびサブスクリプション共有ポリシーを使用することによって、サブスクリプションを共有できますが、アンサブスクライブAPI拡張は、制限なしのクライアントIDを使用するサブスクリプションには使用できません。これを解決するには、恒久サブスクリプションの管理に関する項で説明されているように、管理用の手段を使用します。

恒久サブスクリプションの管理

クラスタ全体に分散したサブスクリプションが存在する場合、削除する必要があってもまだ削除されてはいないサブスクリプションが存在する可能性があります。このようなサブスクリプションは「中止された」サブスクリプションと呼ばれることがあり、メッセージを処理するサブスクライバが存在しない場合でも、メッセージを蓄積し続ける可能性があります。蓄積しているメッセージの有効期限が切れていない場合、それらのメッセージによって結果的にトピックがリソース割当て例外(割当て例外)のスローを開始する可能性があったり、割当てが構成されていない場合には、サーバーがメモリーを使い果たしたりする可能性があります。

たとえば、アクティブ・サブスクライバがサブスクリプション上に存在する場合、unsubscribe呼出しは失敗し、unsubscribe呼出しは非アクティブ(シャットダウン)メンバー上のサブスクリプションに到達しません。これが発生すると、サブスクリプションはメンバー上に残され、管理者によって手動で削除されるか、または呼出しが繰り返されるまで呼出しは失敗します。

このような状況の処理に役立てるため、管理者には恒久サブスクリプションの監視および管理用の次のオプションがあります。

  • 各恒久サブスクリプションには1つのJMSDurableSubscriptionRuntimeMBeanインスタンスがあります。管理者は、管理コンソールまたはWLSTコマンドライン/スクリプトを使用してトピックまたはUDT上で監視できます。Oracle WebLogic Server管理コンソール・ヘルプJMSサーバーの監視に関する項を参照してください。

  • 中止または孤立した恒久サブスクリプションを検出するには、管理者はJMSDurableSubscriberRuntimeMBean上でLastMessagesReceivedTimeをチェックします。getLastMessagesReceivedTime()メソッドは、サブスクライバがサブスクリプションからメッセージを取得した最後の時間を返します。この情報に基づき、同一MBean上のMessagesPendingCountまたはBytesPendingCountなどの属性と共に、管理者は特定の恒久サブスクリプションのステータスに関する明確なビジョンを構築し、リソースのクリーンアップなどの適切な対応を取ることが可能です。

JMSDurableSubscriberRuntimeMbeanのネーミング規則

恒久サブスクリプションがサブスクリプション・キー<MyClientID, MySubscriptionName>を使用して作成される場合、関連付けられるJMSDurableSubscriberRuntimeMBeanの名前は次のいずれかになります。

  • クライアントIDポリシーがRESTRICTEDの場合は、MyClientID_MySubscriptionName。ここで、MyClientIDはこのサブスクリプションのクライアントIDであり、MySubscriptionNameはサブスクリプション名です。

  • クライアントIDポリシーがUNRESTRICTEDの場合は、MyClientID_MySubscriptionName@topicName@JMSServerName。ここで、MyClientIDはこのサブスクリプションのクライアントID、MySubscriptionNameはサブスクリプション名、topicNameはスタンドアロン・トピックまたはUDTメンバーの名前、JMSServerNameはトピックまたはメンバーがデプロイされる場所のJMSServerの名前です。

トピック使用時の設計方針

次の項では、高可用性アプリケーションの開発に使用されるトピック・ベースの設計方針について説明します。

「インスタンスごとに1つのコピー」設計方針

「インスタンスごとに1つのコピー」は従来の設計パターンで、10.3.4.0以前のWebLogic Serverリリースと下位互換性があります。「インスタンスごとに1つのコピー」には、次の特徴があります。

  • アプリケーションの各インスタンスは、トピックにパブリッシュされる各メッセージのコピーを1つ取得します。

「アプリケーションごとに1つのコピー」設計方針

「アプリケーションごとに1つのコピー」は、WebLogic Server 10.3.4.0以降のリリースで使用できる設計パターンです。「アプリケーションごとに1つのコピー」には、次の特徴があります。

  • 通常このパターンを実装する最良の方法は、クラスタ全体のポリシーとサブスクリプションを自動的に設定するMDBを利用することです。「分散トピック用のベスト・プラクティス」を参照してください。

  • 各アプリケーションが全体として(つまり、アプリケーションのすべてのインスタンスを合せて)、DTにパブリッシュされる各メッセージのコピーを1つ取得します。つまり、各インスタンスはDTに送信されるメッセージのサブセットのみを取得します。

  • クライアントIDポリシーはUNRESTRICTEDです。

  • サブスクリプション共有ポリシーはSHARABLEです。

  • サブスクライバが恒久の場合は、同一のサブスクリプションを使用します。

  • すべてのコンシューマは同一のトピック・インスタンス(またはDTメンバー)をサブスクライブします。

分散トピック用のベスト・プラクティス

分散トピックを使用して新しいアプリケーションを設計するときには、次を実行することをお薦めします。