



Pamela Fong、Advisory Software Engineer、IBM
Jeff Brent、Advisory Software Engineer、IBM
2007年5月16日, 原文はこちら(US)
この記事では、WebSphere Process ServerとWebSphere Enterprise Service Busにおけるエラー条件の捕捉方法と処理方法、問題検出、再試行動作、例外の伝搬、および報告について説明します。この記事では、読者がService Component Architecture(SCA)プログラミング・モデルを理解しており、WebSphere Process ServerおよびWebSphere Enterprise Service Busを使用したアプリケーションの開発経験を有していることを前提としています。
実稼働環境でエンタープライズ・アプリケーションを実行する際には、障害が発生した場合のシステムの動作を理解しておくことが重要です。この記事では、IBM® WebSphere® Process Server(以降 Process Serverと記述)およびIBM WebSphere Enterprise Service Bus(以降 Enterprise Service Busと記述)における基本的な例外のカテゴリーについて説明します。この記事では以下の内容を扱います。
- 問題発生時のシステムの動作
- 問題のログ記録先
- さまざまな問題からの回復方法
エラー処理について解説する前に、Service Component Architecture(SCA)の基礎(インターフェースのタイプ、呼び出しパターン、例外カテゴリーなど)を理解しておく必要があります。
インターフェースのタイプ
SCAでは次の2種類のインターフェースがサポートされています。
- JTtype
- Java インターフェースを使用して定義されたインターフェースのタイプ。
- WType
- WSDLポート・タイプを使用して定義されたインターフェースのタイプ。
このタイプは、インターフェースと参照を記述するときに使用されます。クライアント・プログラマーは、参照を使用するときには、このタイプに基づいて参照を対話型で操作する必要があります。呼び出しまたはサービス・プロバイダーのターゲットが、参照方法とは異なるタイプ(JまたはW)を使用することがあります。SCAではこの差異が解決されます。
ビジネス例外はJTypeおよびWTypeの両方のインターフェースで宣言できます。JTypeインターフェースではthrows節が使用されますが、WTypeインターフェースではフォールトが宣言されます。
呼び出しパターン
SCAには次の2つの呼び出しスタイルがあります。
- 同期
- ターゲットに対してブロック化要求が出され、応答が同じスレッドで戻されます。
- 非同期
- 非ブロック化要求が出され、応答が別のスレッドで戻されます。
非同期スタイルでは、SCA非同期プログラミング・モデルに次の3種類の非同期呼び出しパターンがあります。
- 一方向
- 応答不要送信呼び出しパターンとして使用されます。クライアントが、参照を介して示された操作を呼び出すと、制御が直ちに戻されます。応答、例外、フォールトは戻されません。
- 据え置き応答
- 要求/応答非同期呼び出しパターンです。クライアントが要求を出し、クライアントにとって適切な時期に応答を要求します。
- コールバック
- 要求/応答非同期呼び出しパターンです。クライアントがコールバック・インターフェースを実装します。このインターフェースは、応答できる状態になった時点でSCAランタイムにより呼び出されます。
発生する可能性のあるエラー条件を理解する上で、これらの呼び出しパターンの相違を理解しておくことが非常に重要です。
例外の分類
Process ServerとEnterprise Service Busでは、SCAプログラミング・モデルを使用してアプリケーションが構築されています。SCAプログラミング・モデルでは、ビジネス例外(ServiceBusinessException)とシステム例外(ServiceRuntimeException)という2種類のエラー条件が定義されています。
ビジネス例外
ビジネス例外とは、ビジネス・メソッドの関数シグニチャー(WSDLフォールトまたはJava throws)で宣言されているチェック例外です。ビジネス例外は、アプリケーションまたはサービスで予期されるエラー条件を識別するために使用されます。ビジネス例外の例としては、株価情報サービスのInvalidSymbolExceptionなどがあります。ビジネス例外はServiceBusinessExceptionによりラップされ、クライアントに戻されます。
システム例外
システム例外は実行時例外とも呼ばれます。システム例外は、メソッド・シグニチャーで宣言されません。一般に、システム例外はアプリケーションで予期されないエラー条件(JavaコンポーネントのNullPointerExceptionなど)を表します。システム例外はServiceRuntimeExceptionによりラップされ、クライアントに戻されます。クライアントは原因判別のためにServiceRuntimeExceptionを検査できます。
SCAプログラミング・モデルでは、いくつかの組み込みシステム例外が次のようにServiceRuntimeExceptionのサブクラスとして定義されています。
- ServiceExpirationRuntimeException
- 非同期SCAメッセージの有効期限が切れていることを示します。有効期限を設定するには、サービス参照にRequestExpirationまたはResponseExpiration修飾子を使用します。
- ServiceTimeoutRuntimeException
- 非同期要求に対する応答が指定の時間制限内に受け取られなかったことを示します。この時間制限は、据え置き応答非同期通信パターンを使用しているときに、invokeResponse() 呼び出しでプログラマチックに設定されます。
- ServiceUnavailableException
- インポートを介して外部サービスを呼び出し中に例外がスローされたことを示します。
- ServiceUnwiredReferenceRuntimeException
- コンポーネントのサービス参照が正しくワイヤリングされていないことを示します。
サービス・コンポーネントを同期的に呼び出すと、クライアントとサービス・プロバイダーの両方が同一スレッドで実行されます。ターゲットはクライアントに対し、応答メッセージまたは例外を戻すか、または何も戻しません(一方向操作の場合)。結果が例外である場合、これはビジネス例外またはシステム例外のいずれかです。この場合、クライアントはアプリケーション・コードまたは何らかのシステム・コードです。
図1 呼び出しのアセンブリー・ダイアグラム

JTypeインターフェースで宣言されたJavaコンポーネントを呼び出すクライアントの例を次に示します。JTypeインターフェースでは1つのメソッドが次のように宣言されています。
リスト1 株価情報サービスのインターフェース
public interface StockQuote {
float getQuote(String symbol) throws InvalidSymbolException;
}
|
|
クライアント・コードは次のようになります。
リスト2 株価情報サービスの同期クライアント株価取得処理
try {
float quote = StockQuoteService.getQuote(String symbol);
} catch (InvalidSymbolException s) {
System.out.println(This is business exception declared in the Java interface.);
} catch (ServiceRuntimeException e) {
System.out.println(Unchecked system exception detected);
}
|
|
上記のシナリオの1番目の例外InvalidSymbolExceptionは、要求がサービス・プロバイダーに到達したが、サービス・プロバイダーがクライアントの入力を認識しないことを示します。サービス・プロバイダーは、指定されているシンボルが無効であることを示すビジネス例外をスローします。このビジネス例外は、メソッド・シグニチャーで宣言されている唯一の例外です。
InvalidSymbolExceptionなどのJType例外は、JType参照を使用するクライアントでのみキャッチされます。WType参照を使用するクライアント・プログラミングについては、この記事の終わりに示すリンクからWSDLサンプルをダウンロードできます。
クライアントは、宣言されているビジネス例外の他に、システム例外を受け取ることがあります。例えば、株式取引システムで問題が発生すると、何らかのチェックなし例外が原因でサービスが株価情報を取得できないことがあります。このような例外がサービスからスローされると、ServiceRuntimeExceptionがクライアントに戻されます。この場合、クライアントで根本的な原因を判別することがあります。この情報の取得方法を示すコード・スニペットを、以下に示します。
リスト3 株価情報サービスの同期クライアント株価取得処理 II
try {
float quote = StockQuoteService.getQuote(String symbol);
} catch (ServiceRuntimeException e) {
Throwable t = e.getCause();
if (t instanceof RemoteException) {
system.out.println(System ran into RemoteException. Details as follows: + e.toString());
}
|
|
前述したように、SCAプログラミング・モデルでは3種類の非同期呼び出しパターンがサポートされています。サービス・コンポーネントが非同期に呼び出されると、クライアントとサービス・プロバイダーはそれぞれ別のスレッドで実行されます。このため、いずれかのスレッドでエラー条件が発生する可能性があります。クライアントによる呼び出し中にシステム例外が発生するか、またはサービス・プロバイダーによる要求の処理中にビジネス例外またはシステム例外が発生することがあります。
Process ServerまたはEnterprise Service Busでは、前述のインターフェースに対する非同期バージョンが常に存在します。
リスト4 株価情報サービスの非同期インターフェース
public interface StockQuoteAsync {
public Ticket getQuoteAsync(String arg0);
public Ticket getQuoteAsyncWithCallback(String arg0);
public float getQuoteResponse(Ticket ticket, long timeout) throws InvalidSymbolException;
}
|
|
据え置き応答の呼び出しパターンを使用する呼び出しのクライアント・コードを以下に示します。
リスト5 非同期クライアント
Ticket ticket = stockQuote.getQuoteAsync(symbol);
try {
quote = stockQuote.getQuoteResponse(ticket, Service.WAIT);
} catch (InvalidSymbolException s) {
System.out.println(This is business exception declared in the interface.);
} catch (ServiceRuntimeException e) {
System.out.println(Unchecked system exception detected);
}
|
|
同期呼び出しの場合と同様に、InvalidSymbolExceptionは、要求がサービス・プロバイダーに到達したが、サービス・プロバイダーから、シンボルが無効であることを示すビジネス例外がスローされたことを示します。このビジネス例外は、インターフェースで宣言されている唯一の例外です。
ここでも、InvalidSymbolExceptionなどのJType例外は、JType参照を使用するクライアントでのみキャッチされます。WType参照を使用するクライアント・プログラミングについては、この記事の終わりに示すリンクからWSDLサンプルをダウンロードできます。
宣言されているビジネス例外の他に、クライアントはシステム例外(メッセージ送信中に発生した接続エラーなど)も受け取ります。クライアントが、サービス・スレッド(非同期呼び出しのサービス側のスレッド)で発生したシステム例外を受け取ることはありません。SCA非同期プログラミング・モデルでは、ターゲット・コンポーネントで発生した実行時例外はソース・コンポーネントに戻されません。次にこれらのエラーのルーティングについて説明します。
非同期例外処理での例外的なケース
SCA非同期プログラミング・モデル・ルールの例外の1つに、ターゲット・コンポーネントで発生した実行時例外はソース・コンポーネントに戻されないことがあります。ソース・コンポーネントがビジネス・プロセス・コンポーネントまたはスタッフ・プロセス・コンポーネントの場合、ターゲットのサービス・コンポーネントで発生したシステム例外は呼び出し側に戻されます。この機能により、ビジネス・プロセス設計担当者はシステム例外をモデル化してキャッチでき、BPELクライアントからシステム例外が戻される場合にはエラー・ロジックを実行できます。
SCAでは、コンポーネント間のメッセージ移送にService Integration Bus(SIBus)が使用されます。これらの宛先は、Process ServerまたはEnterprise Service Busサーバーへのモジュールのインストール時に、インストール・タスクにより作成されます。呼び出し中に、ターゲットのサービス・コンポーネントからシステム例外が戻されると、モジュール宛先のしきい値に達するまで、SIBusがメッセージの再送信を自動的に実行します。このセクションでは、再試行設定を表示および編集する方法と、この設定を無視する特殊な状況について説明します。
再試行の例
StockServiceModuleモジュールに、ValidatorおよびCalculatorという2つのコンポーネントが組み込まれているとします。Validatorは、Calculatorに対して非同期呼び出しを実行します。非同期呼び出しによりメッセージが生成され、このメッセージがSIBusに格納されます。このメッセージは後でSCA呼び出しフレームワークにより取り出され、これによりCalculatorサービスが呼び出されます。この例では、ソフトウェアの問題が原因で、入力パラメーターがNULLであるためにCalculatorがNullPointerExceptionをスローします。
図2 StockServiceModule

CalculatorからNullPointerExceptionが戻されると、SCAは現行トランザクションをロールバックします。このロールバックにより、呼び出しメッセージがSIBusに戻され、ターゲット・サービスが属するモジュールを表す宛先に戻されます。この例ではモジュール名がStockServiceModuleであるため、メッセージがロールバックされる宛先の名前はsca/StockServiceModuleです。デフォルトでは、SIBusはCalculatorサービスへの同一メッセージの配信を最大5回まで試行します。ユーザーがこの再試行回数を設定できます。
再試行設定の変更
前述したように、SIBusにはSCAメッセージ・ドリブンBean(MDB)を使用した再試行メカニズムが組み込まれています。再試行動作を構成するには、モジュール宛先の「Maximum Failed Deliveries」属性を変更します。StockServiceModuleというモジュールがあり、SCAにより非同期通信に対応する目的で作成されたSIBus宛先が複数あるとします。これらの宛先の1つに、sca/StockServiceModuleがあります。非同期サービス呼び出しが失敗した場合の再試行回数を変更するには、Maximum failed deliveriesの値を次のように変更します。
- ターゲット・コンポーネントが含まれているモジュールを確認します。この例ではStockServiceModuleです。
- 管理コンソールでSCAシステム・バスを見つけます。一般に、このSCAシステム・バスの名前はSCA.SYSTEM.$cellName.Busという命名規則に従っています。例えば、SCA.SYSTEM.widcell.Busは、単体テスト環境のデフォルト・バスです。
- このバスに関連付けられている宛先のリストへ移動します。
- sca/$moduleNameという形式の名前の宛先を見つけます。この例では、sca/StockServiceModuleという名前を探します。
- モジュール宛先の属性画面から、「Maximum failed deliveries」フィールドを見つけ、このフィールドに2以上の任意の整数値を設定します。Enterprise Service BusとProcess Serverでは値0と1は無効です。
図3 最大配信失敗回数(maximum failed deliveries)の構成
再試行構成が機能しない状況
Calculator実装内部にprintステートメントを挿入すると、再配信回数が構成されている値と一致しないことがあります。この状況の原因となる2つの機能を以下に説明します。
JMS エクスポート
要求にJMSエクスポートとコンポーネントの間のメッセージ転送が関与する場合は、再試行回数は常に構成値よりも1回多くなります。次の図に、宛先を使用してJMSエクスポートからコンポーネントへメッセージをルーティングする方法を示します。
図4 JMS エクスポート

- モジュールの外部宛先からメッセージがピックアップされ、ターゲット・コンポーネント(この場合はPojo1)に配信されます。
- Pojo1からシステム例外がスローされます。
- メッセージが、ピックアップされた場所へロールバックされます。この場合、ロールバック先はSCAモジュール宛先 sca/Module1です。
- メッセージが宛先にロールバックされた後で、基礎となるシステムにより、宛先の最大配信失敗回数設定に基づいてメッセージの再配信が実行されます。
図5 JMSエクスポート II

- メッセージがJMSExport1に再配信されます。
- JMSExport1バインディングにより、再配信されたメッセージが検出され、このメッセージが sca/Module1/component/Pojo1 宛先に格納されます。
- メッセージが sca/Module1に転送され、Pojo1に配信されます。
- Pojo1からシステム例外がスローされます。
- メッセージが sca/Module1にロールバックされます。
- sca/Module1から Pojo1へのメッセージ再配信がさらに4回実行されます。
この結果、Pojo1は6回呼び出されることになります。これは、sca/Module1の「Maximum failed deliveries」の値に1を加算した回数です。
ビジネス・プロセス・コンポーネントがターゲット・サービス・コンポーネントを呼び出すと、ターゲット・スレッドにより検出される実行時例外はすべて、プロセス・コンポーネントに戻されます。実行時例外の処理イベントの順序を次に示します。
図6 ビジネス・プロセス・コンポーネント
- プロセス・コンポーネントは、発信宛先にメッセージを配信する前に、すべてのシステム例外を処理のために呼び出し側に戻すことをメッセージに書き込みます。
- メッセージが宛先sca/Module2/component/Pojo2に格納されます。
- メッセージがsca/Module2からピックアップされ、Pojo2に配信されます。
- Pojo2からシステム例外がスローされます。
- メッセージがsca/Module2にロールバックされます。
- sca/Module2から、「Maximum failed deliveries」のデフォルト設定値5(1回の配信と4回の再配信)に基づき、メッセージの再配信が4回実行されます。
- 4回目の再試行時(5回目の配信時)に、メッセージはSCAにより中断され、失敗の原因とともに呼び出し側に戻されます。これにより、メッセージの最終再配信中にPojo2が呼び出されることはありません。
この結果、Pojo2は4回(sca/Module2の「Maximum failed deliveries」値よりも1少ない回数)呼び出されます。
Enterprise Service Busでの配信失敗メッセージのルーティング・ルール
非同期呼び出し中にターゲット・コンポーネントでシステム例外が発生すると、メッセージは着信宛先にロールバックされ、再配信されます。Enterprise Service Busでは、再試行制限に達すると、モジュール宛先の「Exception destination」フィールドの指定に従ってメッセージが例外宛先にルーティングされます。この宛先は、SCAシステム・バスのシステム例外宛先で設定されています。デフォルトでは、サーバーごとにシステム例外宛先が設定されます。
ノード名 WPSNode、サーバー名 server1、およびバス名 SCA.SYSTEM.WBIDev-BGMNode01Cell.Busという環境では、システム例外宛先は_SYSTEM.Exception.Destination.WPSNode.server1-SCA.SYSTEM.WBIDev-BGMNode01Cell.Busになります。
時間の経過に伴い、メッセージがこの例外宛先に累積します。管理コンソールから、キューに格納されているメッセージの数を参照できます。あるいは、例外処理のためにキューからメッセージを読み取るJMSクライアント・アプリケーションを作成できます。
Process Serverでの配信失敗メッセージのルーティング・ルール
Process Server製品では、例外宛先がProcess Server Recovery例外宛先に設定されています。この例外宛先は、次に説明する命名規則に従っています。ノード名がWPSNode、サーバー名がserver1のサーバーの場合、Recovery例外宛先はWBI.FailedEvent.WPSNode.server1になります。
サーバーごとに1つのRecovery例外宛先が設定されます。一般に、SCAシステム・バスに作成されるすべての標準的な宛先は、配信失敗メッセージをRecovery例外宛先にルーティングするよう構成されます。一方で、SCAアプリケーション・バスの標準的な宛先は、配信失敗メッセージをSCAアプリケーション・バス・システム例外宛先にルーティングするよう構成されます。JMSエクスポートが SCAアプリケーション・バスからメッセージをピックアップし、その後ロールバックする状況になると、配信失敗メッセージはWebSphere Business Integration Recovery例外宛先ではなく、SCAアプリケーション・バス・システム例外宛先にルーティングされます。
システム障害が発生すると、Process Server Recovery機能は配信失敗メッセージをこの例外宛先で捕捉するだけでなく、システム・エラーを表す失敗したイベントを生成し、このイベントをRecoveryデータベースに格納します。Failed Event Managerサブシステムは、一連のデータベース表、メッセージ駆動型Bean、EJB、およびその他の J2EE成果物で構成されています。
失敗したイベントの作成手順を次の図に示します。
図7 失敗したイベントの処理
- ソース・コンポーネントが、非同期呼び出しパターンを使用して呼び出しを実行します。
- SCA MDBがSCA宛先からメッセージをピックアップします。
- SCA MDBが正しいターゲット・コンポーネントを呼び出します。
- ターゲット・コンポーネントがServiceRuntimeExceptionをスローします。
- SCA MDBトランザクションがSCA宛先にロールバックします。
- 例外情報が、未確定状態でFEMデータベースに格納されます。
- SIBusにより呼び出しが n 回再試行されます。デフォルトは5回(1回の呼び出しと4回の再試行)です。前述したように、管理コンソールからデフォルト値を変更できます。SCAモジュール M の場合は、Buses => SCA.SYSTEM.$Cellname.Bus => Destinations => sca/M の順に移動し、最大配信失敗回数を変更します。
- 再試行回数に達すると、メッセージはFEM宛先に移動されます。
- FEM MDBがメッセージをピックアップし、データベースで失敗したイベントを更新し、状況を「Failed」に設定します。
失敗したイベントが作成される条件は何でしょうか。前述したように、同期呼び出しと両方向のビジネス・プロセス対話では失敗したイベントは作成されません。失敗したイベントは、クライアントが非同期呼び出しパターンを使用し、サービス・プロバイダーからServiceRuntimeExcpetionがスローされる場合に作成されます。ターゲット・コンポーネントがクラスターのメンバーである場合、メッセージは設定されている再試行回数まで同じクラスター・メンバーに再配信を試行します。その後、メッセージはターゲット・コンポーネントが稼働するサーバー固有のRecovery例外宛先にルーティングされます。
|