Fusion Middleware Oracle WebLogic Server JMSのプログラミング

11gリリース1 (10.3.6)

B61629-04(原本部品番号:E13727-06)

目次

タイトルおよび著作権情報

はじめに

- ドキュメントのアクセシビリティについて

- 表記規則

1 概要とロードマップ

- ドキュメントのスコープおよび対象読者

- このドキュメントの手引き

- 関連ドキュメント

- JMS開発者向けのサンプルとチュートリアル

- Avitek Medical Recordsアプリケーション(MedRec)とチュートリアル

- このリリースでのJMSの新機能と変更点

2 WebLogic JMSについて

- Java Message ServiceとWebLogic JMSの概要

- Java Message Serviceとは

- Java仕様の実装

- Java EE仕様

- JMS仕様

- WebLogic JMSのアーキテクチャ

- 主要な構成要素

- メッセージング・モデルについて

- ポイント・ツー・ポイント・メッセージング

- パブリッシュ/サブスクライブ・メッセージング

- メッセージの永続性

- JMSパブリックAPIの付加価値拡張機能

- WebLogic Serverの付加価値JMS機能

- JMS APIについて

- ConnectionFactory

- デフォルト接続ファクトリの使い方

- 接続ファクトリの構成とデプロイメント

- ConnectionFactoryクラス

- Connection

- Session

- WebLogic JMSセッションのガイドライン

- Sessionのサブクラス

- 非トランザクション・セッション

- トランザクション・セッション

- Destination

- 宛先の分散

- MessageProducerとMessageConsumer

- Message

- メッセージ・ヘッダー・フィールド

- メッセージ・プロパティ・フィールド

- メッセージ本文

- ServerSessionPoolFactory

- ServerSessionPool

- ServerSession

- ConnectionConsumer

3 アプリケーション設計のベスト・プラクティス

- メッセージの設計

- アプリケーション・オブジェクトのシリアライズ

- 文字列のシリアライズ

- サーバー側のシリアライズ

- 選択

- メッセージの圧縮

- メッセージ・プロパティとメッセージ・ヘッダー・フィールド

- メッセージの順序

- トピックとキュー

- 非同期コンシューマと同期コンシューマ

- 永続メッセージと非永続メッセージ

- 確認応答とコミットの延期

- 非恒久サブスクライバでのAUTO_ACKの使用

- 代替のサービス品質、マルチキャスト、NO_ACKNOWLEDGE

- MULTICAST_NO_ACKNOWLEDGEの使用

- NO_ACKNOWLEDGEの使用

- マルチスレッド化の回避

- JMSXUserIDプロパティの使用

- パフォーマンスおよびチューニング

4 WebLogic JMSをEJBやサーブレットと組み合せて使用するために拡張されたサポート

- WebLogic JMSラッパーの有効化

- EJBまたはサーブレットのデプロイメント記述子におけるJMSオブジェクトのリソースとしての宣言

- デプロイメント記述子を使用したラップJMSファクトリの宣言

- デプロイメント記述子を使用したJMS宛先の宣言

- デプロイメント記述子ファイルでパッケージ化JMSアプリケーション・モジュールを参照する

- weblogic-application.xml記述子でアプリケーション・モジュールを参照する

- WebLogicアプリケーションでJMSリソースを参照する

- Java EEアプリケーションでJMSリソースを参照する

- アノテーションを使用したJMS宛先および接続ファクトリの宣言

- クラスにリソース依存関係を注入する

- 非注入EJB 3.0リソース参照アノテーション

- トランザクションXAインタフェースの回避

- ラッピングとプーリングの無効化

- JMSラッパーの内部での処理

- トランザクションの自動登録

- コンテナ管理のセキュリティ

- 接続テスト

- Java EEの準拠

- プールされたJMS接続オブジェクト

- プールされた接続のモニター

- プールによるパフォーマンスの向上

- セッション・オブジェクトのプールによるJNDIルックアップの高速化

- キャッシングによるオブジェクト作成の高速化

- 適切なトランザクション・モードの登録

- 外部JMSプロバイダへのアクセスの簡略化

- JMSラッパー関数の例

- JMSラッパー関数の例

- ejb-jar.xml

- weblogic-ejb-jar.xml

- PoolTest.java

- PoolTestHome.java

- PoolTestBean.java

- Java EEコンテナによるJMSメッセージの送信

- comp/envの使用

- 依存関係インジェクション

- インジェクションを使用しないEJB 3.0ラッパー

5 基本的なJMSアプリケーションの開発

- 必要なパッケージのインポート

- JMSアプリケーションの設定

- ステップ1: JNDIで接続ファクトリをルックアップする

- ステップ2: 接続ファクトリを使用して接続を作成する

- キュー接続の作成

- トピック接続の作成

- ステップ3: 接続を使用してセッションを作成する

- キュー・セッションの作成

- トピック・セッションの作成

- ステップ4: 宛先(キューまたはトピック)をルックアップする

- JNDI名の使用

- 参照の使用

- ステップ5: メッセージ・プロデューサとメッセージ・コンシューマを作成する

- QueueSenderとQueueReceiverの作成

- TopicPublisherとTopicSubscriberの作成

- ステップ6a: メッセージ・オブジェクトを作成する(メッセージ・プロデューサ)

- ステップ6b: 非同期メッセージ・リスナーを登録する(オプション)

- ステップ7: 接続を開始する

- 例: PTPアプリケーションの設定

- ステップ1

- ステップ2

- ステップ3

- ステップ4

- ステップ5

- ステップ6

- ステップ7

- 例: Pub/Subアプリケーションの設定

- ステップ1

- ステップ2

- ステップ3

- ステップ4

- ステップ5

- ステップ6

- ステップ7

- メッセージの送信

- メッセージ・オブジェクトを作成する

- メッセージを定義する

- メッセージを宛先に送信する

- キュー・センダーを使用してメッセージを送信する

- TopicPublisherを使用してメッセージを送信する

- メッセージ・プロデューサ属性の設定

- 例: PTPアプリケーション内でのメッセージの送信

- 例: Pub/Subアプリケーション内でのメッセージの送信

- メッセージの受信

- メッセージの非同期受信

- 非同期メッセージ・パイプライン

- メッセージの同期受信

- プリフェッチ・モードを使用した同期メッセージ・パイプラインの作成

- PTPアプリケーション内でのメッセージの同期受信

- Pub/Subアプリケーション内でのメッセージの同期受信

- 受信メッセージの回復

- 受信メッセージの確認応答

- オブジェクト・リソースの解放

6 アプリケーションの管理

- ロールバック、回復、再配信、または期限切れメッセージの管理

- メッセージの再配信遅延の設定

- 再配信遅延の設定

- 宛先での再配信遅延のオーバーライド

- メッセージの再配信制限の設定

- 宛先のメッセージ再配信制限の構成

- 配信されなかったメッセージに対するエラー宛先の構成

- メッセージの再配信の順序付け

- メッセージング・ブリッジおよびMDBで必須のメッセージ・パイプライン設定

- パフォーマンスの制限

- 期限切れメッセージの処理

- メッセージ配信時間の設定

- プロデューサに対する配信時間の設定

- メッセージに対する配信時間の設定

- 配信時間のオーバーライド

- 存続時間の値との関係

- 相対配信時間のオーバーライドの設定

- スケジューリング済み配信時間のオーバーライドの設定

- JMSスケジュール・インタフェース

- 接続の管理

- 接続例外リスナーの定義

- 接続メタデータへのアクセス

- 接続の開始、停止、クローズ

- セッションの管理

- セッション例外リスナーの定義

- セッションのクローズ

- 宛先の管理

- 宛先の動的作成

- 宛先の動的削除

- 宛先を削除するための事前条件

- 宛先削除後の動作

- 削除された宛先のトラブルシューティングに使用するメッセージのタイムスタンプ

- 削除した宛先の統計

- 一時的な宛先の使い方

- 一時的なキューの作成

- 一時的なトピックの作成

- 一時的な宛先の削除

- 恒久サブスクリプションの設定

- 永続ストアの定義

- クライアントIDポリシーの設定

- クライアントIDの定義

- 共有サブスクリプション・ポリシーの作成

- 恒久サブスクリプション用のサブスクライバの作成

- ベスト・プラクティス:問題が発生したJMS ClientIDは常に閉じる

- 恒久サブスクリプションの削除

- 恒久サブスクリプションの変更

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

- メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照

- メッセージ・ヘッダー・フィールドの設定

- メッセージ・プロパティ・フィールドの設定

- メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの参照

- メッセージのフィルタ処理

- SQL文を使用したメッセージ・セレクタの定義

- XMLセレクタ・メソッドを使用したXMLメッセージ・セレクタの定義

- メッセージ・セレクタの表示

- トピック・サブスクライバのメッセージ・セレクタへの索引付けによるパフォーマンス最適化

- XMLメッセージの送信

- WebLogic XML API

- String表現の使用

- DOM表現の使用

7 JMSモジュール・ヘルパーを使用したアプリケーションの管理

- JMSModuleHelperを使用したJMSシステム・リソースの構成

- JMSサーバーとストア・アンド・フォワード・エージェントの構成

- JMSModuleHelperのサンプル・コード

- JMSシステム・リソースの作成

- JMSシステム・リソースの削除

- JMSModuleHelper使用時のベスト・プラクティス

8 WebLogic JMSでのマルチキャストの使い方

- マルチキャストを使用する利点

- マルチキャストを使用する上での制限事項

- WebLogic Serverユニキャストの使用

- WebLogic Serverでのマルチキャストの構成

- マルチキャストの前提条件

- ステップ1: JMSアプリケーション、マルチキャスト・セッション、およびトピック・サブスクライバを設定する

- ステップ2: メッセージ・リスナーを設定する

- マルチキャストの構成属性の動的構成

- 例: マルチキャストTTL (存続時間)

9 分散宛先の使用

- 分散宛先とは

- 分散宛先を使用する理由

- 分散宛先の作成

- 分散宛先の種類

- 共通分散宛先

- 重み設定された分散宛先

- 分散宛先の使用

- 分散キューの使用

- キューの転送

- QueueSender

- QueueReceiver

- QueueBrowser

- レプリケートされた分散トピックの使用

- TopicPublisher

- TopicSubscriber

- 分散トピックへのメッセージドリブンBeanのデプロイ

- パーティション化された分散トピックの使用

- 分散宛先メンバーへのアクセス

- 分散宛先のフェイルオーバー

- 分散宛先でのメッセージドリブンBeanの使用

- 分散宛先の一般的な使用例

- 生成の最大化

- 可用性の最大化

- キューの使用

- トピックの使用

- メッセージのスタック

10 メッセージ順序単位の使用

- メッセージ順序単位とは

- 順序単位によるメッセージ処理について

- JMS仕様に準拠したメッセージ処理

- 順序単位によるメッセージ処理

- 順序単位によるメッセージ配信

- メッセージ順序単位のケース・スタディ

- Joeによる本の注文

- Joeの注文の処理

- メッセージ順序単位による問題解決

- 順序単位の作成方法

- 順序単位をプログラム的に作成する

- 順序単位を管理者が作成する

- 接続ファクトリと宛先の順序単位を構成する

- 順序単位のネーミング・ルール

- 現在の順序の取得

- メッセージ順序単位の高度なトピック

- 処理中にメッセージが遅延した場合の処理

- フィルタのせいでメッセージを配信できない場合の処理

- 宛先ソート・キーを使用している場合の処理

- 分散宛先で順序単位を使用する

- パス・サービスを使用する

- ハッシュ・ベースのルーティングを使用する

- 共通分散宛先でのルーティングを構成する

- トピックで順序単位を使用する

- 順序単位と分散トピック

- 順序単位、トピック、およびメッセージドリブンBean

- JMSメッセージ管理で順序単位を使用する

- WebLogicストア・アンド・フォワードで順序単位を使用する

- WebLogicメッセージング・ブリッジで順序単位を使用する

- メッセージ順序単位の制限事項

11 作業単位メッセージ・グループの使用

- 作業単位メッセージ・グループとは

- 作業単位によるメッセージ処理について

- UOWに関連する基本用語

- UOWメッセージを処理する場合のルール

- メッセージ作業単位のケース・スタディ

- オンライン・ショップで様々な商品を注文する

- メッセージ作業単位による注文処理の仕組み

- 作業単位メッセージ・グループの作成方法

- UOWメッセージ・プロパティを設定するプロデューサの記述方法

- UOWプロデューサのサンプル・コード

- UOW例外

- 中間宛先のUOWコンシューマおよびプロデューサの記述方法

- 最終宛先の構成

- UOWメッセージの最終分散宛先へのルーティング

- 最終宛先のUOWコンシューマの記述方法

- メッセージ作業単位の高度なトピック

- メッセージ・プロパティの処理

- システム生成のプロパティ

- 最後の構成メッセージのプロパティ

- 構成メッセージの不均一性

- ReplyToメッセージ・プロパティ

- UOWと共通分散宛先

- UOWとストア・アンド・フォワード宛先

- UOWメッセージ・グループの制限事項

12 WebLogic JMSによるトランザクションの使い方

- トランザクションの概要

- JMSトランザクション・セッションの使い方

- ステップ1: JMSアプリケーションを設定し、トランザクション・セッションを作成する

- ステップ2: 必要な処理を実行する

- ステップ3: JMSトランザクション・セッションをコミットまたはロールバックする

- JTAユーザー・トランザクションの使い方

- ステップ1: JMSアプリケーションを設定し、非トランザクション・セッションを作成する

- ステップ2: JNDIでユーザー・トランザクションをルックアップする

- ステップ3: JTAユーザー・トランザクションを開始する

- ステップ4: 必要な処理を実行する

- ステップ5: JTAユーザー・トランザクションをコミットまたはロールバックする

- メッセージドリブンBeanを使用したJTAユーザー・トランザクション

- 例: JTAユーザー・トランザクションにおけるJMSとEJB

- ステップ1

- ステップ2

- ステップ3

- ステップ4

- ステップ5

- クロス・ドメイン・セキュリティの使用

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

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

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

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

- 拡張トピック機能

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

14 サーバー障害からの回復

- JMSクライアントの自動フェイルオーバー

- 自動再接続の制限事項

- JMSプロデューサの自動フェイルオーバー

- プロデューサのサンプル・コード

- 再使用可能なConnectionFactoryオブジェクト

- 再使用可能なDestinationオブジェクト

- 再接続されるConnectionオブジェクト

- 再接続されるSessionオブジェクト

- 再接続されるMessageProducerオブジェクト

- JMSコンシューマの自動フェイルオーバーの構成

- コンシューマ・クライアントのサンプル・コード

- クライアントの自動リフレッシュ・オプションの構成

- 再接続されるConsumerの一般的なケース

- 再接続されるConsumerの特殊なケース

- JMSクライアントの自動フェイルオーバーを明示的に無効にする

- プログラムを使用する場合

- 管理機能を使用する場合

- 自動フェイルオーバーを使用したJMSクライアントのベスト・プラクティス

- 常に例外をキャッチ

- トランザクションを使用してメッセージ作業をグループ化する

- JMSクライアントで必ずclose()メソッドを呼び出す

- WebLogic Server 9.0以前のリリースでの障害に関するプログラミングの考慮事項

- 新しいサーバーへのJMSデータの手動移行

15 WebLogic JMS C API

- WebLogic JMS C APIとは

- システム要件

- 設計上の原則

- ハンドルへのJavaオブジェクトのマッピング

- スレッドの利用

- 例外処理

- 型の変換

- Integer (int)

- Long (long)

- Character (char)

- String

- メモリー割当てとガベージ・コレクション

- 接続のクローズ

- ヘルパー関数

- セキュリティの考慮事項

- 実装のガイドライン

- クライアントのクラッシュにおけるスレッドのデタッチ問題の回避策

A 非推奨となったWebLogic JMS機能

- サーバー・セッション・プールの定義

- ステップ1: JNDIでサーバー・セッション・プール・ファクトリをルックアップする

- ステップ2: サーバー・セッション・プール・ファクトリを使用してサーバー・セッション・プールを作成する

- キュー接続コンシューマで使用するサーバー・セッション・プールを作成する

- トピック接続コンシューマで使用するサーバー・セッション・プールを作成する

- ステップ3: 接続コンシューマを作成する

- キュー用の接続コンシューマを作成する

- トピック用の接続コンシューマを作成する

- 例: PTPクライアントのサーバー・セッション・プールの設定

- ステップ1

- ステップ2

- ステップ3

- 例: Pub/Subクライアントのサーバー・セッション・プールの設定

- ステップ1

- ステップ2

- ステップ3

B FAQ :リモートJMSプロバイダの統合

- JMSおよびJNDIの用語

- トランザクションについて

- リモート・プロバイダと統合する方法

- リモート・プロバイダを統合する場合のベスト・プラクティス

- 外部JMSサーバー定義の使用

- EJB/サーブレットのJMSリソース参照の使用

- WebLogicストア・アンド・フォワードの使用

- WebLogic JMS SAFクライアントの使用

- メッセージング・ブリッジの使用

- メッセージングBeanの使用

- AQ JMSの使用

- JMSの相互運用性に関するドキュメント

C 宛先のルックアップ方法

- JNDI名の使用

- 宛先識別子の作成の使用

- デフォルトのWebLogic CDI構文

- カスタムWebLogic CDI構文

- 宛先ルックアップ時のサーバー・アフィニティ

- 宛先のルックアップに使用する構文の例

- 非分散宛先

- 非分散宛先のJNDI構文

- 非分散宛先のCDI構文

- 共通分散宛先

- JNDI構文(UDDの場合)

- UDDのCDI構文

- 重み設定された分散宛先

- WDDのJNDI構文

- WDDのCDI構文

D JMS宛先の可用性ヘルパーAPIを使用した分散宛先に関する拡張プログラミング

- はじめに

- DDプロデューサ・ロード・バランシングの制御

- 基本のJMS

- 分散キュー(DQ)およびパーティション化された分散トピック(PDT)へのセンダー

- レプリケートされた分散トピック(RDT)へのセンダー

- JMS宛先可用性ヘルパーAPIの使用

- 概要

- 一般的なフロー

- weblogic.jms.extension.DestinationDetailの処理

- コンシューマ・コンテナのベスト・プラクティス

- 登録と登録解除のタイミング

- URLの処理

- 失敗の処理

- JNDIコンテキストの処理

- JMS接続の処理

- 相互運用性ガイドライン

- APIの可用性

- 外部コンテキスト

- 宛先タイプのサポート

- 使用不可の通知

- WebLogic Server 9.0以前の分散キューとの相互運用

- WebLogic Server 10.3.4.0以前の分散トピックとの相互運用

- DestinationDetailのフィールド

- セキュリティの考慮事項

- WebLogic Serverセキュリティ・モデル

- スレッド間の資格証明の受渡し

- クロス・ドメイン・セキュリティの使用タイミング

- ユーザーの認証

- 宛先の保護

- ワイヤー・データの保護

- トランザクションについて

- 共通分散キュー・コンシューマ用の方針

- 一般的な戦略

- ローカル・サーバー・コンシューマのベスト・プラクティス

- 共通分散トピックに関するサブスクライバ用の方針

- インスタンスごとに1つのコピー

- 「インスタンスごとに1つのコピー」の一般的パターン設計方針

- 「インスタンスごとに1つのコピー」を使用したローカル・サーバー・コンシューマ向けベスト・プラクティス

- アプリケーションごとに1つのコピー

- 「アプリケーションごとに1つのコピー」の一般的パターン設計方針

- 「アプリケーションごとに1つのコピー」を使用したローカル・サーバー・コンシューマ向けベスト・プラクティス

Oracle® Fusion Middleware

Oracle WebLogic Server JMSのプログラミング

11gリリース1 (10.3.6)

B61629-04(原本部品番号:E13727-06)

2011年11月

このドキュメントは、WebLogic Server Java Message Service (JMS)を利用したアプリケーションを開発および構成するソフトウェア開発者を対象としています。

Oracle Fusion Middleware Oracle WebLogic Server JMSのプログラミング, 11gリリース1 (10.3.6)

B61629-04

Copyright © 2007, 2011, Oracle and/or its affiliates.All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and license terms set forth in the applicable Government contract, and, to the extent applicable by the terms of the Government contract, the additional rights set forth in FAR 52.227-19, Commercial Computer Software License (December 2007).Oracle America, Inc., 500 Oracle Parkway, Redwood City, CA 94065.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション（人的傷害を発生させる可能性があるアプリケーションを含む）への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性（redundancy）、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXはThe Open Groupの登録商標です。

このソフトウェアまたはハードウェアおよびドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

はじめに

ここでは、このガイド『Oracle WebLogic Server JMSのプログラミング』で使用されるアクセシビリティ機能および表記規則について説明します。

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイトhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=docaccを参照してください。

Oracleサポートへのアクセス

Oracleのお客様は、My Oracle Supportから電子サポートにアクセスできます。詳細情報はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=infoか、聴覚に障害のあるお客様はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=trsを参照してください。

表記規則

このドキュメントでは次の表記規則を使用します。

規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

斜体

イタリックは、ユーザーが特定の値を指定するプレースホルダー変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

1 概要とロードマップ

この章では、このガイド(『Oracle WebLogic Server JMSのプログラミング』)の内容と構成について説明します。

- ドキュメントのスコープおよび対象読者

- このドキュメントの手引き

- 関連ドキュメント

- JMS開発者向けのサンプルとチュートリアル

- このリリースでのJMSの新機能と変更点

ドキュメントのスコープおよび対象読者

このドキュメントは、WebLogic Server Java Message Service (JMS)を利用したアプリケーションを開発および構成するソフトウェア開発者を対象としています。また、WebLogic Serverを評価するビジネス・アナリストや、特定のアプリケーション用にWebLogic Server JMSの使用を考えているシステム設計者にとって便利な情報も掲載しています。

このドキュメントのトピックでは、ソフトウェア・プロジェクトの設計および開発段階に関連する情報を提供します。また、プロジェクトのテストおよび本番前のフェーズで見つかるアプリケーションの問題を解決するうえで便利なトピックもあります。

このドキュメントでは、本番フェーズでのJMSの管理、モニター、パフォーマンス・チューニングについては扱いません。これらのトピックに関するWebLogic Serverのドキュメントとリソースへのリンクについては、「関連ドキュメント」を参照してください。

このドキュメントは、Java EEおよびJMSの概念に精通している読者を対象としています。このドキュメントでは、WebLogic Server JMSが提供する付加価値機能と、JMSアプリケーションを実行するWebLogic Server機能の使い方に関する主要な情報が重点的に扱われています。

このドキュメントの手引き

- この章第1章「概要およびロードマップ」では、このガイドの構成について説明します。

- 第2章「WebLogic JMSについて」では、Java Message Serviceの概要を説明します。また、WebLogic JMSコンポーネントと機能についても説明します。

- 第3章「アプリケーション設計のベスト・プラクティス」では、WebLogic Server JMSの設計オプション、設計のプロセスで検討するアプリケーションの動作、および推奨される設計パターンについて説明します。

- 第4章「WebLogic JMSをEJBやサーブレットと組み合せて使用するために拡張されたサポート」では、WebLogic JMSをJava EEコンポーネント(エンタープライズJava Bean、サーブレットなど)と組み合せて使用するのを容易にする最良の方法について説明します。

- 第5章「基本的なJMSアプリケーションの開発」では、WebLogic JMSアプリケーションを開発する方法について説明します。

- 第6章「アプリケーションの管理」では、WebLogic JMSの付加価値機能を使用してJMSアプリケーションをプログラム的に管理する方法について説明します。

- 第7章「JMSモジュール・ヘルパーを使用したアプリケーションの管理」では、JMSサーバー、ストア・アンド・フォワード・エージェント、およびJMSシステム・リソースをプログラム的に作成および管理する方法について説明します。

- 第8章「WebLogic JMSでのマルチキャストの使い方」では、マルチキャストを使用して、指定したホストのグループへのメッセージ配信を有効にする方法について説明します。マルチキャストで配信されたメッセージは、その後サブスクライバに転送されます。

- 第9章「分散宛先の使用」では、WebLogic JMSで分散宛先を使用する方法について説明します。

- 第10章「メッセージ順序単位の使用」では、メッセージ順序単位を使用して、WebLogic JMSキューの使用時に厳格なメッセージ順序を提供する方法について説明します。

- 第11章「作業単位メッセージ・グループの使用」では、作業単位メッセージ・グループを使用して、WebLogic JMSの使用時にメッセージのグループを提供する方法について説明します。

- 第12章「WebLogic JMSによるトランザクションの使い方」では、WebLogic JMSでトランザクションを使用する方法について説明します。

- 第13章「拡張パブリッシュ/サブスクライブ・アプリケーションの開発」では、高可用性アプリケーションの設計に必要な共通分散トピック(UDT)の機能および詳細概念について説明しています。

- 第14章「サーバー障害からの回復」では、サーバーで障害が発生した場合にJMSアプリケーションを正常に終了させる方法、およびサーバーで障害が発生した後にJMSデータを移行する方法について説明します。

- 第15章「WebLogic JMS C API」では、WebLogic JMSと相互運用するCプログラムを開発する方法について説明します。

- 付録A「非推奨となったWebLogic JMS機能」では、このリリースのWebLogic Serverで非推奨になった機能について説明します。

- 付録B「FAQ :リモートJMSプロバイダの統合」では、WebLogic ServerをリモートJMSプロバイダと統合する方法に関するよくある質問とその回答を紹介します。

- 付録C「宛先のルックアップ方法」では、宛先をルックアップするために使用できる方法の概要について説明します。

- 付録D「JMS宛先の可用性ヘルパーAPIを使用した分散宛先に関する拡張プログラミング」が宛先が使用可能または使用不可になったときに通知を受信する手段を提供します。

関連ドキュメント

このドキュメントには、JMS固有の設計および開発上の情報が含まれています。

WebLogic Serverアプリケーションを開発、デプロイ、およびモニターするための包括的なガイドラインについては、以下のドキュメントを参照してください。

- 『Oracle WebLogic Server JMSの構成と管理』。JMSリソースの構成と管理に関する情報が記載されています。

- 『Oracle WebLogic Serverストア・アンド・フォワードの構成と管理』。WebLogic JMSとストア・アンド・フォワード・サービスの利点および用法に関する情報が記載されています。

- 「WebLogic永続ストアの使い方」。システム・レベルの永続ストアの利点と使い方に関する情報が記載されています。

- 『Oracle WebLogic Serverへのアプリケーションのデプロイ』。WebLogic Serverアプリケーションのデプロイメントについての主要な情報源です。

JMS開発者向けのサンプルとチュートリアル

このドキュメントの他にも、様々なサンプル・コードやチュートリアルがJMS開発者向けに用意されています。サンプルとチュートリアルではWebLogic Server JMSの動作が例示され、主要なJMS開発タスクを実行する実際的な手順が示されています。

独自のJMSアプリケーションを開発する前に、まずJMSサンプルの一部またはすべてを実行することをお薦めします。

Avitek Medical Recordsアプリケーション(MedRec)とチュートリアル

MedRecはWebLogic Serverに付属したエンドツーエンドのサンプルJava EEアプリケーションであり、一元的で独立した医療記録管理システムをシミュレートします。MedRecアプリケーションには、患者、医師、および管理者に対して、様々なクライアントを使用して患者のデータを管理するフレームワークが用意されています。

MedRecはWebLogic ServerとJava EEの機能を例示し、Oracle推奨のベスト・プラクティスを重要点として示します。MedRecはWebLogic Server配布キットに含まれており、Windowsマシンの「スタート」メニューからアクセスできます。Linuxなどのプラットフォームでは、WL_HOME\samples\domains\medrecディレクトリからMedRecを起動します。WL_HOMEは、WebLogic Platformの最上位のインストール・ディレクトリです。

MedRecには、Webアプリケーション、Webサービス、ワークフロー・アプリケーション、および将来のクライアント・アプリケーションからのリクエストを連携して処理する複数のエンタープライズJava Bean (EJB)で主に構成されるサービス層があります。このアプリケーションには、メッセージドリブンEJB、ステートレス・セッションEJB、ステートフル・セッションEJB、およびエンティティEJBが含まれます。

このリリースでのJMSの新機能と変更点

このリリースには、次の新しい機能と変更された機能が含まれています。

- 重み設定された分散宛先は、WebLogic Server 10.3.4.0では非推奨です。共通分散宛先を使用することをお薦めします。

- 高可用性アプリケーションの設計に必要な、高度なWebLogic JMSのパブリッシュとサブスクライブ(pub/sub)の概念および共通分散トピック(UDT)の機能。「拡張パブリッシュ/サブスクライブ・アプリケーションの開発」を参照してください。

- JMSDestinationAvailabilityHelper APIが宛先が使用可能または使用不可になったときに通知を受信する手段を提供します。これらのAPIは、高度な使用事例のみを対象としています。このヘルパーは、WebLogic分散コンシューマの問題を解決する手段が他にない場合にのみ使用してください。『Oracle WebLogic Server JMSのプログラミング』の「分散キューでのJMS宛先可用性ヘルパーAPIの使用」を参照してください。

WebLogic Serverのこのリリースに追加された新機能の一覧については、『「Oracle WebLogic Serverの新機能」』を参照してください。

2 WebLogic JMSについて

この章では、Java Message Service (JMS)の様々な概念と機能を紹介し、それらと他のアプリケーション・オブジェクトおよびWebLogic Serverとの連携の仕組みについて説明します。

この章は、JavaのプログラミングおよびJMS 1.1の概念と機能に精通している読者を対象としています。

- Java Message ServiceとWebLogic JMSの概要

- メッセージング・モデルについて

- JMSパブリックAPIの付加価値拡張機能

- JMS APIについて

Java Message ServiceとWebLogic JMSの概要

WebLogic JMSは、WebLogic Serverプラットフォームに緊密に統合されたエンタープライズ・クラスのメッセージング・システムです。JMS仕様(http://www.oracle.com/technetwork/java/jms/index.html)を完全にサポートし、標準JMS APIを超える機能を持つWebLogic JMS拡張が数多く用意されています。

Java Message Serviceとは

エンタープライズ・メッセージング・システムを使用すると、複数のアプリケーションがメッセージの交換を通じて通信できます。メッセージとは、異なるアプリケーション間の通信を調整するために必要な情報が含まれている、リクエスト、レポート、およびイベントです。メッセージで提供される抽象化の階層により、宛先システムについての詳細情報をアプリケーション・コードから切り離すことができます。

Java Message Service (JMS)は、エンタープライズ・メッセージング・システムにアクセスするための標準のAPIです。具体的なJMSの特長は以下のとおりです。

- メッセージング・システムを共有するJavaアプリケーション同士でメッセージを交換できます

- メッセージを作成、送信、および受信するための標準インタフェースによりアプリケーションの開発が容易になります

次の図は、WebLogic JMSメッセージングの仕組みを示しています。

図2-1 WebLogic JMSメッセージング

「図2-1 WebLogic JMSメッセージング」の説明

上の図に示すとおり、WebLogic JMSはプロデューサ・アプリケーションからメッセージを受信し、それらをコンシューマアプリケーションに送信します。

Java仕様の実装

WebLogic Serverは次のJava仕様に準拠しています。

Java EE仕様

WebLogic Serverは、http://download.oracle.com/javaee/5/api/に示すように、Java Platform、Enterprise Edition (Java EE)バージョン5.0仕様に準拠しています。

JMS仕様

WebLogic ServerはJMS 1.1仕様(http://www.oracle.com/technetwork/java/jms/index.html)に完全に準拠しており、本番環境で使用できます。

WebLogic JMSのアーキテクチャ

次の図は、WebLogic JMSのアーキテクチャを示しています。

図2-2 WebLogic JMSのアーキテクチャ

「図2-2 WebLogic JMSのアーキテクチャ」の説明

主要な構成要素

図2-2に示されているように、WebLogic JMS Serverのアーキテクチャは主に以下の要素で構成されています。

- 定義済みのモジュールのセットをホストできるJMSサーバー、およびそれらに関連付けられた永続ストレージ(WebLogic Serverインスタンスに配置)。

- 構成リソース(問合せ、トピック、接続ファクトリなど)を含み、 http://xmlns.oracle.com/weblogic/weblogic-jms/1.2/weblogic-jms.xsdスキーマに準拠するXMLドキュメントによって定義されるJMSモジュール。

- クライアントJMSアプリケーション。宛先へのメッセージを生成するか、または宛先からのメッセージを消費します。

- リソース・ルックアップ機能を提供するJNDI (Java Naming and Directory Interface)。接続ファクトリ、宛先などのJMSリソースの構成ではJNDI名を使用します。これらのリソースの実行時実装は、特定の名前を使用してJNDIにバインドされます。

- 永続的なメッセージ・データを格納するためのWebLogic永続ストレージ(ファイル・ストアまたはJDBC対応データベース)。

メッセージング・モデルについて

JMSでは、ポイント・ツー・ポイント(PTP)とパブリッシュ/サブスクライブ(pub/sub)の2つのメッセージング・モデルがサポートされています。それらのメッセージング・モデルは非常に似ていますが、以下の点で異なります。

- PTPメッセージング・モデルでは、1つの宛先に対してメッセージが配信されます。

- pub/subメッセージング・モデルでは、複数の宛先に対してメッセージが配信されます。

各モデルは、共通のベース・クラスを拡張したクラスで実装されます。たとえば、PTPクラスjavax.jms.Queue(http://download.oracle.com/javaee/5/api/javax/jms/Queue.html)とpub/subクラスjavax.jms.Topic(http://download.oracle.com/javaee/5/api/javax/jms/Topic.html)は、ともにjavax.jms.Destination(http://download.oracle.com/javaee/5/api/javax/jms/Destination.html)クラスを拡張します。

各メッセージング・モデルについては、以降の節で詳しく説明します。

注意:
「プロデューサ」および「コンシューマ」という用語は、メッセージング・モデルに関係なく、それぞれメッセージを送信および受信するアプリケーションを表すために汎用的に使用します。ただし、各メッセージング・モデルでは、それぞれに固有の一意の用語でプロデューサとコンシューマを表します。

ポイント・ツー・ポイント・メッセージング

ポイント・ツー・ポイント(PTP)メッセージング・モデルでは、アプリケーションが別の1つのアプリケーションにメッセージを送信できます。PTPメッセージング・アプリケーションでは、名前付きのキューを使用してメッセージが送信および受信されます。メッセージは、キュー・センダー(プロデューサ)によって特定のキューに送信されます。キュー・レシーバ(コンシューマ)では、特定のキューからメッセージを受信します。

次の図は、PTPメッセージングの仕組みを示しています。

図2-3 ポイント・ツー・ポイント(PTP)メッセージング

「図2-3 ポイント・ツー・ポイント(PTP)メッセージング」の説明

複数のキュー・センダーおよびキュー・レシーバを1つのキューに関連付けることができますが、個々のメッセージは1つのキュー・レシーバにしか配信できません。

複数のキュー・レシーバがキューのメッセージをリスニングしている場合、次のメッセージを受信するキュー・レシーバは先着順で決定されます。リスニングしているキュー・レシーバがない場合は、キュー・レシーバがキューにアタッチされるまでメッセージはキューにとどまります。

パブリッシュ/サブスクライブ・メッセージング

パブリッシュ/サブスクライブ(pub/sub)メッセージング・モデルでは、アプリケーションが複数のアプリケーションにメッセージを送信できます。pub/subメッセージング・アプリケーションでは、トピックをサブスクライブすることでメッセージが送受信されます。トピック・パブリッシャ(プロデューサ)によって、特定のトピックにメッセージが送信されます。トピック・サブスクライバ(コンシューマ)では、特定のトピックからメッセージが受信されます。

次の図は、pub/subメッセージングの仕組みを示しています。

図2-4 パブリッシュ/サブスクライブ(pub/sub)メッセージング

「図2-4 パブリッシュ/サブスクライブ(pub/sub)メッセージング」の説明

PTPメッセージング・モデルの場合と違って、pub/subメッセージング・モデルでは複数のトピック・サブスクライバが同じメッセージを受信できます。メッセージは、すべてのトピック・サブスクライバが受信するまで維持されます。

pub/subメッセージング・モデルでは恒久サブスクライバがサポートされるので、トピック・サブスクライバに名前を割り当て、ユーザーまたはアプリケーションと関連付けることができます。恒久サブスクライバの詳細は、「恒久サブスクリプションの設定」を参照してください。

メッセージの永続性

JMS仕様(http://www.oracle.com/technetwork/java/jms/index.html)の「Message Delivery Mode」に従って、メッセージを永続的または非永続的として指定できます。

- 永続的なメッセージは確実に1回だけ配信されます。JMSプロバイダの障害が原因でメッセージが失われたり、2回配信されることはありません。メッセージは、ファイルまたはデータベースに正常に書き込まれるまで送信されたとは判断されません。永続的メッセージは、構成時に各JMSサーバーによって必要に応じてターゲット指定されたWebLogic永続ストア(ディスク・ベース・ファイルまたはJDBCによるアクセスが可能なデータベース)に書き込まれます。

- 非永続的メッセージは格納されません。メッセージは最大で1回配信が保証されますが、JMSプロバイダに障害が発生すると失われる場合があります。ただし、2回配信されることはありません。接続をクローズするか回復すると、確認応答されていないすべての非永続的メッセージが再配信されます。非永続的メッセージは確認応答されると再配信されません。

システム全体の使用の詳細は、『Oracle WebLogic Serverサーバー環境の構成』の「WebLogic永続ストアの使い方」を参照してください。

JMSパブリックAPIの付加価値拡張機能

WebLogic JMSはWebLogic Serverプラットフォームと密接に統合されているため、非常にセキュアなJava EEアプリケーションを構築して、WebLogic Serverコンソールで簡単にモニターしたり管理したりできます。XAトランザクションが完全にサポートされているだけでなく、クラスタ機能とサービス移行機能による高可用性を特長としています。加えて、他のバージョンのWebLogic Serverやサード・パーティのメッセージ・プロバイダとのシームレスな相互運用性も提供されます。

これらの付加価値機能の詳細は、『Oracle WebLogic Server JMSの構成と管理』の「WebLogic Serverの付加価値JMS機能」を参照してください。

WebLogic Serverの付加価値JMS機能

WebLogic Serverには、JMS仕様で指定されている標準JMS APIに加え、次の表で説明するクラスやメソッドを含む様々なweblogic.jms.extensions APIが用意されています。

表2-1 WebLogic JMSパブリックAPIの拡張機能

インタフェース/クラス

機能

ConsumerInfo、

DestinationInfo

コンシューマおよび宛先の情報を、CompositeData形式で管理クライアントに提供します。

JMSMessageFactoryImpl、

WLMessageFactory

以下を作成するためのファクトリおよびメソッドを提供します。

- JMSメッセージ

- JMSバイト・メッセージ

- JMSマップ・メッセージ

- JMSオブジェクト・メッセージ

- JMSストリーム・メッセージ

- JMSテキスト・メッセージ

- JMS XMLメッセージ

JMSMessageInfo

JMXを使用したメッセージの表示と操作を提供します。

JMSModuleHelper、

JMSNamedEntityModifier

JMS実行時MBeanをモニターし、JMSモジュール内のJMSモジュール構成エントリを管理します。

JMSRuntimeHelper

JMS実行時JMX MBeanをモニターします。

MDBTransaction

MDB (メッセージドリブンBean)に配信されたメッセージとトランザクションを関連付けます。

WLDestination

宛先がキューであるかトピックであるかを識別します。

WLMessage

メッセージの配信時間、再配信制限、および送信タイムアウトを設定します。

WLMessageProducer

プロデューサのメッセージ配信時間、および順序単位の名前を設定します。

WLQueueSession、

WLSession、

WLTopicSession

javax.jms.QueueSession、javax.jms.Session、およびjavax.jms.TopicSessionでサポートされない追加のフィールドやメソッドを提供します。

XMLMessage

XMLメッセージを作成します。

Schedule

メッセージのスケジューリング済み配信時間を設定します。

JMSHelper

JMS実行時MBeanをモニターします。

このリリースのWebLogic Serverでは非推奨です。JMSModuleHelperに置き換えられました。

ServerSessionPoolFactory、

ServerSessionPoolListener

サーバー・セッション・プールおよびメッセージ・リスナーを作成するためのインタフェースを提供します。

注意:セッション・プールの構成オブジェクトは、このリリースのWebLogic Serverでは非推奨となっています。これらは、Java EE仕様の必須コンポーネントではなく、JTAユーザー・トランザクションもサポートしていません。代わりに、Java EEの必須コンポーネントであるメッセージドリブンBean (MDB)が主に使用されています。MDBの設計の詳細は、『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』を参照してください。

このAPIでは、NO_ACKNOWLEDGEとMULTICAST_NO_ACKNOWLEDGEの確認応答モード、および以下のような例外のスローを含む拡張例外もサポートされています。

- サーバー障害または管理上の介入によってコンシューマの1つがサーバーによってクローズされたときにセッション例外リスナー(設定されている場合)に例外をスローする

- セッションで受信されたが、まだメッセージ・リスナーに配信されていないメッセージの数がそのセッションの最大メッセージ許容数を超えたときにマルチキャスト・セッションから例外をスローする

- データ・ストリームでシーケンスの欠陥(シーケンスの異なる受信メッセージ)が検出されたときにマルチキャスト・コンシューマから例外をスローする

JMS APIについて

JMSアプリケーションを作成するには、javax.jms API(http://download.oracle.com/javaee/5/api/javax/jms/package-summary.html)を使用します。このAPIでは、JMSへの接続やメッセージの送受信に必要なクラス・オブジェクトを作成できます。JMSクラス・インタフェースは、共通の親クラスのキュー・バージョンとトピック・バージョンを提供するサブクラスとして作成されます。

次の表は、以降の項で詳しく説明するJMSクラスを示しています。すべてのJMSクラスの詳細は、javax.jms(http://download.oracle.com/javaee/5/api/javax/jms/package-summary.html)またはweblogic.jms.extensionsのJavadocを参照してください。

表2-2 WebLogic JMSのクラス

JMSクラス

説明

ConnectionFactory

接続の構成情報をカプセル化します。接続ファクトリは接続を作成するために使用します。接続ファクトリはJNDIを使用してルックアップします。

Connection

メッセージング・システムへの開いている通信チャネルを表します。接続はセッションを作成するために使用します。

Session

生成および消費されるメッセージの順序を定義します。

Destination

特定のプロバイダのアドレスをカプセル化して、キューまたはトピックを識別します。キューとトピックでは、それぞれPTPメッセージング・モデルおよびpub/subメッセージング・モデルから配信されるメッセージが管理されます。

MessageProducerとMessageConsumer

メッセージを送信および受信するためのインタフェースを提供します。メッセージ・プロデューサではキューまたはトピックにメッセージが送信されます。メッセージ・コンシューマではキューまたはトピックからメッセージが受信されます。

Message

送信または受信される情報をカプセル化します。

ServerSessionPoolFactory脚注 1

メッセージ・コンシューマのサーバー管理のプールに関する構成情報をカプセル化します。サーバー・セッション・プール・ファクトリはサーバー・セッション・プールを作成するために使用します。

ServerSessionPool脚注 2

メッセージを並行処理するために使用できるサーバー・セッションのプールを接続コンシューマに提供します。

ServerSession脚注 3

スレッドとJMSセッションを関連付けます。

ConnectionConsumer脚注 4

メッセージを並行処理するためにサーバー・セッションを取り出すコンシューマを指定します。

脚注 1 複数のメッセージを並行して処理するためのオプションのJMSインタフェースがサポートされます。

脚注 2 複数のメッセージを並行して処理するためのオプションのJMSインタフェースがサポートされます。

脚注 3 複数のメッセージを並行して処理するためのオプションのJMSインタフェースがサポートされます。

脚注 4 複数のメッセージを並行して処理するためのオプションのJMSインタフェースがサポートされます。

JMSリソースの構成については、『Oracle WebLogic Server JMSの構成と管理』の基本JMSシステム・リソースの構成に関する項を参照してください。JMSアプリケーションを設定する手順については、JMSアプリケーションの設定に関する項を参照してください。

ConnectionFactory

ConnectionFactoryは、接続の構成情報をカプセル化し、JMSアプリケーションがConnection (「Connection」を参照)を作成できるようにします。接続ファクトリでは同時使用がサポートされており、複数のスレッドがオブジェクトに同時にアクセスできます。WebLogic JMSが提供するあらかじめ構成されたデフォルト接続ファクトリを使用するか、1つまたは複数の接続ファクトリを構成することで、アプリケーションに適したあらかじめ定義された属性で接続を作成できます。

デフォルト接続ファクトリの使い方

WebLogic JMSでは2つのデフォルト接続ファクトリが定義されています。これらの接続ファクトリは、次のJNDI名を使用してルックアップできます。

- weblogic.jms.ConnectionFactory

- weblogic.jms.XAConnectionFactory

ユーザー定義の接続ファクトリは、デフォルト・ファクトリの設定がアプリケーションに適さない場合にのみ作成します。デフォルト接続ファクトリの構成済み設定との主な違いは、次の表に示すように、JTAトランザクションを有効にするために使用する「XA接続ファクトリを有効化」属性のデフォルト値です。

表2-3 デフォルト接続ファクトリ用のXAトランザクション設定

デフォルト接続ファクトリ

「XA接続ファクトリを有効化」の設定値

weblogic.jms.ConnectionFactory

False

weblogic.jms.XAConnectionFactory

True

XAファクトリは、JMSアプリケーションでJTAユーザー・トランザクションを使用する場合に必要となりますが、トランザクション・セッションの場合は必要ありません。WebLogic JMSでのトランザクションの使用については、第12章「WebLogic JMSによるトランザクションの使い方」を参照してください。

その他のすべてのデフォルト構成属性は、ユーザー定義の接続ファクトリと同じデフォルト値に設定されます。

「XA接続ファクトリの有効化」属性と、その他の接続ファクトリ属性のデフォルト値については、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJMS接続ファクトリ: 構成: トランザクションに関する項を参照してください。

デフォルトの接続ファクトリを使用する場合のもう1つの違いは、接続ファクトリがデプロイされる可能性のあるWebLogic Serverを限定できない点です。ただし、デフォルトの接続ファクトリはサーバー単位で無効にできます。

デフォルト接続ファクトリの有効化または無効化については、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのサーバー: 構成: サービスに関する項を参照してください。

特定の独立したサーバー、クラスタ内の特定のサーバー、またはクラスタ全体に接続ファクトリをデプロイするには、新しい接続ファクトリを構成し、適切なターゲットを指定する必要があります(『Oracle WebLogic Server JMSの構成と管理』の「接続ファクトリの構成」を参照)。

注意:
下位互換性を維持するため、WebLogic JMSでは非推奨の2つのデフォルト接続ファクトリを現在もサポートしています。該当するファクトリのJNDI名は次のとおりです。javax.jms.QueueConnectionFactoryおよびjavax.jms.TopicConnectionFactory。

接続ファクトリの構成とデプロイメント

システム管理者が1つまたは複数の接続ファクトリを定義および構成して、あらかじめ定義された属性で接続を作成すると、WebLogic Serverでは起動時にそれらの接続ファクトリがJNDIスペースに追加されます。アプリケーションでは、WebLogic JNDIを使用して接続ファクトリを取り出します。ユーザー定義の接続ファクトリには一意の名前を付ける必要があります。

接続ファクトリの構成については、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。

システム管理者は、クラスタにターゲット指定するか、クラスタ内の1つまたは複数のサーバー・インスタンスにターゲット指定することで、クラスタ内のあらゆるサーバーからJMS宛先への透過的なアクセスをクラスタ全体にわたって確立します。これにより、各接続ファクトリを複数のWebLogic Serverインスタンスにデプロイできます。JMSのクラスタリングの詳細は、『Oracle WebLogic Server JMSの構成と管理』の「拡張WebLogic JMSリソースの構成」を参照してください。

ConnectionFactoryクラス

ConnectionFactoryクラスではメソッドは定義されませんが、そのサブクラスでは各メッセージング・モデルのメソッドが定義されます。接続ファクトリでは同時使用がサポートされており、複数のスレッドがオブジェクトに同時にアクセスできます。

注意:
このリリースでは、JMS 1.1仕様の接続ファクトリを使用できます。または、そのサブクラスを使用することもできます。

次の表は、ConnectionFactoryサブクラスを説明しています。

表2-4 ConnectionFactoryサブクラス

サブクラスは...

メッセージング・モデルで...

次を作成するために使用されます...

QueueConnectionFactory

PTP

JMS PTPプロバイダへのQueueConnection

TopicConnectionFactory

pub/sub

JMS pub/subプロバイダへのTopicConnection

アプリケーションでConnectionFactoryクラスを使用する方法については、第5章「基本的なJMSアプリケーションの開発」またはjavax.jms.ConnectionFactoryのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionFactory.html)を参照してください。

Connection

Connectionは、アプリケーションとメッセージング・システムの間の開いている通信チャネルを表し、メッセージを生成および消費するためのSession (「Session」を参照)を作成するために使用します。接続では、アプリケーションとJMSの間のメッセージングを管理するサーバー側とクライアント側のオブジェクトが作成されます。接続では、ユーザーの認証も提供されます。

Connectionは、JNDIルックアップを通じて取得するConnectionFactory (「ConnectionFactory」を参照)によって作成されます。

ユーザーの認証や通信の設定に関わるリソースのオーバーヘッドがあるため、ほとんどのアプリケーションではすべてのメッセージングで1つの接続を確立します。WebLogic Serverでは、JMSトラフィックはサーバーとのクライアント接続で他のWebLogicサービスと多重化されます。JMSのために、新たなTCP/IP接続が作成されることはありません。サーブレットや他のサーバー側オブジェクトもまた、JMS Connectionを使用する場合があります。

デフォルトでは、接続は停止モードで作成されます。停止している接続を開始する方法とタイミングについては、「接続の開始、停止、クローズ」を参照してください。

接続では同時使用がサポートされており、複数のスレッドがオブジェクトに同時にアクセスできます。

注意:
このリリースでは、JMS 1.1仕様のconnectionオブジェクトを使用できます。または、そのサブクラスを使用することもできます。

次の表は、Connectionサブクラスを説明しています。

表2-5 Connectionサブクラス

サブクラスは...

メッセージング・モデルで...

次を作成するために使用されます...

QueueConnection

PTP

QueueSession。QueueConnectionFactoryで作成されたJMS PTPプロバイダへの接続で構成されます。

TopicConnection

pub/sub

TopicSession。TopicConnectionFactoryで作成されたJMS pub/subプロバイダへの接続で構成されます。

アプリケーションでConnectionクラスを使用する方法については、第5章「基本的なJMSアプリケーションの開発」またはjavax.jms.ConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Connection.html)を参照してください。

Session

Sessionオブジェクトでは、生成および消費されるメッセージの順序を定義し、複数のメッセージ・プロデューサとメッセージ・コンシューマを作成できます。メッセージの生成と消費には同じスレッドを使用できます。アプリケーションでメッセージの生成と消費に別々のスレッドが必要な場合は、そのアプリケーションで機能ごとに個別のセッションを作成する必要があります。

Sessionは、Connection (「Connection」を参照)で作成されます。

WebLogic JMSセッションのガイドライン

JMS 1.1仕様(http://www.oracle.com/technetwork/java/jms/index.html)では、汎用セッションであらゆる型のDestinationオブジェクトのMessageConsumerを使用することが許可されています。しかし、WebLogic JMSでは、単一のセッションでQueueConsumer型とTopicSubscriber型のMessageConsumerを一緒に使用することはできません。また、単一のセッションで複数のコンシューマを使用するのは、あまり一般的ではありません。以下の一般的な使用方法がサポートされています。

- 単一のセッションで、QueueSender型とTopicSubscriber型(またはQueueConsumer型とTopicPublisher型)を1つずつ使用します。

- MessageProducerを複数使用します。MessageProducerは型に関係なく複数使用できます。

注意:
セッションおよびそのメッセージのプロデューサとコンシューマには、一度に1つのスレッドしかアクセスできません。それらに複数のスレッドが同時にアクセスした場合、それらの動作は不明確になります。

Sessionサブクラス

次の表は、Sessionサブクラスを説明しています。

表2-6 Sessionサブクラス

サブクラスは...

メッセージング・モデルで...

次のためにコンテキストを提供します...

QueueSession

PTP

JMS PTPプロバイダのメッセージを生成および消費します。QueueConnectionで作成されます。

TopicSession

pub/sub

JMS pub/subプロバイダのメッセージを生成および消費します。TopicConnectionによって作成されます。

アプリケーションでSessionクラスを使用する方法については、第5章「基本的なJMSアプリケーションの開発」、またはjavax.jms.SessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Session.html)およびweblogic.jms.extensions.WLSessionのJavadocを参照してください。

非トランザクション・セッション

非トランザクション・セッションでは、セッションを作成するアプリケーションで、次の表で定義されている5つの確認応答モードのいずれかが選択されます。

表2-7 非トランザクション・セッションで使用する確認応答モード

確認応答モード

説明

AUTO_ACKNOWLEDGE

受信側アプリケーションのメソッドが処理を終えたときに、Sessionオブジェクトでメッセージ受信の確認応答が行われます。

CLIENT_ACKNOWLEDGE

Sessionオブジェクトの動作は、アプリケーションによる確認応答メソッドの呼出しに依存します。メソッドが呼び出されると、セッションでは、前回の確認応答以降に受信されたすべてのメッセージに対して確認応答が行われます。

このモードを使用すると、アプリケーションでは1回の呼出しで複数メッセージの受信、処理、および確認応答を行うことができます。

注意: 管理コンソールでは、接続ファクトリの「確認応答ポリシー」属性がPreviousに設定されているのに対し、指定のセッションでのすべての受信メッセージを確認応答したい場合、最後のメッセージを使用して確認応答メソッドを呼び出します。

「確認応答ポリシー」属性の詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJMS接続ファクトリ: 構成: 全般に関する項を参照してください。

DUPS_OK_ACKNOWLEDGE

受信側アプリケーションのメソッドが処理を終えたときに、Sessionオブジェクトでメッセージ受信の確認応答が行われます。確認応答の重複が許可されます。

このモードでは、最も効率的にリソースが利用されます。

注意: アプリケーションで重複メッセージを処理できない場合は、このモードは使用しません。重複メッセージは、メッセージを配信する最初の試行が失敗した場合に送信されます。

NO_ACKNOWLEDGE

確認応答を必要としません。NO_ACKNOWLEDGEセッションに送信されたメッセージは、サーバーから即座に削除されます。このモードで受信されたメッセージは回復されないので、メッセージを配信する最初の試行が失敗した場合はメッセージが失われたり、重複メッセージが配信されたりします。

このモードは、セッションの確認応答で提供されるサービスの質を必要とせず、それに関連するオーバーヘッドを避ける必要があるアプリケーションで使用します。

注意: アプリケーションで、失われたメッセージや重複メッセージを処理できない場合は、このモードは使用しないようにします。重複メッセージは、メッセージを配信する最初の試行が失敗した場合に送信されます。

MULTICAST_NO_ACKNOWLEDGE

確認応答を必要としないマルチキャスト・モード。

MULTICAST_NO_ACKNOWLEDGEセッションに送信されたメッセージでは、前述のNO_ACKNOWLEDGEモードと同じ特性が共有されます。

このモードは、マルチキャストをサポートし、セッションの確認応答で提供されるサービスの質を必要としないアプリケーションで使用します。マルチキャストの詳細は、第8章「WebLogic JMSでのマルチキャストの使い方」を参照してください。

注意: トピックでのみ使用します。アプリケーションで、失われたメッセージや重複メッセージを処理できない場合は、このモードは使用しないようにします。重複メッセージは、メッセージを配信する最初の試行が失敗した場合に送信されます。

トランザクション・セッション

トランザクション・セッションでは、一度に1つのトランザクションしかアクティブになりません。トランザクション中に送信または受信されたメッセージ数に関係なく、最小の単位として処理されます。

トランザクション・セッションを作成すると、確認応答モードは無視されます。アプリケーションでトランザクションがコミットされると、そのトランザクションの間にアプリケーションで受信されたすべてのメッセージがメッセージング・システムによって確認応答され、アプリケーションで送信されたメッセージは配信されるべく受け入れられます。アプリケーションでトランザクションがロールバックされると、そのトランザクションの間にアプリケーションで受信されたメッセージは確認応答されず、アプリケーションで送信されたメッセージは破棄されます。

JMSは、Java Transaction API (JTA)を使用する他のJavaサービス(EJBなど)との分散トランザクションに参加できます。トランザクションはそのトランザクションに関連付けられたメッセージへのアクセスが制限されているため、トランザクション・セッションではこの機能をサポートしません。JTAの利用の詳細は、「JTAユーザー・トランザクションの使い方」を参照してください。

宛先

Destinationオブジェクトはキューまたはトピックになり、特定プロバイダのアドレス構文をカプセル化します。プロバイダによって構文はさまざまであるため、JMS仕様では標準のアドレス構文は定義されていません。

接続ファクトリの場合と同じように、管理者が宛先を定義し、構成すると、WebLogic Serverの起動時にそれがJNDIスペースに追加されます。また、アプリケーションでは、それが作成されたJMS接続の間だけ存在する一時的な宛先を作成することもできます。

注意:
管理者は、分散宛先を構成することもできます。分散宛先は、単一の論理的な宛先としてクライアントからアクセス可能な1つの宛先セット(キューまたはトピック)です。詳細については、「宛先の分散」を参照してください。

クライアント側では、QueueオブジェクトとTopicオブジェクトは、サーバー上のオブジェクトへのハンドルとして機能します。それらのメソッドは、それらの名前のみを返します。メッセージングを目的としてアクセスするには、それらにアタッチするメッセージ・プロデューサとメッセージ・コンシューマを作成します。

宛先では同時使用がサポートされており、複数のスレッドがオブジェクトに同時にアクセスできます。JMSのQueuesとTopicsは、javax.jms.Destination(http://download.oracle.com/javaee/5/api/javax/jms/Destination.html)を拡張します。

注意:
このリリースでは、JMS 1.1仕様のdestinationオブジェクトを使用できます。または、そのサブクラスを使用することもできます。

次の表は、Destinationサブクラスを説明しています。

表2-8 Destinationサブクラス

サブクラス

メッセージング・モデル

管理するメッセージ

Queue

PTP

JMSポイント・ツー・ポイント・プロバイダ

TemporaryQueue

PTP

JMSポイント・ツー・ポイント・プロバイダのメッセージ。メッセージが作成されたJMS接続の間だけ存在します。一時的なキューはそれを作成したキュー接続によってのみ消費されます。

Topic

pub/sub

JMS pub/subプロバイダのメッセージ。

TemporaryTopic

pub/sub

JMS pub/subプロバイダのメッセージ。メッセージが作成されたJMS接続の間だけ存在します。一時的なトピックはそれを作成したトピック接続によってのみ消費されます。

注意:
アプリケーションでは、キュー・セッションでQueueBrowserオブジェクトを作成することによりキューを参照することができます。このオブジェクトでは、キュー・ブラウザが作成された時点におけるキュー内のメッセージのスナップショットが生成されます。アプリケーションではキュー内のメッセージを表示できますが、メッセージは「読み込まれた」とは判断されず、したがってキューから削除されることはありません。キューの参照の詳細は、「メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照」を参照してください。

アプリケーションでDestinationクラスを使用する方法については、第5章「基本的なJMSアプリケーションの開発」またはjavax.jms.DestinationのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Destination.html)を参照してください。

宛先の分散

分散宛先リソースは、単一の論理的な宛先としてクライアントからアクセス可能な1つの宛先セット(キューまたはトピック)です(たとえば分散トピックは独自のJNDI名を持ちます)。このセットのメンバーは通常、クラスタ内の複数のサーバーに分散されており、各メンバーは別々のJMSサーバーに属しています。分散宛先を使用するアプリケーションは、スタンドアロンの宛先を使用するアプリケーションより可用性が高くなります。これは、WebLogic JMSに、クラスタ内の分散宛先メンバーのためのロード・バランシングおよびフェイルオーバー機能があるためです。

- ご使用のアプリケーションにおける分散宛先の詳細は、第9章「分散宛先の使用」を参照してください。

- 分散キュー宛先の構成手順については、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの共通分散キューの構成に関する項を参照してください。

- 分散トピック宛先の構成手順については、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの共通分散トピックの構成に関する項を参照してください。

MessageProducerとMessageConsumer

MessageProducerでは、メッセージがキューまたはトピックに送信されます。MessageConsumerでは、メッセージがキューまたはトピックから受信されます。メッセージ・プロデューサとメッセージ・コンシューマは、互いに独立して機能します。メッセージ・コンシューマが作成されてメッセージを待っているかどうかに関係なく、メッセージ・プロデューサではメッセージが生成および送信されます(この逆も同様)。

Session (「Session」を参照)では、キューおよびトピックにアタッチされるMessageProducersとMessageConsumersが作成されます。

メッセージ・センダー・オブジェクトとメッセージ・レシーバ・オブジェクトは、MessageProducerクラスおよびMessageConsumerクラスのサブクラスとして作成されます。

注意:
このリリースでは、JMSバージョン1.1仕様のメメッセージ・プロデューサおよびカスタマ・オブジェクトを使用できます。または、そのサブクラスを使用することもできます。

次の表は、MessageProducerおよびMessageConsumerサブクラスを説明しています。

表2-9 MessageProducerおよびMessageConsumerサブクラス

サブクラス

メッセージング・モデルで

次の機能を実行します

QueueSender

PTP

JMSポイント・ツー・ポイント・プロバイダのメッセージを送信します。

QueueReceiver

PTP

JMSポイント・ツー・ポイント・プロバイダのメッセージを受信します。

TopicPublisher

pub/sub

JMS pub/subプロバイダのメッセージを送信します。

TopicSubscriber

pub/sub

JMS pub/subプロバイダのメッセージを受信します。

図2-3で示されているように、PTPモデルでは複数のセッションが同じキューからメッセージを受信できます。ただし、メッセージは、1つのキュー・レシーバにしか配信できません。複数のキュー・レシーバがある場合、次にメッセージを受信するキュー・レシーバは先着順で決まります。

図2-4で示されているように、pub/subモデルではメッセージを複数のトピック・サブスクライバに配信できます。トピック・サブスクライバは、「恒久サブスクリプションの設定」で説明されているように恒久にも非恒久にもなります。

アプリケーションでは、1つのトピックのパブリッシュとサブスクライブに同じJMS接続を使用できます。トピック・メッセージはすべてのサブスクライバに配信されるので、アプリケーションは自身がパブリッシュしたメッセージを受信できます。メッセージがパブリッシュ元のクライアントで受信されるのを防ぐために、JMSアプリケーションではトピック・サブスクライバに対してnoLocal属性を設定できます。詳細は、「ステップ5: メッセージ・プロデューサとメッセージ・コンシューマを作成する」を参照してください。

アプリケーションでMessageProducerクラスとMessageConsumerクラスを使用する方法については、「JMSアプリケーションの設定」、またはjavax.jms.MessageProducerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/MessageProducer.html)およびjavax.jms.MessageConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/MessageConsumer.html)を参照してください。

Message

Messageでは、アプリケーション間で交換される情報がカプセル化されます。この情報は、以下の3つの要素で構成されます。

- メッセージ・ヘッダー・フィールド

- メッセージ・プロパティ・フィールド

- メッセージ本文

メッセージ・ヘッダー・フィールド

すべてのJMSメッセージには、デフォルトで挿入され、メッセージ・コンシューマで利用できる標準のヘッダー・フィールドがあります。一部のフィールドは、メッセージ・プロデューサで設定できます。

メッセージ・ヘッダー・フィールドの設定については、「メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照」、またはjavax.jms.MessageのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Message.html)を参照してください。

次の表は、メッセージ・ヘッダーのフィールドを説明し、各フィールドで値がどのように定義されるのかを示しています。

表2-10 メッセージ・ヘッダー・フィールド

フィールド

説明

次によって定義されます

JMSCorrelationID

WebLogic JMSMessageID (この表内で後述)、アプリケーション固有の文字列、またはbyte[]配列のいずれかを指定します。JMSCorrelationIDはメッセージを相関させるために使用します。send()の前に、アプリケーションによってメッセージに直接設定されます。

このフィールドには2つの一般的な用途があります。

第1の用途は、次のようなリクエストとレスポンスの方式を設定してメッセージをリンクすることです。

1. メッセージを送信するときに、アプリケーションではそのメッセージに割り当てられたJMSMessageID値を格納します。

2. そのメッセージを受信したアプリケーションでは、送信側アプリケーションに送り返すレスポンス・メッセージのJMSCorrelationIDフィールドにJMSMessageIDをコピーします。

第2の用途は、選択した文字列をJMSCorrelationIDフィールドに格納し、一連のメッセージをアプリケーション指定の値でリンクできるようにすることです。

アプリケーション

JMSDeliveryMode

PERSISTENTまたはNON_PERSISTENTを指定します。このフィールドは、プロデューサに設定されるか、send()の前にアプリケーションによって送信されるパラメータとして設定されます。

永続的なメッセージが送信された場合、そのメッセージはWebLogic永続ストアに格納されます。send()処理は、メッセージの配信を保証できるまで成功とは判断されません。永続的なメッセージは少なくとも1回は確実に配信されます。

非永続的メッセージは永続ストアに格納されません。このモードでは、処理のオーバーヘッドが最小限に抑えられます。メッセージは最低1回は配信が保証されますが、システム障害が発生すると失われる場合があります。接続をクローズするか回復すると、確認応答されていないすべての非永続的メッセージが再配信されます。非永続的メッセージは確認応答されると再配信されません。

この値は、producer.send()への呼出しによって上書きされます。この値をメッセージに直接設定しても無効となります。プロデューサによって設定された値は、producer.send()に提供されたメッセージを使用して問い合わせるか、コンシューマがメッセージを受信したときに問い合わせることができます。

send()メソッド

JMSDeliveryTime

メッセージをコンシューマに配信できる最も早い絶対時間を定義します。このフィールドは、プロデューサに設定されたtimeToDeliverに応じて、send()の前にアプリケーションによって設定されます。

このフィールドは、宛先でのメッセージのソート、またはメッセージの選択に使用できます。データ型変換の目的で、JMSDeliveryTimeは長整数として保存されます。

send()メソッド

JMSDestination

メッセージが配信される宛先(キューまたはトピック)を指定します。このフィールドは、プロデューサの作成時に設定されるか、send()の前にアプリケーションによって送信されるパラメータとして設定されます。

この値は、producer.send()への呼出しによって上書きされます。この値をメッセージに直接設定しても無効となります。プロデューサによって設定された値は、producer.send()に提供されたメッセージを使用して問い合わせるか、コンシューマがメッセージを受信したときに問い合わせることができます。メッセージが受信されるとき、その宛先の値は送信時に割り当てられた値と同じでなければなりません。

send()メソッド

JMSExpiration

メッセージの有効期限(存続時間値)を指定します。このフィールドは、send()の前にアプリケーションによって設定されます。プロデューサに設定されるか、アプリケーションがsend()に送信するパラメータとして設定されるtimeToLiveに依存します。

JMSExpirationの値は、アプリケーションの存続時間とその時点のGMTの合計として算出されます。アプリケーションで存続時間が0として指定されると、JMSExpirationは0に設定され、メッセージは無期限になります。

期限の切れたメッセージは、誤って配信されないようにシステムから削除されます。

send()メソッド

JMSMessageID

JMSプロバイダによって送信される各メッセージを一意に識別する文字列値を格納します。このフィールドは、send()によって内部的に設定されます。

すべてのJMSMessageIDはID:という接頭辞で始まります。

この値は、producer.send()への呼出しによって上書きされます。この値をメッセージに直接設定しても無効となります。プロデューサによって設定された値は、producer.send()に提供されたメッセージを使用して問い合わせるか、コンシューマがメッセージを受信したときに問い合わせることができます。メッセージが受信されるときには、プロバイダの割り当てた値が格納されています。

send()メソッド

JMSPriority

優先順位のレベルを指定します。このフィールドは、プロデューサに設定されるか、send()の前にアプリケーションによって送信されるパラメータとして設定されます。

JMSでは、0 - 9の10段階で優先順位が定義されています(0が最低の優先順位)。レベル0 - 4は通常の範囲に属し、レベル5 - 9は至急の範囲に属します。

メッセージが受信されるときには、メッセージを送信するメソッドで指定された値が格納されています。

宛先キーを構成すれば、優先順位を基準に宛先をソートできます。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの宛先キーの構成に関する項を参照してください。

send()メソッド

JMSRedelivered

確認応答がないためメッセージが再配信されるときに設定されるフラグを指定します。このフラグは受信側アプリケーションに関係があります。

フラグが設定されている場合は、以下のいずれかの理由のために、同じメッセージが以前に配信されている可能性があります。

- アプリケーションではすでにメッセージが受信されていますが、確認応答が行われていません。

- セッションのrecover()メソッドが呼び出されて、最後に確認応答されたメッセージの後からセッションが再起動されました。recover()メソッドの詳細は、「受信メッセージの回復」を参照してください。

WebLogic JMS

JMSReplyTo

応答メッセージが送信されるキューまたはトピックを指定します。このフィールドは、send()の前に、アプリケーションによって直接メッセージに設定されます。

この機能はJMSCorrelationIDヘッダー・フィールドと共に使用してリクエストとレスポンスのメッセージを連係させることができます。

JMSReplyToフィールドをただ設定するだけでは、受信側アプリケーションの応答が有効になるだけで、レスポンスが保証されるわけではありません。

アプリケーション

JMSTimestamp

メッセージが送信されたときの時刻を格納します。タイムスタンプは、アプリケーションでメッセージが送信されたときではなく、WebLogic JMSで配信用にメッセージが受け付けられたときにメッセージに書き込まれます。

メッセージが受信されるときには、タイムスタンプが格納されています。

このフィールドには、Javaのミリ時間の値が格納されます。

WebLogic JMS

JMSType

send()の前にアプリケーションによって直接メッセージに設定されたメッセージ・タイプ識別子(String)を示します。

JMS仕様では、多様なJMSプロバイダに適応するため、このフィールドに若干の柔軟性を持たせています。一部のメッセージング・システムでは、アプリケーション固有のメッセージ・タイプを使用できます。そのようなシステムの場合、JMSTypeフィールドは、格納されている型定義にアクセスするためのメッセージ・タイプIDを保持するために使用できます。

WebLogic JMSでは、このフィールドの使用に制限を設けていません。

アプリケーション

メッセージ・プロパティ・フィールド

メッセージのプロパティ・フィールドには、送信側アプリケーションによって追加されたヘッダー・フィールドが格納されます。プロパティは、標準的なJavaの名前と値の組合せです。プロパティ名は、javax.jms.MessageのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Message.html)で定義されているメッセージ・セレクタの構文仕様に準拠していなければなりません。有効な値は、boolean、byte、double、float、int、long、およびStringです。

WebLogic Serverは、JMS 1.1で定義されているとおり次のJMS (JMSX)定義プロパティの使用をサポートします。仕様は、http://www.oracle.com/technetwork/java/jms/index.htmlから参照できます:

表2-11 JMSXプロパティ

タイプ

説明

JMSXUserID

メッセージの送信者であるユーザーを識別するシステム生成のプロパティ。「JMSXUserIDプロパティの使用」を参照してください。

JMSXDeliveryCount

メッセージの配信試行回数を指定するシステム生成のプロパティ。1回目の試行を1とします。

JMSXGroupID

メッセージ・グループのID。

JMSXGroupSeq

グループ内のメッセージの連続番号。

メッセージ・プロパティ・フィールドは、アプリケーション固有の目的に使用できますが、それらは基本的にはメッセージ・セレクタで使用するために用意されています。JMSプロパティをそれぞれの環境でどのように使用するかはユーザーが決定します。たとえば、処理条件に応じて一部のメッセージにだけ含め、その他のメッセージでは省略することもできます。詳細については、以下を参照してください。

- メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照

- メッセージのフィルタ処理

- JMS 1.1.仕様は、http://www.oracle.com/technetwork/java/jms/index.htmlに説明があります

メッセージ本文

メッセージ本文は、プロデューサからコンシューマに配信される内容です。

次の表は、JMSで定義されているメッセージ・タイプを説明しています。すべてのメッセージ・タイプは、メッセージ・ヘッダーとメッセージ・プロパティ(メッセージ本文はなし)で構成されるjavax.jms.Message(http://download.oracle.com/javaee/5/api/javax/jms/Message.html)を拡張します。

表2-12 JMSメッセージ・タイプ

タイプ

説明

javax.jms.BytesMessage

未解釈バイトのストリーム。センダーとレシーバによって理解されなければなりません。このメッセージ・タイプのアクセス・メソッドは、java.io.DataInputStreamおよびjava.io.DataOutputStreamに基づくストリーム対応のリーダーとライター。http://download.oracle.com/javaee/5/api/javax/jms/BytesMessage.htmlを参照してください。

javax.jms.MapMessage

名前が文字列であり、値がJavaプリミティブ型である、複数の名前と値の組合せ。名前と値の組合せは、名前を指定することによって順次的にもランダムにも読み込むことができます。

javax.jms.ObjectMessage

1つのシリアライズ可能なJavaオブジェクト。http://download.oracle.com/javaee/5/api/javax/jms/ObjectMessage.htmlを参照してください。

javax.jms.StreamMessage

Javaプリミティブ型のみがストリームで読み書きされること以外は、BytesMessageと同じです。http://download.oracle.com/javaee/5/api/javax/jms/StreamMessage.htmlを参照してください。

javax.jms.TextMessage

1つのString。TextMessageではXMLコンテンツも格納できます。http://download.oracle.com/javaee/5/api/javax/jms/TextMessage.htmlを参照してください。

weblogic.jms.extensions.XMLMessage

XMLコンテンツ。XMLMessageタイプを使用すると、TextMessageで送信されるXMLコンテンツでは処理しにくいメッセージのフィルタ処理を容易に行うことができます。

詳細は、javax.jms.MessageのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Message.html)を参照してください。特定のメッセージ・タイプのアクセス・メソッドや変換チャートについては、そのメッセージ・タイプのJavadocを参照してください。

ServerSessionPoolFactory

注意:
セッション・プールおよび接続コンシューマの構成オブジェクトは、WebLogic Serverの本リリースでは非推奨となっています。これらは、Java EE仕様の必須コンポーネントではなく、JTAユーザー・トランザクションもサポートしていないためです。かわりに、より単純で可用性が高く、管理も容易なメッセージドリブンBean (MDB)が主に使用されています。MDBの設計の詳細は、『Oracle WebLogic Server Enterprise JavaBeansのプログラミング』の「メッセージドリブンEJB」を参照してください。

サーバー・セッション・プールは、メッセージの並行処理を実現するWebLogic固有のJMS機能です。サーバー・セッション・プール・ファクトリは、サーバー側のServerSessionPoolを作成するために使用します。

WebLogic JMSでは、デフォルトで次のようなServerSessionPoolFactoryオブジェクトが定義されています。weblogic.jms.extensions.ServerSessionPoolFactory:<name>。ここで<name>には、セッション・プールの作成先になるJMSサーバーの名前を指定します。WebLogic Serverではデフォルトのサーバー・セッション・プール・ファクトリが起動時にJNDIスペースに追加され、アプリケーションではWebLogic JNDIを使用してサーバー・セッション・プール・ファクトリが取り出されます。

アプリケーションでサーバー・セッション・プール・ファクトリを使用する方法については、「サーバー・セッション・プールの定義」またはweblogic.jms.extnesions.ServerSessionPoolFactoryのJavadocを参照してください。

ServerSessionPool

ServerSessionPoolアプリケーション・サーバー・オブジェクトでは、メッセージを並行処理するために接続コンシューマで取り出すことができるサーバー・セッションのプールが提供されます。

ServerSessionPoolは、JNDIルックアップで取得されるServerSessionPoolFactoryオブジェクト(「ServerSessionPoolFactory」を参照)によって作成されます。

アプリケーションでサーバー・セッション・プールを使用する方法については、「サーバー・セッション・プールの定義」またはjavax.jms.ServerSessionPoolのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ServerSessionPool.html)を参照してください。

ServerSession

ServerSessionアプリケーション・サーバー・オブジェクトでは、メッセージを作成、送信、および受信するためのコンテキストが提供され、スレッドとJMSセッションを関連付けることができます。

ServerSessionは、ServerSessionPoolオブジェクト(「ServerSessionPool」を参照)によって作成されます。

アプリケーションでサーバー・セッションを使用する方法については、「サーバー・セッション・プールの定義」またはjavax.jms.ServerSessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ServerSession.html)を参照してください。

ConnectionConsumer

ConnectionConsumerオブジェクトでは、サーバー・セッションを使用して受信メッセージを処理します。メッセージ・トラフィックが大きい場合は、スレッド・コンテキストの切替えを最小限に抑えるために、接続コンシューマでは複数のメッセージで各サーバー・セッションをロードすることができます。ConnectionConsumerは、Connectionオブジェクト(「Connection」を参照)によって作成されます。

アプリケーションで接続コンシューマを使用する方法については、「サーバー・セッション・プールの定義」またはjavax.jms.ConnectionConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionConsumer.html)を参照してください。

注意:
接続コンシューマ・リスナーは、サーバーと同じJVMで動作します。

3 アプリケーション設計のベスト・プラクティス

この章では、WebLogic Server JMSの設計オプション、設計の過程で考慮すべきアプリケーションの動作、および推奨の設計パターンについて説明します。

- メッセージの設計

- メッセージの圧縮

- メッセージ・プロパティとメッセージ・ヘッダー・フィールド

- メッセージの順序

- トピックとキュー

- 非同期コンシューマと同期コンシューマ

- 永続メッセージと非永続メッセージ

- 確認応答とコミットの延期

- 非恒久サブスクライバでのAUTO_ACKの使用

- 代替のサービス品質、マルチキャスト、NO_ACKNOWLEDGE

- マルチスレッド化の回避

- JMSXUserIDプロパティの使用

- パフォーマンスおよびチューニング

メッセージの設計

この節では、メッセージングのパフォーマンスを向上させるメッセージの設計方法について説明します。

アプリケーション・オブジェクトのシリアライズ

Javaオブジェクトのシリアライズを行うと、CPUに非常に大きな負荷がかかるおそれがあります。最終的には、この負荷がJMSオブジェクト・メッセージに影響します。この負荷は、java.io.Externalizableを実装するアプリケーション・オブジェクトを使用することである程度相殺できますが、クラス記述子のマーシャリングにおいては依然として大きなオーバーヘッドになります。Objectメッセージに組み込む追加オブジェクトのクラス記述子を記述する手間を省くには、これらのオブジェクトにExternalizableを実装し、オブジェクト上で直接readExternalおよびwriteExternalを呼び出します。たとえば、stream.writeObject(obj)ではなくobj.writeExternal(stream)を呼び出します。通常、BytesメッセージやStreamメッセージを使用すると、より望ましい結果が得られます。

文字列のシリアライズ

Java文字列のシリアライズは、その他のJavaプリミティブ型のシリアライズよりも大きな負荷がかかります。文字列はメモリーも多用します。1文字につき2バイトのメモリーを消費し、バイナリ・データ(整数など)をコンパクトに表現することもできません。また、文字列ベースのメッセージを使用すると、多くの場合、文字列をアプリケーションで直接使用できる形式に処理するための解析が負荷になります。したがって、Bytesメッセージ、Streamメッセージ、Mapメッセージ、そしてObjectメッセージでさえも、TextメッセージやXMLメッセージよりも望ましい結果になることがあります。同様に、メッセージ・プロパティでは文字列を使用しないことをお薦めします(特にそのサイズが大きい場合)。

サーバー側のシリアライズ

非永続メッセージのシリアライズの負荷は、WebLogic JMSサーバーにはかかりません。非永続メッセージ・タイプのシリアライズは、リモート・クライアントの負荷で実行されます。永続メッセージは、サーバーでシリアライズされます。

選択

セレクタを使用すると大きな負荷になります。この点は、JMSセレクタを使用してアクセスするアプリケーション・データを、メッセージ内のどこに格納するかを決める上で十分に考慮する必要があります。

メッセージの圧縮

JMSアプリケーション内の大きなメッセージを圧縮するとパフォーマンスが向上します。圧縮することで、ネットワーク上でのメッセージの転送に必要な時間が短縮され、JMSサーバーが使用するメモリーの量も減ります。また、永続メッセージの場合は、永続書込みのサイズも小さくなります。多くの場合、TextおよびXMLメッセージはかなり圧縮できます。ただし、圧縮を行うと、当然のことながらクライアントのCPU使用量が増えることになります。

小さいメッセージの場合は、圧縮する利点がない場合もあります。メッセージのサイズが数KB以下の場合、圧縮することで実際のサイズが大きくなることもあります。JDKには、組込みの圧縮ライブラリが用意されています。詳細については、java.util.zipパッケージを参照してください。

指定されたしきい値のサイズを超過したメッセージの自動圧縮をJMS接続ファクトリを使用して指定する方法については、『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「メッセージの圧縮」を参照してください。

メッセージ・プロパティとメッセージ・ヘッダー・フィールド

ユーザー定義のメッセージ・プロパティのかわりに、標準のJMSメッセージ・ヘッダー・フィールドや、メッセージ・データのメッセージ本文を使用することも検討してください。メッセージ・プロパティは、シリアライズに余分な負荷がかかり、アクセスにおいても標準のJMSメッセージ・ヘッダー・フィールドより大きな負荷がかかります。

また、プロパティ・フィールドやヘッダー・フィールドに大量のデータを組み込むことも避けてください。ページングが有効になっている場合でも、ページングされるのはメッセージの本文のみです。したがって、アプリケーションにユーザー定義のメッセージ・プロパティが定義されている場合は、大きな文字列プロパティを使用しないようにしてください。

詳細については、「メッセージ・ヘッダー・フィールド」および「メッセージ・プロパティ・フィールド」を参照してください。

メッセージの順序

メッセージの処理を厳格に順序付けする場合は、再配信の順序付け機能ではなく、メッセージ順序単位機能を使用することをお薦めします。再配信の順序付けに比べ、メッセージ順序単位には以下の利点があります。

- 構成のしやすさ。

- 非同期レシーバのカスタム接続ファクトリが必要ありません。たとえば、メッセージドリブンBean (MDB)を使用する場合は、MessagingMaximumを1に設定します。

- 分散宛先を使用する場合の、単純な構成。

- 処理遅延の間もメッセージの順序が維持されます。

- トランザクションのロールバックやセッションのリカバリの間もメッセージの順序が維持されます。

再配信の順序付けを使用しているアプリケーションは、メッセージ順序単位を使用するようにアップグレードすることをお薦めします。詳細については、第10章「メッセージ順序単位の使用」を参照してください。

トピックとキュー

アプリケーションの設計を始めるときには、トピックとキューのどちらを使用したほうがよいかを即座に判断できない場合もあります。一般的には、以下の条件のいずれかが満たされる場合にのみトピックを選択します。

- 同じメッセージを、複数のコンシューマにレプリケートする必要があります。

- メッセージを選択するアクティブなコンシューマがない場合に、そのメッセージを破棄する必要があります。

- たくさんのサブスクライバがあり、それぞれに一意のセレクタがあります。

恒久サブスクライバが1つのみのトピックは、セマンティクスの面ではキューに似ています。相違点は以下のとおりです。

- 恒久サブスクライバのトピック・セレクタを変更した場合、サブスクリプション内の以前のメッセージがすべて削除されますが、コンシューマのキュー・セレクタを削除してもキュー内のメッセージは削除されません。

- キューの場合はメッセージを複数のコンシューマにラウンドロビン方式で配信できますが、トピック・サブスクライバのコンシューマは1つに制限されています。

JMSキューとトピックの構成の詳細は、『Oracle WebLogic Server JMSの構成と管理』の「キューおよびトピック宛先リソースの構成」を参照してください。

非同期コンシューマと同期コンシューマ

一般的に、非同期(onMessage)コンシューマは、パフォーマンスとスケーラビリティの面で同期コンシューマより優れています。

- 非同期コンシューマの場合、作成されるネットワーク・トラフィックが少なくなります。メッセージは、メッセージ・リスナーへのパイプラインを使用して一方向に送信されます。パイプラインでは、複数のメッセージを単一のネットワーク呼出しに集約できます。

注意:
WebLogic Serverでは、JMS接続ファクトリの「同期コンシューマのプリフェッチ・モード」オプションを有効にすることで、同期コンシューマでも非同期コンシューマと同じ効率的な動作を利用できるようになります。詳細は、「プリフェッチ・モードを使用した同期メッセージ・パイプラインの作成」を参照してください。

- 非同期コンシューマの場合、使用するスレッドが少なくなります。非同期コンシューマは、アクティブでない間はスレッドを使用しません。同期コンシューマは、受信呼出しの間スレッドを消費します。その結果、スレッドがアイドル状態になる期間が長くなり、呼出しにブロッキング・タイムアウトが指定されている場合は特に顕著になります。

- サーバーで実行するアプリケーション・コードでは、ほとんどの場合、非同期コンシューマを(通常はMDBを介して)使用するのが最適。非同期コンシューマを使用することで、アプリケーション・コードがサーバー上でブロッキング処理を実行するのを回避できます。ブロッキング処理は、サーバー側スレッドをアイドルにし、デッドロックの原因になることもあります。デッドロックは、ブロッキング処理がすべてのスレッドを消費したときに発生します。ブロッキング処理自体の解除処理に使用するスレッドが残っていないと、ブロッキングを解除することができなくなってしまいます。

詳細については、「メッセージの非同期受信」および「メッセージの同期受信」を参照してください。

永続メッセージと非永続メッセージ

アプリケーションを設計する際は、永続QOSが必要な場合を除いて、メッセージが非永続モードで送信されるように指定してください。非永続モードをお薦めする理由は、同期書込みが無効になっていない限り、永続QOSが原因でパフォーマンスがかなり悪化する場合が多いためです。

注意:
メッセージが誤って永続化されないよう十分に注意してください。設計者がメッセージを非永続モードで送信するつもりで設計しても、アプリケーションが永続メッセージを送信することがあります。

メッセージが本当に非永続であれば、通常のJMSストアには格納されません。誤って永続化されたメッセージがないことを確認するには、消費されていないメッセージがJMSサーバーに蓄積されているときに、JMSストアのサイズが大きくなっているかどうかをチェックします。以下に、メッセージの永続性を決定する条件を優先度の高い順に示します。

- プロデューサの接続の接続ファクトリの構成:

- PERSISTENT (デフォルト)

- NON_PERSISTENT

- QueueSenderおよびTopicPublisherでのJMSプロデューサAPIオーバーライド:

- setDeliveryMode(DeliveryMode.PERSISTENT)

- setDeliveryMode(DeliveryMode.NON_PERSISTENT)

- setDeliveryMode(DeliveryMode.DEFAULT_DELIVERY_MODE) (デフォルト)

- QueueSenderおよびTopicPublisherでのメッセージごとのJMSプロデューサAPIオーバーライド:

- キューの場合は、send()の省略可能なdeliveryModeパラメータ

- トピックの場合は、publish()の省略可能なdeliveryModeパラメータ

- 宛先の構成でのオーバーライド:

- 永続

- 非永続

- 配信しない(デフォルト、オーバーライドしないことを意味します)

- JMSサーバーの構成でのオーバーライド:

- ストアが構成されていない場合は、ターゲットの各WebLogic Serverインスタンス上で使用できるデフォルトの永続ストアを使用することを意味します。

- ストアが構成されている場合はオーバーライドがないことを意味します。

- 恒久サブスクライバのみ:

- サブスクライバがない場合や、トピックに非恒久サブスクライバしかない場合は、メッセージが非永続に格下げされます(非恒久サブスクライバはJMSサーバーの稼動中しか存在しないため、メッセージを永続化する理由がありません)。

- 一時的な宛先:

- 一時的な宛先はそれらをホストするJMSサーバーの稼動中しか存在しないため、メッセージを永続化する理由がありません。WebLogic JMSでは、一時的な宛先のすべてのメッセージが自動的に非永続になります。

恒久サブスクライバが非永続メッセージしか受信しない場合でも、そのJMSサーバーには永続ストアを構成する必要があります。恒久サブスクリプションは、JMS仕様の要件に従って、サーバーの再起動後も継続するように永続化されます。

確認応答とコミットの延期

通常は送信よりも受信のほうに時間がかかるため、複数のメッセージを受信してまとめて確認応答できるようになるまで確認応答を延期して、受信に関わるオーバーヘッドを軽減することを検討してください。トランザクションを使用している場合は、「確認応答」を「コミット」と読み替えてください。

ただし、非恒久サブスクリプションの場合はすでに内部的に最適化されているため、確認応答を延期してもパフォーマンスはあまり向上しません。

非同期リスナーには、確認応答の延期を実装できない場合があります。メッセージ10個ごとに確認応答する非同期リスナーが5個のメッセージしか受信しなかった場合、最後のいくつかのメッセージが確認応答されない可能性があります。考えられる解決策としては、onMessage()コールバック内からの同期非ブロッキング受信を非同期コンシューマにポストさせて、後続のメッセージを受信します。別の解決策としては、wake upリスナーがトリガーされたときに、リスナーの宛先にメッセージを送信するタイマーが開始されるようにします。このメッセージが正しいリスナーに確実に転送されれば、リスナーの宛先が起動してまだ確認応答されていない未処理の作業を完了します。

非恒久サブスクライバでのAUTO_ACKの使用

トランザクション非対応の非恒久トピック・サブスクライバがメッセージのローカル・コピーをクライアント側で格納するように最適化されており、これによって確認応答の発行に伴うネットワーク・オーバーヘッドを軽減しています。この最適化によってパフォーマンスが10 - 20%向上します。パフォーマンスの向上は、サブスクライバの負荷が大きいほどより顕著になります。

この最適化の副作用の1つは、特に数多くのトピック・サブスクライバが同時に存在する場合に、クライアント側でのガベージ・コレクションのオーバーヘッドが大きくなり、メッセージ・サブスクリプションのパフォーマンスが悪化するおそれがあることです。このような悪化を防ぐため、サブスクライバ・クライアントのヒープ・サイズを大きくすることをお薦めします。たとえば、10個のJVMで100個のサブスクライバを同時に存在させるテストでは、各JVMのヒープ・サイズの初期値と最大値を64 MBに設定すれば十分でした。

代替のサービス品質、マルチキャスト、NO_ACKNOWLEDGE

WebLogic JMSでは、パフォーマンスを改善できる代替のサービス品質(QOS)拡張が提供されています。

MULTICAST_NO_ACKNOWLEDGEの使用

非恒久トピック・サブスクライバは、MULTICAST_NO_ACKNOWLEDGEを使用してメッセージをサブスクライブできます。トピックにこのようなサブスクライバがある場合、JMSサーバーはマルチキャスト・モードを使用してこれらのサブスクライバにメッセージをブロードキャストします。マルチキャストでは、サブスクライバごとに1つずつメッセージを処理するのではなく、サブスクライバがいくつあってもネットワークで1つのメッセージを処理するだけでよいため、パフォーマンスが格段に向上し、直線的なスケーラビリティが提供されます。ネットワークが混み合っている場合や、クライアントによるメッセージ処理が遅れている場合は、マルチキャスト・メッセージが消失するおそれがあります。マルチキャスト・メッセージでrecover()やacknowledge()を呼び出しても効果はありません。

注意:
クライアント側では、マルチキャスト・セッションごとに、マルチキャスト・ソケットからメッセージを取り出すための専用のスレッドが1つ必要になります。そのため、JMSクライアント側のスレッド・プール・サイズを増やして調整する必要があります。

このQOS拡張による保証は、非恒久トピック・サブスクリプション用にOracle WebLogic Server以外のベンダーから提供されている一部のJMS実装のデフォルトQOSによる保証と同じレベルです。JMS 1.1仕様では、サブスクライバの準備が整っていない場合に非恒久トピック・メッセージを破棄(削除)することが明確に許可されています。WebLogic JMSでは、非恒久トピック・サブスクリプション用に、JMS 1.1仕様で必須とされているレベルよりも高いレベルのQOSがデフォルトで提供されます。

NO_ACKNOWLEDGEの使用

NO_ACKNOWLEDGE配信モードでは、サーバーからコンシューマにメッセージが送信されますが、確認応答は呼び出されません。かわりに、サーバーはメッセージを事前に確認応答します。この確認応答モードでは、メッセージがすでに確認応答されているため、リカバリを呼び出しても機能しません。このモードを使用すると、確認応答のための追加のネットワーク呼出しによるオーバーヘッドは軽減されますが、サーバー、ネットワーク、またはクライアントで障害が発生した場合にメッセージが消失するおそれがあります。

注意:
このような状況で非同期クライアントがclose()を呼び出すと、非同期パイプライン内のすべてのメッセージが消失します。

NO_ACKNOWLEDGE QOSを使用する非同期コンシューマでは、クラッシュ時に消失するメッセージの数を抑えるために、メッセージ・パイプラインのサイズを小さくすることも検討してください。

マルチスレッド化の回避

JMS仕様(http://www.oracle.com/technetwork/java/jms/index.html)では、close()を呼び出したときを除き、セッション、プロデューサ、コンシューマ、またはメッセージ・メソッドをマルチスレッド化すると動作が不安定になるとされています。このリリースのWebLogic JMSでは、マルチスレッド化されたプロデューサを作成すると、サーバー・インスタンスからJMSExceptionがスローされます。アプリケーションのスレッドが制限されている場合は、プロデューサおよびセッションの数を増やすことを検討してください。

JMSXUserIDプロパティの使用

WebLogic Server 9.0以降では、メッセージ・センダーの認証されたユーザー名が自動的に伝播されるようにJMS接続ファクトリまたは宛先を構成できます。ユーザー名は、JMSXUserIDというjavax.jms.Messageプロパティに配置されます。

アプリケーションでJMSXUserIDプロパティを使用する場合は、次の点に注意してください。

- JMSXUserIDはJMS仕様によって規定されますが、その動作の定義は厳格ではないため、JMSベンダーによって動作が異なる場合があります。

- JMSXUserIDは、アプリケーションがJMSプロデューサの作成に使用するスレッドの資格証明に基づいています。JMS送信呼出し時にスレッド上にある資格証明からは派生しません。

- JMSは、アプリケーションがJMSXUserIDを直接設定しようとする試行を無視またはオーバーライドします(たとえば、javax.jms.Message.setXXXProperty()は機能しません)。

- JMSメッセージは署名または暗号化されません(RMI/EJB呼出しと同様)。したがって、JMSXUserIDを完全に保護して転送するには、セキュア・プロトコル(t3sやhttpsなど)を使用してメッセージを送信する必要があります。

- WebLogicストア・アンド・フォワード・エージェントは、JMSXUserIDを伝播しません(nullに設定します)。

- WebLogicメッセージング・ブリッジは、メッセージング・ブリッジが9.0以降のJMSサーバーに転送し、メッセージのプロパティを保持するように構成されている場合、ソース宛先のメッセージのJMSXUserIDを伝播します。それ以外の場合は、転送されたメッセージはユーザー名を含まないか、ブリッジ・センダーによって使用されるユーザー名を含みます。後者の動作は、ブリッジ・センダーの接続ファクトリと宛先の構成によって決定されます。

- WebLogic JMSのWLMessageProducer.forward()拡張を使用すると、受信したメッセージのJMSXUserIDを転送可能です。

注意:
9.0より前のWebLogic JMSクライアントのJMSXUserID Interopの動作は未定義です。

接続ファクトリまたは宛先のJMSXUserIDプロパティの設定手順については、管理コンソール・オンライン・ヘルプの以下のトピックを参照してください。

- 「接続ファクトリのセキュリティ・パラメータの構成」

- 「キューに関する詳細なパラメータの構成」

- 「トピックに関する詳細なパラメータの構成」

- 「共通分散キュー - 詳細パラメータの構成」

- 「共通分散トピック - 詳細パラメータの構成」

パフォーマンスとチューニング

アプリケーションを最大限に活用する方法については、『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「WebLogic JMSのチューニング」のWebLogic JMSで利用できるパフォーマンス・チューニング機能を実装します。

4 WebLogic JMSをEJBやサーブレットと組み合せて使用するために拡張されたサポート

この章では、Java EE標準を拡張し、WebLogic JMSまたはサード・パーティのJMSプロバイダを使用して、EJBコンテナおよびサーブレット・コンテナに簡単にアクセスできるようにするWebLogic Serverの拡張機能(JMSラッパーなど)について説明します。実際に、JMSラッパーのサポートを実装することは、EJBまたはサーブレットの内部からWebLogic JMSメッセージを送信する最良の方法です。

- WebLogic JMSラッパーの有効化

- ラッピングとプーリングの無効化

- JMSラッパーの内部での処理

- プールによるパフォーマンスの向上

- 外部JMSプロバイダへのアクセスの簡略化

- JMSラッパー関数の例

WebLogic JMSラッパーの有効化

WebLogic Serverでは、JMSラッパーを用いることで、EJBやサーブレットなどのJava EEコンポーネント内部でWebLogic JMSを簡単に使用できるようにするとともに、次のような多数の拡張されたユーザービリティ機能とパフォーマンス機能を提供しています。

- JMS接続オブジェクトおよびセッション・オブジェクトの自動プーリング(およびメッセージ・プロデューサ・オブジェクトの一定のプーリング)

- WebLogic JMSの実装と、2フェーズ・コミット・トランザクション(XAプロトコル)をサポートするサード・パーティのJMSプロバイダに対応した自動トランザクション登録

- JMS接続のテストおよび接続失敗後の再接続

- EJBコンテナまたはサーブレット・コンテナによって管理されるセキュリティ資格証明

次の項では、WebLogic JMSラッパーの使用方法について説明します。

- EJBまたはサーブレットのデプロイメント記述子におけるJMSオブジェクトのリソースとしての宣言

- デプロイメント記述子ファイルでパッケージ化JMSアプリケーション・モジュールを参照する

- アノテーションを使用したJMS宛先および接続ファクトリの宣言

- トランザクションXAインタフェースの回避

EJBまたはサーブレットのデプロイメント記述子におけるJMSオブジェクトのリソースとしての宣言

次の項では、JMSオブジェクトのリソースとしての宣言について説明します。

- デプロイメント記述子を使用したラップJMSファクトリの宣言

- デプロイメント記述子を使用したJMS宛先の宣言

EJBのパッケージ化の詳細は、『Oracle WebLogic Server Enterprise JavaBeansのプログラミング』のEnterprise JavaBeansの実装に関する項を参照してください。サーブレットのプログラミングの詳細は、『Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発』のサーブレットの作成と構成に関する項を参照してください。

デプロイメント記述子を使用したラップJMSファクトリの宣言

注意:
新しいアプリケーションは、デプロイメント記述子ではなくEJB 3.0アノテーションを使用する場合があります。アノテーションについては、「アノテーションを使用したJMS宛先および接続ファクトリの宣言」で説明します。

ejb-jar.xmlまたはweb.xmlファイルにresource-ref要素を定義することによって、EJBまたはサーブレットの一部としてJMS接続ファクトリを宣言できます。この処理によって、「ラップされた」JMS接続ファクトリが作成され、「プールによるパフォーマンスの向上」で説明している、より高度なセッション・プーリング、自動トランザクション登録、接続のモニター、およびコンテナ管理によるセキュリティ機能のメリットを得ることができます。

このような接続ファクトリ要素の例を次に示します。

<resource-ref>
<res-ref-name>jms/QCF</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

この要素は、JMSオブジェクトQueueConnectionFactoryをJNDIの次の場所にバインドすることを宣言しています。

java:comp/env/jms/QCF

このJNDI名は、resource-refを宣言したEJBまたはサーブレットのコンテキスト内部でのみ有効です。JNDIコンテキストjava:comp/envはこのコンテキストを表します。

この要素以外にも、その場所に配置するJMS接続ファクトリをJava EEコンテナに指示するために、対応するresource-description要素がweblogic-ejb-jar.xml(EJB用)ファイルまたはweblogic.xml(サーブレット用)ファイルになければなりません。次に例を示します。

<resource-description>
<res-ref-name>jms/QCF</res-ref-name>
<jndi-name>weblogic.jms.ConnectionFactory</jndi-name>
</resource-description>

ここで指定する接続ファクトリは、グローバルJNDIツリーにすでに存在している必要があります。(この例では、組込みのWebLogic JMSサーバーを使用した場合に自動的に作成されるデフォルトJMS接続ファクトリの1つを使用しています。)同じクラスタにある別のWebLogic JMS接続ファクトリを使用するには、その接続ファクトリのJNDI名をjndi-name要素の内側に追加します。別のベンダーまたは別のWebLogic Serverクラスタから接続ファクトリを使用するには、外部JMSサーバーを作成します。

resource-description要素に指定したJNDI名が正しくない場合でも、アプリケーションはデプロイされます。ただし、接続ファクトリを使用しようとしたときにエラーが返されます。

デプロイメント記述子を使用したJMS宛先の宣言

注意:
新しいアプリケーションは、デプロイメント記述子ではなくEJB 3.0アノテーションを使用する場合があります。アノテーションについては、「アノテーションを使用したJMS宛先および接続ファクトリの宣言」で説明します。

JMSキューまたはトピックの宛先をJNDIツリーjava:comp/env/jmsにバインドすることもできます。そのためには、その宛先をejb-jar.xmlまたはweb.xmlのデプロイメント記述子にresource-env-ref要素として宣言します。トランザクション登録、プーリング、接続モニターの機能は、宛先ではなく接続ファクトリ内で実行されます。ただし、この機能は一貫性を維持し、特定のWebLogic Server構成に対するアプリケーションの依存性を低減するために有用です。対応するresource-env-refの記述を変更するだけで簡単に宛先を変更でき、ソース・コードを再コンパイルする必要がないからです。

このようなキュー宛先要素の例を次に示します。

<resource-env-ref>
<resource-env-ref-name>jms/TESTQUEUE</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>

この要素は、JMS宛先オブジェクトQueueをJNDIの次の場所にバインドすることを宣言しています。

java:comp/env/jms/TESTQUEUE

参照される接続ファクトリと同様に、このJNDI名は、resource-refを宣言したEJBまたはサーブレットのコンテキスト内部でのみ有効です。

また、対応するresource-env-description要素をweblogic-ejb-jar.xmlまたはweblogic.xmlファイルに定義する必要があります。これによって間接レイヤーが提供され、対応するresource-env-refデプロイメント記述子を変更するだけで、参照される宛先を簡単に変更できます。

<resource-env-description>
<resource-env-ref-name>jms/TESTQUEUE</resource-env-ref-name>
<jndi-name>jmstest.destinations.TESTQUEUE</jndi-name>
</resource-env-description>

ここで指定するキューまたはトピック宛先は、グローバルJNDIツリーにすでに存在している必要があります。宛先が存在しない場合でも、アプリケーションはデプロイされますが、宛先を使用しようとすると例外がスローされます。

デプロイメント記述子ファイルでパッケージ化JMSアプリケーション・モジュールを参照する

JMSモジュールをエンタープライズ・アプリケーションにパッケージ化する際は、該当するすべてのJava EEアプリケーション・コンポーネントの記述子ファイルで、モジュール内のJMSリソースを参照する必要があります。以下に、該当する記述子ファイルの例を挙げます。

- WebLogicエンタープライズ記述子ファイル(weblogic-application.xml)

- WebLogicデプロイメント記述子ファイル(weblogic-ejb-jar.xml、weblogic.xmlなど)

- EJB (ejb-jar.xml)ファイル、WebApp (web.xml)ファイルなど、すべてのJava EE記述子ファイル

weblogic-application.xml記述子でアプリケーション・モジュールを参照する

エンタープライズ・アプリケーションにJMSモジュールを含める際は、アプリケーションと一緒にパッケージ化されたweblogic-application.xml記述子ファイルで、JMSタイプのモジュール要素として各JMSモジュールを列挙し、Java EEアプリケーションのルートからの相対パスを指定する必要があります。次に、WorkflowsというJMSモジュールへの参照の例を示します。

<module>
<name>Workflows</name>
<type>JMS</type>
<path>jms/Workflows-jms.xml</path>
</module>

WebLogicアプリケーションでJMSリソースを参照する

EJB (weblogic-ejb-jar.xml)、WebApp (weblogic.xml)など、weblogic-で始まるすべての記述子ファイルでは、JMSモジュールの名前の後ろにシャープ記号(#)の区切り文字を付加し、その後ろにモジュール内のリソースの名前を指定します。たとえば、OrderQueueというキューを含むWorkflowsというJMSモジュールであれば、Workflows#OrderQueueという名前になります。

<resource-env-description>
<resource-env-ref-name>jms/OrderQueue</resource-env-ref-name>
<resource-link>Workflows#OrderQueue</resource-link>
</resource-env-description>

<resource-link>要素はWebLogic Server固有の要素で、JMSモジュール内に定義されたリソースを他の様々なJava EEアプリケーション・コンポーネントから参照(リンク)するために使用します。

Java EEアプリケーションでJMSリソースを参照する

JMSモジュール内に指定されたJMS接続ファクトリ・リソースのname要素は、これを参照するEJBまたはWebAppアプリケーション記述子ファイルに定義されたres-ref-name要素と一致させる必要があります。res-ref-name要素により、java:comp/envで使用するリソース名が、EJBから参照されるモジュールにマップされます。

JMSモジュール内に指定されたキュー宛先リソースおよびトピック宛先リソースのname要素の場合は、これを参照するモジュール記述子ファイルに定義されたres-env-ref要素と一致させる必要があります。

この名前は、EJBまたはWebアプリケーション・モジュールで参照されるリソースと、JMSモジュールで定義されたリソースをリンクさせるためのものです。例:

<resource-ref>
<res-ref-name>jms/OrderQueueFactory</res-ref-name>
<res-type>javax.jms.ConnectionFactory</res-type>
</resource-ref>
<resource-env-ref>
<resource-env-ref-name>jms/OrderQueue</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>

アノテーションを使用したJMS宛先および接続ファクトリの宣言

WebLogic Server 10.0以降のリリースでは、アノテーションを使用してメタデータを構成するEJB 3.0プログラミング・モデルをサポートするため、デプロイメント記述子は必要ありません。『Oracle WebLogic Server Enterprise JavaBeansバージョン3.0のプログラミング』の「EJB 3.0で使用される標準のJDKアノテーション」の説明に従い、@Resourcesアノテーションを使用してJMSオブジェクトを宣言できます。

クラスにリソース依存関係を注入する

クラスに@Resourceを適用する場合、リソースはcomp/envコンテキストで入手できます。次に、EJB、MDB、サーブレットなどのJava EEアプリケーションにWebLogic JMS宛先および接続ファクトリのリソースを注入する方法の例を示します。

次に、ラップJMSプーリング・アノテーションの例を示します。

例4-1 ラップJMSプーリング・アノテーションの例

.
.
.
// The "name=" or "type=" are not always required,
// "mappedName=" is usually sufficient.
@Resource(name="ReplyQueue",
type=javax.jms.Queue.class,
mappedName="jms/ReplyQueue") Destination rq;
.
.
.
@Resource(name="ReplyConnectionFactory",
type=javax.jms.ConnectionFactory.class,
mappedName = "jms/ConnectionFactory") ConnectionFactory cf;
.
.
.

非注入EJB 3.0リソース参照アノテーション

注入されたリソース依存関係は、ホストEJBまたはサーブレットがインスタンス化されると解決されます。これは、次の理由により望ましくない場合があります。

- インジェクションにより、コンテナがデプロイ時に参照を解決しようとする場合、アプリケーションの正常なデプロイメントが妨げられることがあります。

- アプリケーションが最初に呼び出されるまで、参照の解決を延期する場合があります。

非注入リソース参照を設定するには、クラス定義の上に@Resourcesアノテーションを配置する方法があります。アプリケーションは、Beanコンテキストで参照をルックアップして実行時にこのような参照を解決できます。ベスト・プラクティスでは、繰り返されるルックアップのオーバーヘッドを回避するために、Beanまたはサーブレットで結果をキャッシュする必要もあります。例:

例4-2 非注入リソースの例

.
.
.
@Resources ({
@Resource(name="targetCFRef",
mappedName="TargetCFJNDIName",
type=javax.jms.ConnectionFactory.class),

@Resource(name="targetDestRef",
mappedName="TargetDestJNDIName",
type=javax.jms.Destination.class)
})

@Stateless(mappedName="StatelessBean")
public class MyStatelessBean implements MyStateless {

@Resource
private SessionContext sctx;   // inject the bean context

private ConnectionFactory targetCF;
private Destination targetDest;

public void completeWorkOrder() {

// Lookup the JMS resources and cache for re-use.  Note that a
// "java:/comp/env" prefix isn't needed for EJB3.0 bean contexts.

if (targetCF == null) targetCF =
(javax.jms.ConnectionFactory)sctx.lookup("targetCFRef");

if (targetDest == null) targetDest =
(javax.jms.Destination)sctx.lookup("targetDestRef");
.
.
.

完全な例については、第4章「インジェクションを使用しないEJB 3.0ラッパー」を参照してください。

トランザクションXAインタフェースの回避

リソース・ラッピングでは、javax.jms XAのトランザクションXAインタフェースを使用しないでください。JMSコードがトランザクション・コンテキスト内部で使用される場合、コンテナはそれらを内部的に使用します。これにより、EJBアプリケーション・コードは、デプロイメント記述子を変更するだけでトランザクションが存在する環境または非トランザクション環境でEJBを実行できます。

ラッピングとプーリングの無効化

リソース参照を活用し、リソース参照のラッピングとプーリングを無効にすることが望ましい場合があります。無効にするには、デプロイメント記述子の方法を使用しますが、接続ファクトリのスタンザresource-refでres-typeをjava.lang.Object.classに変更します。アノテーションを使用して、ラッピングとプーリングを無効にする方法は現在承認されていません。

JMSラッパーの内部での処理

この節では、WebLogic ServerがJMSオブジェクトを包むラッパーを作成するときに実際に行われる処理について説明します。たとえば、「Java EEコンテナによるJMSメッセージの送信」にあるサンプル・コードでは、接続ファクトリがJNDIツリーjava:comp/envからルックアップされたため、実際のJMS接続ファクトリではなくWebLogic固有のラッパー・クラスのインスタンスが返されています。このラッパー・オブジェクトはJMSプロバイダへの特定の呼出しをインターセプトし、正しいJava EEの動作を挿入します。これについて以下の節で説明します。

- トランザクションの自動登録

- コンテナ管理のセキュリティ

- 接続テスト

- Java EEの準拠

- プールされたJMS接続オブジェクト

- プールされた接続のモニター

トランザクションの自動登録

この機能は、WebLogic JMSの実装に対して、または2フェーズ・コミット・トランザクション(XAプロトコル)をサポートするサード・パーティのJMSプロバイダに対して有効です。ラップされたJMS接続のトランザクション・コンテキスト内部でメッセージが送受信されるとき、メッセージの送受信に使用されているJMSセッションがJMSプロバイダのXA機能によってトランザクションに自動的に登録されます。コンテナ管理によるトランザクションを有効にしてEJB内部でJMSコードを呼び出し、トランザクションを暗黙的に開始したか、Bean管理のトランザクションをサポートするサーブレットまたはEJBで、UserTransactionインタフェースを使用してトランザクションを手動で開始したかにかかわらず、この処理が行われます。

ただし、EJBまたはサーブレットがトランザクション・コンテキストの内部でメッセージの送受信を試みた場合、JMSプロバイダがXAをサポートしていないと、send()またはreceive()呼出しは以下の例外をスローします。

[J2EE:160055] Unable to use a wrapped JMS session in the transaction because two-phase commit is not available.

したがって、トランザクション内部でメッセージを送受信するXAをサポートしていないJMSプロバイダを使用する場合は、トランザクション・モードとしてNotSupportedを指定してEJBを宣言するか、いずれかのJTA APIを使用してトランザクションを中断します。

コンテナ管理のセキュリティ

WebLogic JMSでは、EJBコンテナまたはサーブレット・コンテナを呼び出したときにスレッド上に存在するセキュリティ資格証明が使用されます。ただし、外部JMSプロバイダでは、ejb-jar.xmlまたはweb.xmlファイルでresource-ref要素を使用してJMS接続ファクトリを宣言する場合、res-authというオプションのサブ要素があります。この要素には次に示す2つのオプションのいずれかを設定できます。

Container - res-auth要素にContainerを設定すると、JMSプロバイダに対するセキュリティはJava EEコンテナによって管理されます。この場合、JMS接続ファクトリが外部JMS接続ファクトリ構成MBeanを使用してJNDIツリーにマップされた後、MBeanのユーザー名とパスワードが使用されます。それ以外の場合、WebLogic Serverはユーザー名またはパスワードの指定なしでプロバイダに接続し、createConnection()メソッドを使用して接続ファクトリにユーザー名とパスワードを渡すとエラーをスローします。

Application - res-auth要素にApplicationを設定すると、MBeanのユーザー名またはパスワードは無視されます。そのかわりに、アプリケーション・コードでは、JMS接続ファクトリのcreateConnection(String userName, String password)メソッドに対してユーザー名とパスワードを指定するか、ユーザー名またはパスワードが必要ない場合はそれらを指定しないcreateConnection()のバージョンを使用する必要があります。

接続テスト

JMSラッパー・クラスは、JMSプロバイダに対して確立された各接続をモニターします。これは次の2つの方法で行われます。

- JMSオブジェクトExceptionListenerを接続に登録します。

- 一時キューまたはトピックにメッセージを送信し、それを再度受信することによって、2分ごとに接続をテストします。

Java EEの準拠

Java EE仕様では、特定のJMS API呼出しをJava EEアプリケーションの内部で実行してはならないとされています。制約違反があった場合、JMSラッパーは以下の例外をスローして制約を適用します。

- 接続オブジェクトに対しては、createConnectionConsumer()、createDurableConnectionConsumer()、setClientID()、setExceptionListener()、stop()の各メソッドを呼び出してはいけません。

- セッション・オブジェクトに対しては、getMessageListener()およびsetMessageListener()メソッドを呼び出してはいけません。

- コンシューマ・オブジェクト(QueueReceiverまたはTopicSubscriberオブジェクト)では、getMessageListener()およびsetMessageListener()メソッドを呼び出してはいけません。

さらに、createSession()メソッドと、関連するcreateQueueSession()およびcreateTopicSession()メソッドは扱いが異なります。createSession()メソッドには、「確認応答」モードと「トランザクション化」フラグの2つのパラメータを指定します。EJBの内部で使用した場合、これらの2つのパラメータは無視されます。トランザクションが存在する場合は、JMSセッションがトランザクションに登録されます(「トランザクションの自動登録」を参照)。存在しない場合は登録されません。デフォルトでは、確認応答モードは「自動確認」に設定されます。この動作はJava EE仕様で規定されています。

注意:
この仕様のため、EJB内部からのメッセージ受信はいっそう難しくなりますが、EJB内部からメッセージを受信するには、MDBを使用することをお薦めします(『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』を参照)。

サーブレットの内部では、createQueueSession()およびcreateTopicSession()のパラメータが正常に処理され、様々なメッセージ確認応答モードがすべて使用できます。

プールされたJMS接続オブジェクト

「Java EEコンテナによるJMSメッセージの送信」に示した例のようなコードをより効率的にするために、JMSラッパーは様々なセッション・オブジェクトをプールします。プールされたJMS接続は、デプロイメント記述子でresource-ref要素を使用してJMS接続ファクトリを定義しているEJBおよびサーブレットによって使用されるセッション・プールです(「デプロイメント記述子を使用したラップJMSファクトリの宣言」を参照)。

プールされた接続のモニター

プールされた接続は、管理コンソールを使用して監視できます。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJMSサーバー: モニター: アクティブなプール済接続に関する項を参照してください。

プールによるパフォーマンスの向上

JMSラッパーによって接続オブジェクトおよびその他のオブジェクトが自動的にプールされるため、「Java EEコンテナによるJMSメッセージの送信」に示すようにコードを記述すると効率的です。この例では、メッセージを送信するたびに接続ファクトリ、接続、およびセッションの各オブジェクトが作成されます。実際には、これら3つのクラスは連携して動作し、例のような使い方をした場合、これらのオブジェクトが実行する動作はほとんどプールからセッション・オブジェクトを取得することだけです。

- セッション・オブジェクトのプールによるJNDIルックアップの高速化

- キャッシングによるオブジェクト作成の高速化

- 適切なトランザクション・モードの登録

セッション・オブジェクトのプールによるJNDIルックアップの高速化

接続ファクトリ・オブジェクトと宛先オブジェクトのJNDIルックアップでは、パフォーマンスの負荷が大きくなる可能性があります。宛先オブジェクトが外部JMS宛先MBeanを指していて、そのためローカルでないJNDIプロバイダをルック・アップする場合は、特にその可能性があります。接続ファクトリ・オブジェクトと宛先オブジェクトはスレッド・セーフであるため、作成時にEJBまたはサーブレットの内部で1回ルック・アップすることができます。毎回ルック・アップを行う必要がなく、時間を節約できます。

サーブレットの内部では、このようなルックアップをinit()メソッドの内部で実行できます。次に接続ファクトリ・オブジェクトと宛先オブジェクトをインスタンス変数に割り当て、メッセージ送信時に再利用できます。

EJBの内部では、このようなルックアップをejbCreate()メソッドの内部で実行し、インスタンス変数に割り当てることができます。セッションBeanの場合、Beanの各インスタンスに専用のコピーがあります。ステートレス・セッションBeanはプールされるので、このメソッドは非常に効率的でもあります(さらにJava EE仕様完全準拠です)。これは、JMS接続オブジェクトをプールすることによって、ルックアップ発生回数が大幅に削減されるからです。(これらのオブジェクトをEJBクラスの静的メンバーにキャッシュすることもできますが、Java EE仕様では推奨されていません。)

ただし、これらのオブジェクトをejbCreate()またはinit()メソッドの内部にキャッシュする場合は、エラーが発生したときにオブジェクトを再作成する方法をEJBまたはサーブレットが備えている必要があります。この方法が必要な理由は、WebLogic JMSのように一部のJMSプロバイダは、サーバー障害発生後に宛先オブジェクトを無効化するためです。そのため、EJBがServer Aで動作していて、JMSがServer Bで動作している場合、Server AのEJBは、Server Bのオブジェクトをサーバー回復後に再度JNDIルックアップしなければなりません。「PoolTestBean.java」の例は、このキャッシング後の再ルックアップ処理を適切に実行するサンプルEJBを示しています。

キャッシングによるオブジェクト作成の高速化

接続ファクトリ・オブジェクトや宛先オブジェクトのプールが確立された後、接続オブジェクト、セッション・オブジェクト、プロデューサ・オブジェクトなどの他のオブジェクトをejbCreate()メソッドの内部でキャッシュしようとする場合があります。この方法は機能しますが、必ずしも最も効率的な解決策ではありません。基本的に、この方法ではセッション・オブジェクトをキャッシュから削除し、特定のEJBに永続的に割り当てます。これに対し、設計どおりにJMSラッパーを使用すると、他のEJBおよびサーブレットもセッション・オブジェクトを共有できます。さらに、ラッパーは、JMSプロバイダとの通信障害が発生した場合にJMS接続の再確立と新しいセッション・オブジェクトの作成を試みますが、セッション・オブジェクトを独自にキャッシュすると、この機能は動作しません。

適切なトランザクション・モードの登録

JMSのsend()またはreceive()処理をトランザクション内部で実行する場合、EJBまたはサーブレットは自動的にJMSプロバイダをトランザクションに登録します。トランザクションは、コンテナ管理のトランザクションを持つEJBまたはサーブレットの内部で自動的に開始するか、UserTransactionインタフェースを使用して明示的に開始できます。いずれの場合も、コンテナはJMSプロバイダを自動的に登録します。ただし、EJBまたはサーブレットが使用する基底のJMS接続ファクトリがXAをサポートしていない場合、コンテナは例外をスローします。

トランザクション登録の実行はオーバーヘッドを伴います。さらに、XA接続ファクトリを使用していても、send()またはreceive()メソッドをトランザクションの外部で呼び出す場合は、どのJMSプロバイダを使用するかにかかわらず処理が適切に実行されるように、コンテナはJTAトランザクションを作成してsend()またはreceive()メソッドをラップする必要があります。これは1フェーズのみのコミットですが、サーバーの処理速度が低下する場合があります。

したがって、JMSリソースを非トランザクション形式で使用するEJBまたはサーブレットを記述する場合、最適な方法は、XAをサポートするように構成されていないJMS接続ファクトリを使用することです。

外部JMSプロバイダへのアクセスの簡略化

この項では、管理コンソールでの外部JMSプロバイダのサポートについて簡単に説明します。詳細は、『Oracle WebLogic Server JMSの構成と管理』の「外部JMSプロバイダへのアクセス」を参照してください。この機能を使用すると、外部JMSプロバイダ(別のクラスタまたはドメインにあるWebLogic Serverのリモート・インスタンスを含む)を簡単にマップして、ローカルのJNDIツリーにローカルのJMSオブジェクトとして表示できます。

外部JMSプロバイダの別の機能セットを使用すると、サード・パーティのJNDIプロバイダ内のJMS接続ファクトリまたは宛先オブジェクトと、ローカルのWebLogic Server内部のオブジェクトとのシンボリック・リンクを作成できます。この機能を使用すると、ローカルのWebLogic JNDIツリーで別のクラスタまたはドメインにあるWebLogic Serverのリモート・インスタンスを参照することもできます。

このタスクに使用する3つのシステム・モジュールMBeanがあります。

- 外部サーバー - 初期コンテキスト・ファクトリ、URL、追加パラメータなど、リモートのJNDIプロバイダに関する情報を格納します。これは、外部接続ファクトリMBeanと外部宛先MBeanの親です。独立したWebLogic Serverまたはクラスタをターゲットとすることができます。詳細は、Oracle WebLogic Server MBeanリファレンスのForeignServerBeanに関する項を参照してください。

- 外部接続ファクトリ - 外部接続ファクトリを表します。リモートのJNDIプロバイダ内の接続ファクトリの名前、その接続ファクトリのマップ先となるサーバーのJNDIツリー内の場所、およびオプションのユーザー名とパスワードを格納します。ユーザー名とパスワードは、外部接続ファクトリをEJBまたはサーブレットのresource-referenceの内側に、Containerモードauthenticationを指定して使用している場合にのみ、使用されます。その場合、親の外部接続ファクトリMBeanの対象となっている各WebLogic Serverインスタンスに非レプリケートJNDIオブジェクトが作成されます(クラスタの各ノードにJNDIオブジェクトを作成するには、そのクラスタを親MBeanの対象にします)。詳細は、Oracle WebLogic Server MBeanリファレンスのForeignConnectionFactoryBeanに関する項を参照してください。

- 外部宛先 - 外部宛先を表します。外部JNDIプロバイダでルックアップする名前と、その名前をローカルのサーバーにマップする名前を格納します。

JMSラッパー関数の例

- JMSラッパー関数の例

- Java EEコンテナによるJMSメッセージの送信

- 依存関係インジェクション

- インジェクションを使用しないEJB 3.0ラッパー

JMSラッパー関数の例

次のファイルは、EJBが呼び出されたときにWebLogic JMSラッパー関数を使用してトランザクション・メッセージ(sendXATransactional)を送信する、簡単なステートレスEJBセッションBeanを記述しています。この例ではセッションBeanを使用していますが、同じXML記述子とBeanクラスを(ほとんど変更を加えることなく)メッセージドリブンBeanにも使用できます。

- ejb-jar.xml

- weblogic-ejb-jar.xml

- PoolTest.java

- PoolTestHome.java

- PoolTestBean.java

ejb-jar.xml

このセクションにはEJBコンポーネントを記述します。この節に示されている「JMSラッパー」コード・スニペットでは、ラップされたJMS接続ファクトリ(QueueConnectionFactory)と参照されるJMS宛先(TESTQUEUE)のresource-refおよびresource-env-ref要素をこのセクションで宣言しています。

<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee  http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
<?xml version="1.0"?>
...
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>PoolTestBean</ejb-name>
<home>weblogic.jms.pool.test.PoolTestHome</home>
<remote>weblogic.jms.pool.test.PoolTest</remote>
<ejb-class>weblogic.jms.pool.test.PoolTestBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>

<resource-ref>
<res-ref-name>jms/QCF</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

<resource-env-ref>
<resource-env-ref-name>jms/TESTQUEUE</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>
</session>
</enterprise-beans>

<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>PoolTestBean</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>

weblogic-ejb-jar.xml

このセクションでは、キュー接続ファクトリおよびキュー宛先に対応するresource-description要素を宣言します。この要素は、その位置に格納するJMS接続ファクトリと宛先をJava EEコンテナに指示します。

<!DOC<weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/920" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/920 http://www.bea.com/ns/weblogic/920/weblogic-ejb-jar.xsd">

...
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>PoolTestBean</ejb-name>
<stateless-session-descriptor>
<pool>
<max-beans-in-free-pool>8</max-beans-in-free-pool>
<initial-beans-in-free-pool>2</initial-beans-in-free-pool>
</pool>
</stateless-session-descriptor>

<resource-description>
<res-ref-name>jms/QCF</res-ref-name>
<jndi-name>weblogic.jms.XAConnectionFactory</jndi-name>
</resource-description>
<resource-env-description>
<res-env-ref-name>jms/TESTQUEUE</res-env-ref-name>
<jndi-name>TESTQUEUE</jndi-name>
</resource-env-description>
<jndi-name>PoolTest</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>

PoolTest.java

このセクションでは、PoolTest Beanに使用するリモート・インタフェースを定義します。sendXATransactionalというメソッドを1つ宣言します。

package weblogic.jms.pool.test;

import java.rmi.*;
import javax.ejb.*;
public interface PoolTest extends EJBObject
{
public String sendXATransactional(String text)
throws RemoteException;
}

PoolTestHome.java

このセクションでは、PoolTest Beanに使用する「ホーム」インタフェースを定義します。EJB仕様ではこのセクションは必須です。

package weblogic.jms.pool.test;

import java.rmi.*;
import javax.ejb.*;

public interface PoolTestHome
extends EJBHome
{
PoolTest create()
throws CreateException, RemoteException;
}

PoolTestBean.java

このセクションでは実際のEJBコードを定義します。sendXATransactionalメソッドが呼び出されたときは常にメッセージを送信します。

package weblogic.jms.pool.test;

import java.lang.reflect.*;
import java.rmi.*;
import javax.ejb.*;
import javax.jms.*;
import javax.naming.*;
import javax.transaction.*;

public class PoolTestBean
extends PoolTestBeanBase
implements SessionBean
{
private SessionContext context;
private QueueConnectionFactory qcf;
private Queue destination;

public void ejbActivate()
{
}

public void ejbRemove()
{
}

public void ejbPassivate()
{
}

public void setSessionContext(SessionContext ctx)
{
context = ctx;
}

private void lookupJNDIObjects()
throws NamingException
{
InitialContext ic = new InitialContext();
try {
qcf =
(QueueConnectionFactory)ic.lookup
("java:comp/env/jms/QCF");
destination =
(Queue)ic.lookup("java:comp/env/jms/TESTQUEUE");
} finally {
ic.close();
}
}

public void ejbCreate()
throws CreateException
{
try {
lookupJNDIObjects();
} catch (NamingException ne) {
throw new CreateException(ne.toString());
}
}

public String sendXATransactional(String text)
throws RemoteException
{
String id = "Not sent yet";
try {
if ((qcf == null) || (destination == null)) {
lookupJNDIObjects();
}
QueueConnection connection = qcf.createQueueConnection();
try {
QueueSession session = connection.createQueueSession
(false, 0);
TextMessage message = session.createTextMessage
(text);
QueueSender sender = session.createSender(destination);
sender.send(message);
id = message.getJMSMessageID();
} finally {
connection.close();
}
} catch (Exception e) {
// Invalidate the JNDI objects if there is a failure
// this is necessary because the destination object
// may become invalid if the destination server has
// been shut down
qcf = null;
destination = null;
throw new RemoteException("Failure in EJB: " + e);
}
return id;
}
}

Java EEコンテナによるJMSメッセージの送信

JMS接続ファクトリと宛先のリソースを宣言すると、そのリソースを使用して、EJBまたはサーブレット内部でJMSメッセージの送受信を行うことができます。次の項では、メッセージの送信方法の例を示します。

comp/envの使用

次のコード・フラグメントは、java:comp/env JNDIツリーにマップする場合にメッセージを送信します。

例4-3 comp/envを使用したメッセージの送信

.
.
.

InitialContext ic = new InitialContext();
QueueConnectionFactory qcf =
(QueueConnectionFactory)ic.lookup("java:comp/env/jms/QCF");
Queue destQueue =
(Queue)ic.lookup("java:comp/env/jms/TESTQUEUE");
ic.close();
QueueConnection connection = qcf.createQueueConnection();
try {
QueueSession session = connection.createQueueSession(0, false);
QueueSender sender = session.createSender(destQueue);
TextMessage msg = session.createTextMessage("This is a test");
sender.send(msg);
} finally {
connection.close();
}

これはJava EE仕様に準拠した標準的なコードであり、Java EEを適切にサポートする任意のEJBまたはサーブレット製品上で動作します。違いは、WebLogic Serverでは様々なオブジェクトが背後でプールされるため、さらに効率的に実行できる点です(「プールされたJMS接続オブジェクト」を参照)。

このサンプル・コードでは、try...finallyブロックを使用して、ブロックの内側にある文で例外が発生した場合でも、JMS接続オブジェクトのclose()メソッドが確実に実行されるようにしている点に注意してください。接続プーリングが行われていない場合は、接続をクローズするため、およびサーバー・リソースの消費を避けるために、このブロックが必要です。しかし、WebLogic Serverはこのコードによって作成されたオブジェクトの一部をプールに入れるため、close()を呼び出すことがさらに重要です。そうしないと、EJBコンテナまたはサーブレット・コンテナに、オブジェクトをプールにいつ戻すかが通知されません。

また、JMS APIのトランザクションXA拡張機能はこのサンプル・コードでは使用されていません。かわりに、トランザクション・コンテキスト内でJMSコードが使用されている場合、コンテナはそれらの拡張機能を内部的に使用します。しかし、XAが内部的に使用されるかどうかにかかわらず、ユーザーが記述するコードは同じであり、JMS XAクラスを使用しません。これはJava EEの仕様です。EJBコードをこのように記述すると、デプロイメント記述子を変更するだけで、トランザクションが存在する環境または非トランザクション環境でEJBを実行できます。

注意:
ラップされたJMS接続ファクトリは、resource-ref機能を使用して取得し、java:comp/env/jms JNDIツリー・コンテキストを使用してルックアップします。EJBでjavax.jms XAのトランザクションXAインタフェースを使用することはできません。

依存関係インジェクション

次のコード・フラグメントは、変数に依存関係インジェクションを使用した場合にメッセージを送信します。

例4-4 依存関係インジェクションを使用したメッセージの送信

package test;
// Example injected annotation.
import javax.annotation.Resource;
import javax.ejb.*;
import javax.jms.*;

@Stateless(mappedName="StatelessBean")
public class MyStatelessBean implements MyStateless {
@Resource(mappedName="myDestJNDIName")
private Destination dest;

@Resource(mappedName="weblogic.jms.XAConnectionFactory")
private ConnectionFactory connectionFactory;

public void completeWorkOrder() {
Connection con =  null;
Session session = null;
MessageProducer sender = null;
try {
System.out.println("completeWorkOrder called!");
con = connectionFactory.createConnection();
session = con.createSession(true, Session.AUTO_ACKNOWLEDGE);
sender = session.createProducer(null);
Message message = session.createTextMessage("work order complete!");
sender.send(dest, message);
} catch(Exception e) {
throw new EJBException("Exception sending message:   " + e, e);
} finally {
try {
if (con != null) con.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}

インジェクションを使用しないEJB 3.0ラッパー

この例では、注入されないリソースを参照するMDBのEJB 3.0アノテーションを示します。参照は、MDBインスタンスがインスタンス化されるときではなく、MDBが呼び出されると実行時に解決されます。

例4-5 非注入MDBの例

package test;

import javax.annotation.Resources;
import javax.annotation.Resource;
import javax.naming.*;
import javax.ejb.*;
import javax.jms.*;

import javax.ejb.ActivationConfigProperty;

@MessageDriven(
name = "MyMDB",
mappedName = "JNDINameOfMDBSourceDest",
activationConfig = {
// the JMS interface type for the MDB destination, either javax.jms.Topic or javax.jms.Queue
@ActivationConfigProperty(
propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
// optionally specify a connection factory
// there's no need to specify a connection factory if the source
// destination is a WebLogic JMS destination
@ActivationConfigProperty(
propertyName = "connectionFactoryJndiName",
propertyValue = "JNDINameOfMDBSourceCF"),
})

// resources that are not injected

@Resources ({
@Resource(name="targetCFRef",
mappedName="TargetCFJNDIName",
type=javax.jms.ConnectionFactory.class),

@Resource(name="targetDestRef",
mappedName="TargetDestJNDIName",
type=javax.jms.Destination.class)
})

public class MyMDB implements MessageListener {

// inject a reference to the MDB context

@Resource
private MessageDrivenContext mdctx;

// cache targetCF and targetDest for re-use (performance)

private ConnectionFactory targetCF;
private Destination targetDest;

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void onMessage(Message message) {

Connection jmsConnection = null;

try {
System.out.println("My MDB got message: " + message);

if (targetCF == null)
targetCF = (javax.jms.ConnectionFactory)mdctx.lookup("targetCFRef");

if (targetDest == null)
targetDest = (javax.jms.Destination)mdctx.lookup("targetDestRef");

jmsConnection = targetCF.createConnection();
Session s = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer mp = s.createProducer(null);

if (message.getJMSReplyTo() != null)
mp.send(message.getJMSReplyTo(), s.createTextMessage("My Reply"));
else
mp.send(targetDest, message);

} catch (JMSException e) {
throw new EJBException(e);

} finally {

// Return JMS resources to the resource reference pool for later re-use.
// Closing a connection automatically also closes its sessions, etc.

try { if (jmsConnection != null) jmsConnection.close(); }
catch (JMSException ignored) {};
}
}
}

5 基本的なJMSアプリケーションの開発

この章では、基本的なJMSアプリケーションの開発に必要な手順について説明します。

1. 必要なパッケージのインポート

2. JMSアプリケーションの設定

3. メッセージの送信

4. メッセージの受信

5. 受信メッセージの確認応答

6. オブジェクト・リソースの解放

上記のアプリケーション開発手順の他にも、設計開発時に以下の手順を任意に行うことができます。

- 接続およびセッション処理の管理

- 宛先の動的作成

- 恒久サブスクリプションの作成

- メッセージ・ヘッダーおよびメッセージ・プロパティ・フィールドの設定と参照、メッセージのフィルタ処理、およびメッセージの並行処理によるメッセージ処理の管理

- トランザクション内でのJMSの使用(第12章「WebLogic JMSによるトランザクションの使い方」を参照)

注意:
この項で説明するJMSクラスの詳細は、Java Webサイト(http://www.oracle.com/technetwork/java/index.html)にあるJMSのJavadocを参照してください。

必要なパッケージのインポート

次の表に、WebLogic JMSアプリケーションで一般に使用されるパッケージを示します。

表5-1 WebLogic JMSパッケージ

パッケージ名

説明

javax.jms

JMS API。このパッケージは常にWebLogic JMSアプリケーションで使用されます。http://download.oracle.com/javaee/5/api/javax/jms/package-summary.htmlを参照してください。

javax.naming
weblogic.jndi

サーバーおよび宛先ルックアップに必要なJNDIパッケージ。http://download.oracle.com/javase/1.4.2/docs/api/javax/naming/package-summary.htmlを参照してください。

javax.transaction.UserTransaction

JTAユーザー・トランザクション・サポートに必要なJTA API。http://www.javasoft.com/products/jta/javadocs-1.0.1/javax/transaction/UserTransaction.htmlを参照してください。

weblogic.jms.extensions

追加のクラスとメソッドを提供するWebLogic固有のJMSパブリックAPI (「JMSパブリックAPIの付加価値拡張機能」を参照)。

weblogic.jms.extensions.ServerSessionPoolFactory

WebLogic Server 8.1で非推奨になっています。

JMSアプリケーションの設定

メッセージを送受信するには、あらかじめJMSアプリケーションを設定しておく必要があります。次の図に、JMSアプリケーションの設定に必要な手順を示します。

図5-1 JMSアプリケーションの設定

「図5-1 JMSアプリケーションの設定」の説明

以下の節では、この設定手順について説明します。また、ポイント・ツー・ポイント(PTP)およびパブリッシュ/サブスクライブ(Pub/Sub)アプリケーションの詳しい例も示します。これらの例は、WL_HOME\samples\server\examples\src\examples\jmsディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jmsパッケージからの抜粋です。

設定手順に進む前に、WebLogic Serverの構成を担当するシステム管理者が必要なJMSリソース(接続ファクトリ、JMSサーバー、宛先など)を構成したことを確認してください。

- 詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのメッセージの構成に関する項を参照してください。

- これらの項に記述されているJMSクラスとメソッドの詳細は、「JMS APIについて」、javax.jms (http://download.oracle.com/javaee/5/api/javax/jms/package-summary.html)、またはweblogic.jms.extensionsのJavadocを参照してください。

- トランザクション・アプリケーションおよびJTAユーザー・トランザクションの設定については、第12章「WebLogic JMSによるトランザクションの使い方」を参照してください。

ステップ1: JNDIで接続ファクトリをルックアップする

接続ファクトリをルックアップするには、あらかじめ接続ファクトリを構成情報の一部として定義しておく必要があります。WebLogic JMSには、構成の一部として組み込まれているデフォルト接続ファクトリが2つ用意されています。このファクトリは、weblogic.jms.ConnectionFactory JNDI名とweblogic.jms.XAConnectionFactoryでルックアップできます(これらはJTAトランザクションを有効化します)。管理者は構成時に新しい接続ファクトリを構成できますが、これらのファクトリには一意の名前を付ける必要があります。そうしないとサーバーが起動しません。接続ファクトリの構成および使用できるデフォルトについては、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。

接続ファクトリを定義したら、その接続ファクトリをルックアップするために、まずInitialContext()メソッド(http://download.oracle.com/javase/1.4.2/docs/api/javax/naming/InitialContext.html#InitialContext())を使用してJNDIコンテキスト(context)を確立します。サーブレット・アプリケーション以外のアプリケーションの場合は、初期コンテキストの作成に使用する環境を渡す必要があります。

コンテキストを定義したら、JNDIで接続ファクトリをルックアップするために、以下のコマンド(PTPまたはPub/Subメッセージング用)のいずれかを実行します。

QueueConnectionFactory queueConnectionFactory =
(QueueConnectionFactory) context.lookup(CF_name);

TopicConnectionFactory topicConnectionFactory =
(TopicConnectionFactory) context.lookup(CF_name);

CF_name引数には、構成時に定義した接続ファクトリ名を指定します。

ConnectionFactoryクラスの詳細は、「ConnectionFactory」またはjavax.jms.ConnectionFactoryのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionFactory.html)を参照してください。

ステップ2: 接続ファクトリを使用して接続を作成する

メッセージング・システムにアクセスするための接続を作成するには、次節で説明するConnectionFactoryメソッドを使用します。

Connectionクラスの詳細は、「Connection」またはjavax.jms.ConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Connection.html)を参照してください。

キュー接続の作成

QueueConnectionFactoryは、キュー接続を作成するための以下の2つのメソッドを提供します。

public QueueConnection createQueueConnection(
) throws JMSException

public QueueConnection createQueueConnection(
String userName,
String password
) throws JMSException

最初のメソッドはQueueConnectionを作成し、2番目のメソッドは指定されたユーザーIDを使用してQueueConnectionを作成します。どちらのケースでも、接続は停止モードで作成されます。メッセージを受け付けるには、「ステップ7: 接続を開始する」で説明するとおりに接続を開始しなければなりません。

QueueConnectionFactoryクラスのメソッドの詳細は、javax.jms.QueueConnectionFactoryのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueConnectionFactory.html)を参照してください。QueueConnectionクラスのメソッドの詳細は、javax.jms.QueueConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueConnection.html)を参照してください。

トピック接続の作成

TopicConnectionFactoryは、トピック接続を作成するための、以下の2つのメソッドを提供します。

public TopicConnection createTopicConnection(
) throws JMSException

public TopicConnection createTopicConnection(
String userName,
String password
) throws JMSException

最初のメソッドはTopicConnectionを作成し、2番目のメソッドは指定されたユーザーIDを使用してTopicConnectionを作成します。どちらのケースでも、接続は停止モードで作成されます。メッセージを受け付けるには、「ステップ7: 接続を開始する」で説明するとおりに接続を開始しなければなりません。

TopicConnectionFactoryクラスのメソッドの詳細は、javax.jms.TopicConnectionFactoryのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicConnectionFactory.html)を参照してください。TopicConnectionクラスの詳細は、javax.jms.TopicConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicConnection.html)を参照してください。

ステップ3: 接続を使用してセッションを作成する

キューまたはトピックにアクセスするために1つまたは複数のセッションを作成するには、以降の節で説明するConnectionメソッドを使用します。

注意:
セッションおよびそのメッセージのプロデューサとコンシューマには、一度に1つのスレッドしかアクセスできません。それらに複数のスレッドが同時にアクセスした場合、それらの動作は不明確になります。
WebLogic JMSでは、単一のセッションでQueueConsumer型とTopicSubscriber型のMessageConsumerを一緒に使用することはできません。ただし、単一のセッションでQueueSender型とTopicSubscriber型(またはQueueConsumer型とTopicPublisher型)を1つずつ使用することは可能です。また、MessageProducerは型に関係なく複数使用できます。

Sessionクラスの詳細は、「Session」またはjavax.jms.SessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Session.html)を参照してください。

キュー・セッションの作成

QueueConnectionクラスは、キュー・セッション作成用のメソッドを次のとおり定義します。

public QueueSession createQueueSession(
boolean transacted,
int acknowledgeMode
) throws JMSException

このメソッドでは、セッションをトランザクション処理するか(true)、またはトランザクション処理しないか(false)を示すブール引数と、非トランザクション・セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション・セッションの場合、acknowledgeMode属性は無視されます。この場合、メッセージはcommit()メソッドでトランザクションがコミットされたときに確認応答されます。

QueueConnectionクラスのメソッドの詳細は、javax.jms.QueueConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueConnection.html)を参照してください。QueueSessionクラスの詳細は、javax.jms.QueueSessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueSession.html)を参照してください。

トピック・セッションの作成

TopicConnectionクラスは、トピック・セッション作成用のメソッドを次のとおり定義します。

public TopicSession createTopicSession(
boolean transacted,
int acknowledgeMode
) throws JMSException

このメソッドでは、セッションをトランザクション処理するか(true)、またはトランザクション処理しないか(false)を示すブール引数と、非トランザクション・セッションの確認応答モードを示す整数値を指定する必要があります。トランザクション・セッションの場合、acknowledgeMode属性は無視されます。この場合、メッセージはcommit()メソッドでトランザクションがコミットされたときに確認応答されます。

TopicConnectionクラスのメソッドの詳細は、javax.jms.TopicConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicConnection.html)を参照してください。TopicSessionクラスの詳細は、javax.jms.TopicSessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicSession.html)を参照してください。

ステップ4: 宛先(キューまたはトピック)をルックアップする

宛先をルックアップする場合、事前にWebLogic JMSシステム管理者によって宛先が構成されている必要があります。宛先の構成については、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックの構成に関する項およびキューの構成に関する項で説明されています。Destinationクラスの詳細は、「Destination」またはjavax.jms.DestinationのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Destination.html)を参照してください。

宛先が構成されていれば、以下のいずれかの手順を実行して宛先をルックアップできます。

JNDI名の使用

JNDIコンテキスト(context)を確立し(「ステップ1: JNDIで接続ファクトリをルックアップする」で実行済み)、以下のコマンド(PTPまたはPub/Subメッセージング用)のいずれかを実行することによって、宛先をルックアップできます。

Queue queue = (Queue) context.lookup(Dest_name);

Topic topic = (Topic) context.lookup(Dest_name);

Dest_name引数には、構成時に定義された宛先のJNDI名を指定します。

参照の使用

JNDIネームスペースを使用しない場合は、以下のQueueSessionまたはTopicSessionメソッドを使用してキューまたはトピックをそれぞれ参照できます。

注意:
createQueue()メソッドとcreateTopic()メソッドでは宛先が動的には作成されず、既存の宛先への参照のみが作成されます。宛先の動的な作成については、第7章「JMSモジュール・ヘルパーを使用したアプリケーションの管理」を参照してください。

public Queue createQueue(
String queueName
) throws JMSException

public Topic createTopic(
String topicName
) throws JMSException

JNDIの構文、createQueue()、およびcreateTopic()については、「宛先のルックアップ方法」を参照してください。

ステップ5: メッセージ・オブジェクトとメッセージ・コンシューマを作成する

メッセージ・プロデューサとメッセージ・コンシューマを作成するには、次節で説明するSessionメソッドに宛先の参照を渡します。

注意:
各コンシューマはメッセージの独自のローカル・コピーを受信します。受信が済んだら、ヘッダー・フィールド値を変更することはできますが、メッセージ・プロパティとメッセージ本文は読取り専用です。(この時点でメッセージ・プロパティまたは本文を変更しようとすると、MessageNotWriteableExceptionが発生します)。メッセージ本文を変更するには、対応するメッセージ・タイプのclearbody()メソッドを実行して、既存の内容を消去し、書込み権限を有効にします。

MessageProducerクラスとMessageConsumerクラスの詳細は、「MessageProducerとMessageConsumer」またはjavax.jms.MessageProducerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/MessageProducer.html)およびjavax.jms.MessageConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/MessageConsumer.html)を参照してください。

QueueSenderとQueueReceiverの作成

QueueSessionオブジェクトは、キュー・センダーとキュー・レシーバを作成するための、以下のメソッドを定義します。

public QueueSender createSender(
Queue queue
) throws JMSException

public QueueReceiver createReceiver(
Queue queue
) throws JMSException

public QueueReceiver createReceiver(
Queue queue,
String messageSelector
) throws JMSException

作成するキュー・センダーまたはキュー・レシーバに関連付けるキュー・オブジェクトを指定しなければなりません。また、メッセージをフィルタ処理するためのメッセージ・セレクタを指定できます。メッセージ・セレクタの詳細は、「メッセージのフィルタ処理」を参照してください。

createSender()メソッドにnull値を渡すと、匿名プロデューサが作成されます。この場合、メッセージの送信で説明するように、メッセージの送信時にキュー名を指定しなければなりません。

キュー・センダーまたはキュー・レシーバの作成が済んだら、以下のQueueSenderメソッドまたはQueueReceiverメソッドを使用して、そのキュー・センダーまたはレシーバに関連付けられているキュー名にアクセスできます。

public Queue getQueue(
) throws JMSException

QueueSessionクラスのメソッドの詳細は、javax.jms.QueueSessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueSession.html)を参照してください。QueueSenderクラスとQueueReceiverクラスの詳細は、javax.jms.QueueSenderのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueSender.html)およびjavax.jms.QueueReceiverのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueReceiver.html)を参照してください。

TopicPublisherとTopicSubscriberの作成

TopicSessionオブジェクトは、トピック・パブリッシャとトピック・サブスクライバを作成するための、以下のメソッドを定義します。

public TopicPublisher createPublisher(
Topic topic
) throws JMSException

public TopicSubscriber createSubscriber(
Topic topic
) throws JMSException

public TopicSubscriber createSubscriber(
Topic topic,
String messageSelector,
boolean noLocal
) throws JMSException

注意:
この節で説明するメソッドでは、非恒久サブスクライバが作成されます。非恒久トピック・サブスクライバは、アクティブな間だけメッセージを受信します。恒久サブスクリプションを作成して、すべてのメッセージが恒久サブスクライバに届けられるまでメッセージを保持できるようにするためのメソッドについては、「恒久サブスクリプション用のサブスクライバの作成」を参照してください。この場合、恒久サブスクライバはサブスクライバがサブスクライブした後にパブリッシュされたメッセージのみを受信します。

作成するパブリッシャまたはサブスクライバに関連付けるトピック・オブジェクトを指定しなければなりません。また、メッセージをフィルタ処理するためのメッセージ・セレクタ、およびnoLocalフラグ(この節で後述)を指定することもできます。メッセージ・セレクタの詳細は、「メッセージのフィルタ処理」を参照してください。

createPublisher()メソッドにnull値を渡すと、匿名プロデューサが作成されます。この場合、メッセージの送信で説明するように、メッセージの送信時にトピック名を指定しなければなりません。

アプリケーションは、JMS接続を使用して同じトピックに対してパブリッシュとサブスクライブの両方を行う場合があります。トピック・メッセージはすべてのサブスクライバに届けられるので、アプリケーションは自身がパブリッシュしたことを示すメッセージを受信する可能性があります。この動作を防ぐために、JMSアプリケーションはnoLocalフラグをtrueに設定できます。

トピック・パブリッシャまたはトピック・サブスクライバの作成が済んだら、以下のTopicPublisherメソッドまたはTopicSubscriberメソッドを使用して、そのトピック・パブリッシャまたはサブスクライバに関連付けられているトピック名にアクセスできます。

Topic getTopic(
) throws JMSException

また、次のTopicSubscriberメソッドを使用すると、トピック・サブスクライバに関連付けられるnoLocal変数の設定値にアクセスできます。

boolean getNoLocal(
) throws JMSException

TopicSessionクラスのメソッドの詳細は、javax.jms.TopicSessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicSession.html)を参照してください。TopicPublisherクラスとTopicSubscriberクラスの詳細は、javax.jms.TopicPublisherのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicPublisher.html)およびjavax.jms.TopicSubscriberのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicSubscriber.html)を参照してください。

ステップ6a: メッセージ・オブジェクトを作成する(メッセージ・プロデューサ)

注意:
この手順は、メッセージ・プロデューサだけに適用されます。

メッセージ・オブジェクトを作成するには、以下のSessionクラス・メソッドまたはWLSessionクラス・メソッドのいずれかを使用します。

- Sessionメソッド

注意:
これらのメソッドは、QueueSessionサブクラスとTopicSessionサブクラスの両方によって継承されます。

public BytesMessage createBytesMessage(
) throws JMSException

public MapMessage createMapMessage(
) throws JMSException

public Message createMessage(
) throws JMSException

public ObjectMessage createObjectMessage(
) throws JMSException

public ObjectMessage createObjectMessage(
Serializable object
) throws JMSException

public StreamMessage createStreamMessage(
) throws JMSException

public TextMessage createTextMessage(
) throws JMSException

public TextMessage createTextMessage(
String text
) throws JMSException

- WLSessionメソッド

public XMLMessage createXMLMessage(
String text
) throws JMSException

SessionクラスおよびWLSessionクラスのメソッドの詳細は、それぞれjavax.jms.SessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Session.html)およびweblogic.jms.extensions.WLSessionのJavadocを参照してください。Messageクラスとそのメソッドの詳細は、「Message」またはjavax.jms.MessageのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Message.html)を参照してください。

ステップ6b: 非同期メッセージ・リスナーを登録する(オプション)

注意:
この手順は、メッセージ・コンシューマだけに適用されます。

メッセージを非同期的に受信するには、次の手順で非同期メッセージ・リスナーを登録する必要があります。

1. onMessage()メソッドを持つインタフェースjavax.jms.MessageListener (http://download.oracle.com/javaee/5/api/javax/jms/MessageListener.html)を実装します。

注意:
onMessage()メソッドのインタフェースの例については、「例: PTPアプリケーションの設定」を参照してください。
onMessage()メソッド呼出し内でclose()メソッドを発行する場合、システム管理者は接続ファクトリを構成するときに「onMessage()でのcloseを許可」オプションを選択する必要があります。接続ファクトリ・オプションの構成の詳細は、『Oracle WebLogic Server JMSの構成と管理』の「基本JMSシステム・リソースの構成」を参照してください。

2. 次のMessageConsumerメソッドを使用してメッセージ・リスナーを設定し、リスナー情報を引数として渡します。

public void setMessageListener(
MessageListener listener
) throws JMSException

3. 必要に応じて、「接続例外リスナーの定義」で説明するように、例外を取得するためのセッションの例外リスナーを実装します。

メッセージ・リスナーの設定を解除するには、null値を指定してMessageListener()メソッドを呼び出します。

メッセージ・リスナーを定義したら、次のMessageConsumerメソッドを呼び出してそのリスナーにアクセスできます。

public MessageListener getMessageListener(
) throws JMSException

注意:
WebLogic JMSは、同じセッションの複数のonMessage()呼出しが同時に実行されないことを保証します。

メッセージ・コンシューマが管理者またはサーバー障害によってクローズされた場合、ConsumerClosedExceptionがセッション例外リスナーに送信されます(定義されている場合)。このように、必要な場合は新しいメッセージ・コンシューマを作成できます。セッション例外リスナーの定義については、「セッション例外リスナーの定義」を参照してください。

MessageConsumerクラスのメソッドは、QueueReceiverおよびTopicSubscriberクラスによって継承されます。MessageConsumerクラスのメソッドの詳細は、「MessageProducerとMessageConsumer」またはjavax.jms.MessageConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/MessageConsumer.html)を参照してください。

ステップ7: 接続を開始する

接続を開始するには、Connectionクラスのstart()メソッドを使用します。

接続の開始、停止、およびクローズの詳細は、「接続の開始、停止、クローズ」またはjavax.jms.ConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Connection.html)を参照してください。

例: PTPアプリケーションの設定

次の例は、WL_HOME\samples\server\examples\src\examples\jms\queueディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jms.queue.QueueSendサンプルからの抜粋です。init()メソッドは、JMSアプリケーションのQueueSessionをどのように設定して開始するかを示すものです。次に、そのinit()メソッドを示し、あわせて各設定手順も述べます。

必要な変数(JNDIコンテキストなど)、JMS接続ファクトリ、およびキュー静的変数を定義します。

public final static String JNDI_FACTORY=
"weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY=
"weblogic.examples.jms.QueueConnectionFactory";
public final static String
QUEUE="weblogic.examples.jms.exampleQueue";

private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;

JNDI初期コンテキストを次のとおり設定します。

InitialContext ic = getInitialContext(args[0]);
.
.
.
private static InitialContext getInitialContext(
String url
) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}

注意:
EJBまたはサーブレットのJNDI初期コンテキストを設定する場合は、以下のメソッドを使用します。
Context ctx = new InitialContext();

JMSキューにメッセージを送信するのに必要なすべてのオブジェクトを作成します。ctxオブジェクトは、main()メソッドによって渡されたJNDI初期コンテキストです。

public void init(
Context ctx,
String queueName
) throws NamingException, JMSException
{

ステップ1

JNDIで接続ファクトリをルックアップします。

qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);

ステップ2

接続ファクトリを使用して接続を作成します。

qcon = qconFactory.createQueueConnection();

ステップ3

接続を使用してセッションを作成します。次のコードでは、セッションが非トランザクションとして定義され、メッセージに対する確認応答が自動的に行われるものと指定されます。トランザクション・セッションと確認応答モードの詳細は、「Session」を参照してください。

qsession = qcon.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);

ステップ4

JNDIで宛先(キュー)をルックアップします。

queue = (Queue) ctx.lookup(queueName);

ステップ5

セッションと宛先(キュー)を使用してメッセージ・プロデューサ(キュー・センダー)への参照を作成します。

qsender = qsession.createSender(queue);

ステップ6

メッセージ・オブジェクトを作成します。

msg = qsession.createTextMessage();

ステップ7

接続を開始します。

qcon.start();
}

examples.jms.queue.QueueReceiveの例のinit()メソッドは、前記のQueueSend init()メソッドとほぼ同じですが、例外が1つあります。ステップ5とステップ6は、それぞれ以下のコードに置き換えられます。

qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);

最初の行では、createSender()メソッドを呼び出してキュー・センダーへの参照を作成するかわりに、アプリケーションはcreateReceiver()メソッドを呼び出してキュー・レシーバを作成します。

2番目の行では、メッセージ・コンシューマは非同期メッセージ・リスナーを登録します。

メッセージがキュー・セッションに届くと、そのメッセージはexamples.jms.QueueReceive.onMessage()メソッドに渡されます。次のQueueReceiveの例からの引用コードは、onMessage()インタフェースを示したものです。

public void onMessage(Message msg)
{
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage)msg).getText();
} else { // If it is not a TextMessage...
msgText = msg.toString();
}

System.out.println("Message Received: "+ msgText );

if (msgText.equalsIgnoreCase("quit")) {
synchronized(this) {

quit = true;
this.notifyAll(); // Notify main thread to quit
}
}
} catch (JMSException jmse) {
jmse.printStackTrace();
}
}

onMessage()メソッドは、キュー・レシーバを通して受信したメッセージを処理します。このメソッドは、メッセージがTextMessageであるかどうかを検証し、そうである場合は、そのメッセージのテキストを印刷します。onMessage()が別のタイプのメッセージを受信した場合、そのメッセージのtoString()メソッドを使用してメッセージの内容を表示します。

注意:
受信したメッセージのタイプが、メッセージ・ハンドラ・メソッドが予期したタイプであるかどうかを検証するようにしてください。

この例で使用されているJMSクラスの詳細は、「JMS APIについて」またはjavax.jmsのJavadoc (http://www.oracle.com/technetwork/java/jms/index.html)を参照してください。

例: Pub/Subアプリケーションの設定

次の例は、WL_HOME\samples\server\examples\src\examples\jms\topicディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jms.topic.TopicSendサンプルからの抜粋です。init()メソッドは、JMSアプリケーションのトピック・セッションをどのように設定して開始するかを示すものです。次に、そのinit()メソッドを示し、あわせて各設定手順も述べます。

必要な変数(JNDIコンテキストなど)、JMS接続ファクトリ、およびトピック静的変数を定義します。

public final static String JNDI_FACTORY=
"weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY=
"weblogic.examples.jms.TopicConnectionFactory";
public final static String
TOPIC="weblogic.examples.jms.exampleTopic";

protected TopicConnectionFactory tconFactory;
protected TopicConnection tcon;
protected TopicSession tsession;
protected TopicPublisher tpublisher;
protected Topic topic;
protected TextMessage msg;

JNDI初期コンテキストを次のとおり設定します。

InitialContext ic = getInitialContext(args[0]);
.
.
.
private static InitialContext getInitialContext(
String url
) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}

注意:
サーブレットのJNDI初期コンテキストを設定する場合は、以下のメソッドを使用します。
Context ctx = new InitialContext();

JMSキューにメッセージを送信するのに必要なすべてのオブジェクトを作成します。ctxオブジェクトは、main()メソッドによって渡されたJNDI初期コンテキストです。

public void init(
Context ctx,
String topicName
) throws NamingException, JMSException
{

ステップ1

JNDIを使用して接続ファクトリをルックアップします。

tconFactory =
(TopicConnectionFactory) ctx.lookup(JMS_FACTORY);

ステップ2

接続ファクトリを使用して接続を作成します。

tcon = tconFactory.createTopicConnection();

ステップ3

接続を使用してセッションを作成します。次のコードでは、セッションが非トランザクションとして定義され、メッセージに対する確認応答が自動的に行われるものと指定されます。セッションのトランザクションと確認応答モードの設定については、「Session」を参照してください。

tsession = tcon.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);

ステップ4

JNDIを使用して宛先(トピック)をルックアップします。

topic = (Topic) ctx.lookup(topicName);

ステップ5

セッションと宛先(トピック)を使用してメッセージ・プロデューサ(トピック・パブリッシャ)への参照を作成します。

tpublisher = tsession.createPublisher(topic);

ステップ6

メッセージ・オブジェクトを作成します。

msg = tsession.createTextMessage();

ステップ7

接続を開始します。

tcon.start();
}

examples.jms.topic.TopicReceiveの例のinit()メソッドは、前記のTopicSend init()メソッドとほぼ同じですが、例外が1つあります。ステップ5とステップ6は、それぞれ以下のコードに置き換えられます。

tsubscriber = tsession.createSubscriber(topic);
tsubscriber.setMessageListener(this);

最初の行では、createPublisher()メソッドを呼び出してトピック・パブリッシャへの参照を作成するかわりに、アプリケーションはcreateSubscriber()メソッドを呼び出してトピック・サブスクライバを作成します。

2番目の行では、メッセージ・コンシューマは非同期メッセージ・リスナーを登録します。

メッセージがトピック・セッションに届くと、そのメッセージはexamples.jms.TopicSubscribe.onMessage()メソッドに渡されます。TopicReceiveの例のonMessage()インタフェースは、QueueReceive onMessage()インタフェース(「例: PTPアプリケーションの設定」を参照)と同じです。

この例で使用されているJMSクラスの詳細は、「JMS APIについて」またはjavax.jmsのJavadoc (http://www.oracle.com/technetwork/java/jms/index.html)を参照してください。

メッセージの送信

「JMSアプリケーションの設定」の説明に従ってJMSアプリケーションを設定すると、メッセージを送信できるようになります。メッセージを送信するには、以下の節で説明する手順を順番どおりに実行する必要があります。

1. メッセージ・オブジェクトを作成する

2. メッセージを定義する

3. メッセージを宛先に送信する

メッセージの送信に使用するJMSクラスとメッセージ・タイプの詳細は、javax.jms.MessageのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Message.html)を参照してください。メッセージの受信については、「メッセージの受信」を参照してください。

メッセージ・オブジェクトを作成する

この手順は、「ステップ6a: メッセージ・オブジェクトを作成する(メッセージ・プロデューサ)」で説明したように、クライアント設定手順の一部としてすでに完了しています。

メッセージを定義する

この手順は、ステップ6a: メッセージ・オブジェクトを作成する(メッセージ・プロデューサ)で説明したように、アプリケーションの設定時に完了している場合もあります。この手順が完了しているかどうかは、メッセージ・オブジェクトを作成するために呼び出されたメソッドによって決まります。たとえば、TextMessageタイプとObjectMessageタイプの場合は、メッセージ・オブジェクトを作成するときにオプションでメッセージを定義することができます。

すでに値が指定されており、それを変更しない場合は、そのままステップ3に進みます。

値が指定されていない場合、または既存の値を変更する場合は、適切なsetメソッドを使用して値を定義できます。たとえば、TextMessageのテキストを定義するメソッドは次のとおりです。

public void setText(
String string
) throws JMSException

注意:
メッセージはnullとして定義することができます。

それ以後は、次のメソッドを使用してメッセージを消去できます。

public void clearBody(
) throws JMSException

メッセージの定義に使用するメソッドの詳細は、javax.jms.SessionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Session.html)を参照してください。

メッセージを宛先に送信する

メッセージを宛先に送信するには、メッセージ・プロデューサ、つまりキュー・センダー(PTP)またはトピック・パブリッシャ(Pub/Sub)と、以下の節で説明するメソッドを使用します。DestinationオブジェクトとMessageProducerオブジェクトは、「JMSアプリケーションの設定」で説明したとおり、アプリケーションの設定時に作成されています。

注意:
複数のトピック・サブスクライバが同じトピックに対して定義されている場合、各サブスクライバはメッセージの独自のローカル・コピーを受信します。受信が済んだら、ヘッダー・フィールド値を変更することはできますが、メッセージ・プロパティとメッセージ本文は読取り専用です。メッセージ本文を変更するには、対応するメッセージ・タイプのclearbody()メソッドを実行して、既存の内容を消去し、書込み権限を有効にします。

MessageProducerクラスの詳細は、「MessageProducerとMessageConsumer」またはjavax.jms.MessageProducerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/MessageProducer.html)を参照してください。

キュー・センダーを使用してメッセージを送信する

メッセージを送信するには、以下のQueueSenderメソッドを使用します。

public void send(
Message message
) throws JMSException

public void send(
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException

public void send(
Queue queue,
Message message
) throws JMSException

public void send(
Queue queue,
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException

メッセージを指定する必要があります。また、キュー名(匿名メッセージ・プロデューサ用)、配信モード(DeliveryMode.PERSISTENTまたはDeliveryMode.NON_PERSISTENT)、優先度(0-9)、および存続時間(ミリ秒単位)も指定できます。指定しない場合、配信モード、優先度、および存続時間の各属性は以下のいずれかに設定されます。

- プロデューサに対して定義された接続ファクトリまたは宛先オーバーライド構成属性(Oracle WebLogic Server管理コンソール・オンライン・ヘルプのデフォルトの配信パラメータの構成に関する項を参照)。

- メッセージ・プロデューサのsetメソッドによって指定された値(「メッセージ・プロデューサ属性の設定」を参照)

注意:
WebLogic JMSでは、以下に示す独自の属性も提供されています(「メッセージ・プロデューサ属性の設定」を参照)。

- TimeToDeliver (生成時間)。この属性は、送信されたメッセージがその宛先に到着するまでの遅延を表します。

- RedeliveryLimit。この属性は、回復またはロールバック後のメッセージの再送信の回数を指定します。

- SendTimeout。この属性は、メッセージの送信時にプロデューサがスペースの空きを待つ最長時間です。

配信モードをPERSISTENTとして定義した場合、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの永続ストアの構成に関する項で説明しているように、宛先のバッキング・ストアを構成する必要があります。

注意:
バッキング・ストアが構成されていない場合、配信モードはNON_PERSISTENTに変更され、メッセージは永続ストアに書き込まれません。

キュー・センダーが匿名プロデューサである場合(つまり、キューが作成されたときにその名前がNULLに設定された場合)、キュー名を指定して(最後の2つのメソッドのいずれかを使用する)メッセージの配信先を指示する必要があります。匿名プロデューサの定義の詳細は、「QueueSenderとQueueReceiverの作成」を参照してください。

たとえば、次のコードは、永続的メッセージを優先度4、存続時間1時間で送信します。

QueueSender.send(message, DeliveryMode.PERSISTENT, 4, 3600000);

QueueSenderクラスのメソッドの詳細は、javax.jms.QueueSenderのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueSender.html)を参照してください。

TopicPublisherを使用してメッセージを送信する

メッセージを送信するには、以下のTopicPublisherメソッドを使用します。

public void publish(
Message message
) throws JMSException

public void publish(
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException

public void publish(
Topic topic,
Message message
) throws JMSException

public void publish(
Topic topic,
Message message,
int deliveryMode,
int priority,
long timeToLive
) throws JMSException

メッセージを指定する必要があります。また、トピック名、配信モード(DeliveryMode.PERSISTENTまたはDeliveryMode.NON_PERSISTENT)、優先度(0-9)、および存続時間(ミリ秒単位)を指定することもできます。指定しない場合、配信モード、優先度、および存続時間の各属性は以下のいずれかに設定されます。

- プロデューサに対して定義された接続ファクトリまたは宛先オーバーライド構成属性(Oracle WebLogic Server管理コンソール・オンライン・ヘルプのデフォルトの配信パラメータの構成に関する項を参照)。

- メッセージ・プロデューサのsetメソッドによって指定された値(「メッセージ・プロデューサ属性の設定」を参照)

注意:
WebLogic JMSでは、以下に示す独自の属性も提供されています(「メッセージ・プロデューサ属性の設定」を参照)。

- TimeToDeliver (生成時間)。この属性は、送信されたメッセージがその宛先に到着するまでの遅延を表します。

- RedeliveryLimit。この属性は、回復またはロールバック後のメッセージの再送信の回数を指定します。

- SendTimeout。この属性は、メッセージの送信時にプロデューサがスペースの空きを待つ最長時間です。

配信モードをPERSISTENTとして定義した場合、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのカスタム永続ストアの構成に関する項で説明しているように、バッキング・ストアを構成する必要があります。

注意:
バッキング・ストアが構成されていない場合、配信モードはNON_PERSISTENTに変更され、メッセージは保存されません。

トピック・パブリッシャが匿名プロデューサである場合(つまり、トピックが作成されたときにその名前がNULLに設定された場合)、トピック名を指定して(最後の2つのメソッドのいずれかを使用する)メッセージの配信先を指示する必要があります。匿名プロデューサの定義の詳細は、「TopicPublisherとTopicSubscriberの作成」を参照してください。

たとえば、次のコードは、永続的メッセージを優先度4、存続時間1時間で送信します。

TopicPublisher.publish(message, DeliveryMode.PERSISTENT,
4,3600000);

TopicPublisherクラスのメソッドの詳細は、javax.jms.TopicPublisherのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicPublisher.html)を参照してください。

メッセージ・プロデューサ属性の設定

前項で説明したように、メッセージを送信するときには、配信モード、優先度、および存続時間をオプションで指定できます。指定しない場合、これらの属性には接続ファクトリの構成属性の値が設定されます。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。

かわりに、メッセージ・プロデューサのsetメソッドを使用して、配信モード、優先度、配信時間、存続時間、再配信遅延(タイムアウト)、および再配信制限の各属性値を動的に設定できます。次の表に、メッセージ・プロデューサのsetメソッドとgetメソッドを、動的構成可能な属性ごとに示します。

注意:
配信モード、優先度、存続時間、配信時間、再配信遅延(タイムアウト)、および再配信制限の各属性値は、「配信モードのオーバーライド」、「優先度のオーバーライド」、存続時間のオーバーライド、配信時間のオーバーライド、「再配信遅延のオーバーライド」、および「再配信の制限」の各構成属性を使用して宛先によってオーバーライドできます。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのメッセージ配信のオーバーライドの構成に関する項およびトピック・メッセージ配信のオーバーライドの構成に関する項を参照してください。

表5-2 メッセージ・プロデューサのsetメソッドおよびgetメソッド

属性

setメソッド

getメソッド

配信モード

public void setDeliveryMode(
int deliveryMode
) throws JMSException

public int getDeliveryMode(
) throws JMSException

優先順位

public void setPriority(
int defaultPriority
) throws JMSException

public int getPriority(
) throws JMSException

存続時間

public void setTimeToLive(
long timeToLive
) throws JMSException

public long getTimeToLive(
) throws JMSException

配信時間

public void setTimeToDeliver(
long timeToDeliver
) throws JMSException

public long getTimeToDeliver(
) throws JMSException

再配信の制限

public void setRedeliveryLimit(
int redeliveryLimit
) throws JMSException

public int getredeliveryLimit(
) throws JMSException

送信タイムアウト

public void setsendTimeout(
long sendTimeout
) throws JMSException

public long getsendTimeout(
) throws JMSException

注意:
JMSでは、メッセージIDとタイムスタンプ情報を無効にするためのMessageProducerメソッドを定義することもできます。ただし、これらのメソッドはWebLogic JMSでは無視されます。

MessageProducerクラスのメソッドの詳細は、javax.jms.MessageProducerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/MessageProducer.html)またはweblogic.jms.extensions.WLMessageProducerのJavadocを参照してください。

例: PTPアプリケーション内でのメッセージの送信

次の例は、WL_HOME\samples\server\examples\src\examples\jms\queueディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jms.queue.QueueSendサンプルからの抜粋です。この例では、TextMessageを作成し、メッセージのテキストを設定してキューに送信するために必要なコードを示してあります。

msg = qsession.createTextMessage();
.
.
.
public void send(
String message
) throws JMSException
{
msg.setText(message);
qsender.send(msg);
}

QueueSenderクラスのメソッドの詳細は、javax.jms.QueueSenderのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueSender.html)を参照してください。

例: Pub/Subアプリケーション内でのメッセージの送信

次の例は、WL_HOME\samples\server\examples\src\examples\jms\topicディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jms.topic.TopicSendサンプルからの抜粋です。この例では、TextMessageを作成し、メッセージのテキストを設定してトピックに送信するために必要なコードを示してあります。

msg = tsession.createTextMessage();
.
.
.
public void send(
String message
) throws JMSException
{
msg.setText(message);
tpublisher.publish(msg);
}

TopicPublisherクラスとメソッドの詳細は、javax.jms.TopicPublisherのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicPublisher.html)を参照してください。

メッセージの受信

「JMSアプリケーションの設定」の説明に従ってJMSアプリケーションを設定すると、メッセージを受信できるようになります。

メッセージを受信するには、以下の節で説明するとおりレシーバ・オブジェクトを作成し、メッセージを同期受信するか非同期受信するかを指定する必要があります。

メッセージを受信する順序は、以下の要素によって設定できます。

- 構成時またはsend()メソッドの一部として定義するメッセージ配信属性(配信モードとソート条件)。詳細については、「メッセージの送信」を参照してください。

- 宛先キーを使用して設定される宛先ソート順序。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの宛先キーの構成に関する項を参照してください。

受信が済んだら、ヘッダー・フィールド値を変更することはできますが、メッセージ・プロパティとメッセージ本文は読取り専用です。メッセージ本文を変更するには、対応するメッセージ・タイプのclearbody()メソッドを実行して、既存の内容を消去し、書込み権限を有効にします。

メッセージの受信に使用するJMSクラスとメッセージ・タイプの詳細は、javax.jms.MessageのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Message.html)を参照してください。メッセージの送信については、「メッセージの送信」を参照してください。

メッセージの非同期受信

この手順については、アプリケーションの設定手順の中で説明されています。詳細は、「ステップ6b: 非同期メッセージ・リスナーを登録する(オプション)」を参照してください。

注意:
接続ファクトリの構成時に「セッションあたりの最大メッセージ数」属性を設定すると、非同期コンシューマに存在し、メッセージ・リスナーにまだ渡されていないメッセージの最大数を指定できます。

非同期メッセージ・パイプライン

メッセージの生成速度が非同期メッセージ・リスナー(コンシューマ)によるそれらの消費速度を上回る場合、JMSサーバーは複数の未消費メッセージをまとめ、別の使用可能な非同期メッセージ・リスナーのセッションに送ります。こうした処理中のメッセージはメッセージ・パイプラインと呼ばれ、JMSベンダーによってはメッセージ・バックログとも呼ばれます。パイプラインまたはバックログのサイズは、非同期コンシューマで蓄積され、メッセージ・リスナーに渡されていないメッセージの数です。

メッセージ・パイプラインの構成

クライアントの最大パイプライン・サイズを設定するには、クライアントの接続ファクトリのセッションあたりの最大メッセージ数属性を構成します。この属性は、非同期コンシューマに存在し、メッセージ・リスナーにまだ渡されていないメッセージの最大数です。デフォルト値は10です。JMS接続ファクトリの構成の詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。

パイプライン・メッセージの動作

構成されたメッセージ・パイプラインは、次のように動作します。

- 統計 - JMSモニター統計では、メッセージ・パイプラインのバックログ・メッセージは、コミットまたは確認応答されるまで保留中(キューおよび恒久サブスクライバに対して)として報告されます。

- パフォーマンス - 「セッションあたりの最大メッセージ数」パイプライン・サイズを増やすと、高スループット・アプリケーションのパフォーマンスが向上する場合があります。パイプライン・サイズを増やすと、クライアントのメモリー使用率が高くなります。これは、非同期コンシューマのリスナーが呼び出されるまで保留中のパイプライン・メッセージがクライアントJVMに蓄積されるからです。

- ソート - 非同期コンシューマのパイプライン内のメッセージは、コンシューマ宛先の構成済みソート順序に従ってソートされず、JMSサーバーから送信された順序を保持します。たとえば、宛先のソート順序が優先順位である場合でも、優先順位が最も高いメッセージが、非同期コンシューマのパイプラインにすでに送信されている優先順位の低いメッセージの前に来ることはありません。

注意:
接続ファクトリの「セッションあたりの最大メッセージ数」パイプライン・サイズは、JMSサーバーおよび宛先の最大メッセージ割当ての設定とは関係ありません。
パイプライン・メッセージは、ネットワーク・トランスポートで単一のメッセージに集約される場合があります。パイプライン・メッセージのサイズが大きい場合、書き込まれるデータの集約サイズが最大トランスポート値を超え、望ましくない動作が発生する場合があります。たとえば、t3プロトコルでは、デフォルトの最大メッセージ・サイズは10,000,000バイトに設定されており、サーバーのMaxT3MessageSize属性で構成できます。このため、10通の2 MBメッセージがパイプライン処理される場合、t3の制限を上回る場合があります。

メッセージの同期受信

メッセージを同期的に受信するには、以下のMessageConsumerメソッドを使用します。

public Message receive(
) throws JMSException

public Message receive(
long timeout
) throws JMSException

public Message receiveNoWait(
) throws JMSException

どのケースでも、アプリケーションは次に生成されるメッセージを受信します。receive()メソッドを引数なしで呼び出した場合、その呼出しはメッセージが生成されるか、またはアプリケーションがクローズされるまで無期限にブロックされます。代わりに、タイムアウト値を渡してメッセージの待ち時間を指定することもできます。値0を指定してreceive()メソッドを呼び出した場合、その呼出しは無期限にブロックされます。receiveNoWait()メソッドは、次のメッセージが存在する場合はそれを受信し、それ以外の場合はnullを返します。この場合、呼出しはブロックされません。

MessageConsumerクラスのメソッドは、QueueReceiverおよびTopicSubscriberクラスによって継承されます。MessageConsumerクラスのメソッドの詳細は、javax.jms.MessageConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/MessageConsumer.html)を参照してください。

プリフェッチ・モードを使用した同期メッセージ・パイプラインの作成

WebLogic Server 9.1より前のバージョンでは、同期コンシューマで各メッセージに対し双方向のネットワーク呼出しが必要でした。この方法は同期コンシューマで複数のメッセージを受け取れないので非効率的であり、また同期コンシューマで利用可能なメッセージ用にサーバーのポーリングが続けられるのでネットワーク・トラフィック・リソースが増加するおそれがありました。WebLogic 9.1以降では、管理コンソールまたはJMSClientParamsBean MBeanを介してJMS接続ファクトリの「同期コンシューマのプリフェッチ・モード」オプションを有効にすることにより、同期コンシューマでも非同期コンシューマと同じ効率的な動作を利用できるようになります。

JMSクライアントの接続ファクトリでプリフェッチ・モードが有効な場合、非同期メッセージのパイプラインのように、その接続ファクトリにターゲット指定されたJMSサーバーが未消費のメッセージのバッチを積極的に同期メッセージ・コンシューマに送信します。この際、バッチごとにプリフェッチされるメッセージの最大数を定義するために、その接続ファクトリの「セッションあたりの最大メッセージ数」パラメータが使用されます。これにより、同期コンシューマでさらにメッセージを処理する準備ができたときに、そのコンシューマに対してメッセージが用意され待機している状態になるため、パフォーマンスが向上する場合があります。さらに、コンシューマでメッセージのポーリングが続けられることがなく、コンシューマからの同期呼出し数が減るので、ネットワーク・トラフィックが減少することもあります。

同期メッセージ・プリフェッチは、同期メッセージ受信に対するユーザー(XA)トランザクションも、(キューであるかトピックであるかに関係なく)セッションごとの複数の同期コンシューマもサポートしていません。上記に該当するほとんどの場合、WebLogic JMSでは何の通知もなく「同期コンシューマのプリフェッチ・モード」フラグは無視されます。ただし、無視されない場合、アプリケーションの同期受信呼出しは失敗します。

パイプライン・メッセージの動作の詳細は、「非同期メッセージ・パイプライン」を参照してください。JMS接続ファクトリの構成の詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。

PTPアプリケーション内でのメッセージの同期受信

次の例は、WL_HOME\samples\server\examples\src\examples\jms\queueディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jms.queue.QueueReceiveサンプルからの抜粋です。メッセージ・リスナーを設定するのではなく、各メッセージに対してqreceiver.receive()を呼び出します。例:

qreceiver = qsession.createReceiver(queue);
qreceiver.receive();

最初の行では、キューに対するキュー・レシーバが作成されます。2番目の行では、receive()メソッドが実行されます。receive()メソッドは、ブロックしてメッセージを待ちます。

Pub/Subアプリケーション内でのメッセージの同期受信

次の例は、WL_HOME\samples\server\examples\src\examples\jms\topicディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jms.topic.TopicReceiveサンプルからの抜粋です。メッセージ・リスナーを設定するのではなく、各メッセージに対してtsubscriber.receive()を呼び出します。

例:

tsubscriber = tsession.createSubscriber(topic);
Message msg = tsubscriber.receive();
msg.acknowledge();

最初の行では、トピックに対するトピック・サブスクライバが作成されます。2番目の行では、receive()メソッドが実行されます。receive()メソッドは、ブロックしてメッセージを待ちます。

受信メッセージの回復

注意:
この節の説明は、確認応答モードがCLIENT_ACKNOWLEDGEに設定されている非トランザクション・セッションだけに適用されます。同期受信されるAUTO_ACKNOWLEDGEメッセージは確認応答済みのため、回復されないことがあります。

アプリケーションは、次のメソッドを使用して、JMSにメッセージの再配信(未確認)をリクエストできます。

public void recover(
) throws JMSException

recover()メソッドは、次の手順を実行します。

- セッションのメッセージ配信を停止します。

- 確認応答されていない(ただし配信されている可能性のある)すべてのメッセージに再配信のタグを付けます。

- そのセッションの確認応答されていない最初のメッセージからメッセージの送信を再開します。

注意:
キュー内のメッセージは、必ずしも元の配信順序と同じ順序で、または同じキュー・コンシューマに再配信されるとは限りません。再配信メッセージの正しい配信順序の保証については、「メッセージの再配信の順序付け」を参照してください。

受信メッセージの確認応答

注意:
この節の説明は、確認応答モードがCLIENT_ACKNOWLEDGEに設定されている非トランザクション・セッションだけに適用されます。

受信したメッセージの確認応答を行うには、次のMessageメソッドを使用します。

public void acknowledge(
) throws JMSException

acknowledge()メソッドは、接続ファクトリの「確認応答ポリシー」属性の構成によって次のように異なります。

- デフォルト・ポリシーの「All」の場合、あるメッセージの確認応答が呼び出されると、セッションで受信したすべての未確認応答メッセージに対して確認応答が行われます。

- 「Previous」ポリシーの場合、あるメッセージの確認応答が呼び出されると、そのメッセージ以前の未確認応答メッセージだけに対して確認応答が行われます。確認応答が行われないメッセージは、クライアントに再配信できます。

このメソッドは、確認応答モードがCLIENT_ACKNOWLEDGEに設定されている非トランザクション・セッションに対してだけ有効です。それ以外の場合、このメソッドは無視されます。

オブジェクト・リソースの解放

JMSアプリケーションにかわって作成した接続、セッション、メッセージ・プロデューサ/コンシューマ、接続コンシューマ、またはキュー・ブラウザを使い終えたら、それらを明示的にクローズしてリソースを解放する必要があります。

JMSオブジェクトをクローズするには、close()メソッドを次のとおり入力します。

public void close(
) throws JMSException

オブジェクトをクローズするときには、以下の処理が行われます。

- メソッド呼出しが完了して未処理の非同期レシーバのonMessage()メソッド呼出しが完了するまで、その呼出しがブロックされます。

- 関連付けられているすべてのサブオブジェクトもクローズされます。たとえば、セッションをクローズすると、関連付けられているすべてのメッセージ・プロデューサおよびコンシューマもクローズされます。接続をクローズすると、関連付けられているすべてのセッションもクローズされます。

各オブジェクトに対するclose()メソッドの影響については、該当するjavax.jmsのJavadoc (http://www.oracle.com/technetwork/java/jms/index.html)を参照してください。また、接続またはセッションのclose()メソッドの詳細は、それぞれ「接続の開始、停止、クローズ」、「セッションのクローズ」を参照してください。

次の例は、WL_HOME\samples\server\examples\src\examples\jms\queueディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jms.queue.QueueSendサンプルからの抜粋です。この例では、メッセージ・コンシューマ、セッション、および接続オブジェクトをクローズするのに必要なコードを示してあります。

public void close(
) throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}

このQueueSendの例では、main()の最後にclose()メソッドが呼び出され、オブジェクトのクローズとリソースの解放が行われます。

6 アプリケーションの管理

この章では、WebLogic JMSの付加価値機能を使用してJMSアプリケーションをプログラム的に管理する方法について説明します。

- ロールバック、回復、または再配信されたか、期限切れになったメッセージの管理

- メッセージ配信時間の設定

- 接続の管理

- セッションの管理

- 宛先の管理

- 一時的な宛先の使い方

- 恒久サブスクリプションの設定

- メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照

- メッセージのフィルタ処理

- XMLメッセージの送信

ロールバック、回復、または再配信されたか、期限切れになったメッセージの管理

以下の節では、ロールバックまたは回復されたメッセージを管理する方法について説明します。

- メッセージの再配信遅延の設定

- メッセージの再配信制限の設定

- メッセージの再配信の順序付け

- 期限切れメッセージの処理

メッセージの再配信遅延の設定

一時的または外部的な要因でアプリケーションがメッセージを正しく処理できない場合に、メッセージの再配信を遅延させることができます。これによって、アプリケーションは、現時点では処理できない「有害な」メッセージを一時的に受信できないようにすることができます。メッセージがロールバックまたは回復される場合、再配信遅延は、メッセージが止められてから再配信が試行されるまでの間隔です。

JMSでメッセージをすぐに再配信すると、エラーの原因が解決されず、アプリケーションはメッセージを処理できないままの場合があります。ただし、アプリケーションが再配信遅延用に構成されている場合、メッセージがロールバックまたは回復されると、メッセージは再配信の遅延が過ぎるまで止められます。遅延の期間を過ぎた時点でメッセージを再配信できるようになります。

セッションによって消費された結果、ロールバックまたは回復したすべてのメッセージは、ロールバックまたはリカバリ時にそのセッションの再配信遅延を受信します。単一のユーザー・トランザクションの一部として複数のセッションで消費されたメッセージは、個々のメッセージを消費したセッションの機能として異なる再配信遅延を受信します。意識的か、または失敗の結果、クライアントによる確認応答またはコミットされていないメッセージには、再配信遅延が割り当てられません。

再配信遅延の設定

セッションは、作成時に接続ファクトリから再配信遅延を継承します。接続ファクトリのRedeliveryDelay属性は、管理コンソールで構成します。

詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの構成に関する項を参照してください。

セッションを作成するアプリケーションは、javax.jms.Sessionインタフェースに対するWebLogic固有の拡張を使用して接続ファクトリ設定をオーバーライドできます。セッション属性は動的なので、いつでも変更できます。セッションの再配信遅延を変更すると、メッセージが非恒久トピックを使用するセッション内にある場合を除いて、変更後にそのセッションで消費およびロールバック(またはリカバリ)されるすべてのメッセージに影響します。

注意:
セッションで非恒久トピックを使用している場合、setRedeliveryDelayメソッドは適用されません。その結果、非恒久トピック・コンシューマを使用してワークフローを駆動している場合に予期しない動作が発生することがあります。

セッションに対して再配信遅延を設定するメソッドは、javax.jms.Sessionインタフェースの拡張であるweblogic.jms.extensions.WLSessionインタフェースを介して提供されます。セッションの再配信遅延を定義するには、以下のメソッドを使用します。

public void setRedeliveryDelay(
long redeliveryDelay
) throws JMSException;

public long getRedeliveryDelay(
) throws JMSException;

WLSessionクラスの詳細は、weblogic.jms.extensions.WLSessionのJavadocを参照してください。

宛先での再配信遅延のオーバーライド

再配信遅延がセッションで設定されているかどうかに関係なく、メッセージがロールバックまたは回復される宛先で再配信遅延の設定をオーバーライドできます。メッセージの再配信に割り当てられた再配信遅延のオーバーライドは、メッセージがロールバックまたは回復されるときに有効になります。

宛先のRedeliveryDelayOverride属性は、管理コンソールで構成します。詳細については、以下を参照してください。

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプのキューに関するメッセージ配信の失敗オプションの構成に関する項

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックに関するメッセージ配信の失敗オプションの構成に関する項

メッセージの再配信制限の設定

WebLogic JMSによるアプリケーションへのメッセージ再配信の試行回数に制限を設けることができます。宛先へのメッセージの再配信の失敗が指定した回数に達すると、そのメッセージ宛先に関連付けられたエラー宛先にメッセージをリダイレクトできます。再配信の制限が構成されていて、エラー宛先が構成されていない場合、永続メッセージまたは非永続メッセージは再配信の制限に達すると削除されます。

かわりに、メッセージ・プロデューサのsetメソッドを使用して、再配信の制限値を動的に設定できます(「メッセージ・プロデューサ属性の設定」を参照)。

宛先のメッセージ再配信制限の構成

宛先によるコンシューマへのメッセージ再配信の試行が指定した再配信制限に達すると、宛先はメッセージを配信不能にします。RedeliveryLimit属性は、宛先で設定され、管理コンソールで構成できます。この設定は、メッセージのプロデューサ側で設定された再配信制限をオーバーライドします。詳細については、以下を参照してください。

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプのキューに関するメッセージ配信の失敗オプションの構成に関する項

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックに関するメッセージ配信の失敗オプションの構成に関する項

配信されなかったメッセージに対するエラー宛先の構成

配信されなかったメッセージのエラー宛先がJMSサーバーに構成されている場合は、宛先に配信できないと判断されたメッセージが指定したエラー宛先にリダイレクトされます。エラー宛先はトピックまたはキューのいずれかですが、定義されている宛先と同じJMSサーバーに構成する必要があります。エラー宛先が構成されていない場合、配信されなかったメッセージは削除されます。

ErrorDestination属性は、管理コンソールを使用して、スタンドアロンの宛先および共通分散宛先に構成します。詳細は次を参照してください。

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプのキューに関するメッセージ配信の失敗オプションの構成に関する項

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックに関するメッセージ配信の失敗オプションの構成に関する項

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプの共通分散キュー - 配信の失敗パラメータの構成に関する項

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプの共通分散トピック - 配信の失敗パラメータの構成に関する項

メッセージの再配信の順序付け

注意:
再配信の順序付けを使用しているアプリケーションは、メッセージ順序単位を使用するようにアップグレードすることをお薦めします。第10章「メッセージ順序単位の使用」を参照してください。

指定されたプロデューサからコンシューマに最初に配信されるすべてのメッセージは、生成された順にコンシューマに届くことが保証されています。WebLogic JMSはこの要件を満たすだけでなく、さらに「メッセージの再配信の順序付け」機能を提供しています。この機能は、再配信メッセージについても正しい順序を保証します。

この保証を提供するために、WebLogic JMSでは特定の制約を課す必要があります。制約は次のとおりです。

- 単独のコンシューマ - 順序付き再配信は、単独のコンシューマが存在する場合にのみ保証されます。複数のコンシューマが存在する場合、個々のコンシューマがメッセージを受信する順序は保証されません。

注意:
MDB (メッセージドリブンBean)については、コンシューマ数は、ある特定のMDB用にデプロイされたMDBインスタンス数の関数です。インスタンス数の初期値および最大値は1に設定する必要があります。そうでない場合、再配信メッセージに関する順序付けは保証できません。

- ソート順序 - ある特定の宛先がソートの対象でJMS宛先キーが定義されている場合、別のメッセージが生成されて、そのメッセージが順序付けの先頭に置かれると、再配信される既存メッセージと配信される受信メッセージの間で順序の保証はできません。

- メッセージの選択 - コンシューマがセレクタを使用している場合、再配信での順序付けは、再配信対象のメッセージと、そのセレクタの基準に一致する他のメッセージの間でのみ保証されます。セレクタに一致しないメッセージに関しては順序は保証されません。

- 再配信の遅延 - メッセージに再配信遅延期間が設定されており、リカバリまたはロールバックされた場合、そのメッセージはその期間にわたって使用できなくなります。この期間中は、他のメッセージを(遅延メッセージのあとに送信されたものであっても)先に配信できます。

- リカバリを保留しているメッセージ - 順序付き再配信は、サーバーの障害やシステムの再起動が原因で、リカバリ状態を保留することになった再配信メッセージには適用されません。

メッセージング・ブリッジおよびMDBで必須のメッセージ・パイプライン設定

WebLogicメッセージング・ブリッジまたはMDBを使用する非同期コンシューマやJMSアプリケーションでは、メッセージ・パイプラインのサイズを1に設定する必要があります。パイプラインのサイズは、受信側アプリケーションが使用するJMS接続ファクトリの「最大メッセージ数」属性を使用して設定します。1より大きい値は、再配信メッセージの前に追加の送信中メッセージがある可能性を示します。MDBアプリケーションでは、アプリケーションに固有のJMS接続ファクトリを定義し、その接続ファクトリの「最大メッセージ数」属性の値を1に設定する必要があります。さらに、MDBアプリケーションのEJB記述子で接続ファクトリを参照する必要があります。

詳細は、『Oracle WebLogic Server Enterprise JavaBeansのプログラミング』の「メッセージドリブンEJB」を参照してください。

パフォーマンスの制限

順序付き再配信機能を実装したJMSアプリケーションには、JTAトランザクション(具体的にはMDBおよびWebLogicメッセージング・ブリッジ)を使用する非同期コンシューマのパフォーマンス低下が伴います。原因は送信中メッセージ数が強制的に1に削減されることであり、そのためメッセージは集約されずにクライアントに送信されます。

期限切れメッセージの処理

WebLogic JMSには、アクティブなメッセージ有効期限ポリシーが用意されています。このポリシーでは、期限切れメッセージの検索方法と処理方法を設定できます。この機能では、単純に期限切れメッセージを破棄するか、期限切れメッセージを破棄してそれをログに記録するか、または期限切れメッセージをローカルJMSサーバーのエラー宛先に転送することによって期限切れメッセージが即座に消去できます。

メッセージ配信時間の設定

アプリケーションへのメッセージ配信を、将来の指定した時間にスケジューリングできます。短い期間(秒や分など)の後でメッセージを配信することも、長い期間をおいた後で配信(数時間単位でバッチ処理する場合など)することもできます。その配信時間になって配信されるまでメッセージは表示されないため、将来の特定の時間に作業をスケジューリングできます。

メッセージが送信されるのは1回だけで、繰返し送信されることはありません。メッセージが繰返し送信されるようにするには、受信したスケジューリング済みのメッセージを元の送信先に戻す必要があります。一度のみというセマンティクスを保証するため、受信、送信、およびこれらに関連する作業は同じトランザクションのもとで行われます。

プロデューサに対する配信時間の設定

個々のプロデューサに対する配信時間の設定および取得のサポートは、javax.jms.MessageProducerインタフェースの拡張であるweblogic.jms.extensions.WLMessageProducerインタフェースを介して提供されます。個々のプロデューサに対して配信時間を定義するには、以下のメソッドを使用します。

public void setTimeToDeliver(
long timeToDeliver
) throws JMSException;

public long getTimeToDeliver(
) throws JMSException;

WLMessageProducerクラスの詳細は、weblogic.jms.extensions.WLMessageProducerのJavadocを参照してください。

メッセージに対する配信時間の設定

DeliveryTimeは、メッセージを配信するのに最も早い絶対時間を定義できるJMSメッセージ・ヘッダーです。つまり、メッセージはメッセージング・システムによって保持され、その時間になるまでどのコンシューマにも配信されません。

DeliveryTimeは、JMSヘッダー・フィールドとして宛先でのメッセージのソート、またはメッセージの選択に使用できます。データ型変換の目的で、配信時間は長整数として保存されます。

注意:
メッセージの配信時間の値を設定しても、このフィールドには影響しません。これは、メッセージが送信またはパブリッシュされるたびに、JMSがこの値をプロデューサの値でオーバーライドするためです。ここで説明するメッセージ配信時間の方法は、プロデューサによって設定される他のJMSメッセージ・フィールド(配信モード、優先度、配信時間、存続時間、再配信遅延、再配信制限など)と似ています。特に、これらのフィールドの設定はJMSプロバイダ(WebLogic JMSを含む)用に予約されます。

個々のメッセージに対する配信時間の設定および取得のサポートは、javax.jms.Messageインタフェースの拡張であるweblogic.jms.extensions.WLMessageインタフェースを介して提供されます。メッセージの配信時間を定義するには、以下のメソッドを使用します。

public void setJMSDeliveryTime(
long deliveryTime
) throws JMSException;

public long getJMSDeliveryTime(
) throws JMSException;

WLMessageクラスの詳細は、weblogic.jms.extensions.WLMessageのJavadocを参照してください。

配信時間のオーバーライド

作成されたプロデューサは、接続の作成に使用する接続ファクトリ(プロデューサもそこに含まれます)からTimeToDeliver属性(ミリ秒)を継承します。配信時間がプロデューサで設定されているかどうかに関係なく、メッセージが送信またはパブリッシュされる宛先で配信時間の設定をオーバーライドできます。管理者は、相対形式またはスケジューリング済み文字列形式のいずれかで宛先に対するTimeToDeliverOverride属性を設定できます。

存続時間の値との関係

指定した存続時間の値(JMSExpiration)が指定した配信時間と同じかそれより少ない場合、メッセージの配信は成功します。ただし、メッセージは通知されずに期限切れになります。

相対配信時間のオーバーライドの設定

相対TimeToDeliverOverrideは、整数で指定した文字列で、管理コンソールで構成可能です。

スケジューリング済み配信時間のオーバーライドの設定

スケジューリング済みTimeToDeliverOverrideはweblogic.jms.extensions.Scheduleクラスを使用しても指定できます。このクラスでは、スケジュールを取得し、次回のメッセージ配信時間を戻すメソッドが提供されています。

表6-1 メッセージ配信スケジュール

例

説明

0 0 0,30 * * * *

次の最も近い30分

* * 0,30 4-5 * * *

午前4時から午前5時までの任意の30分のうち最初の分

* * * 9-16 * * *

午前9時と午後5時の間(9:00.00 A.M. - 4:59.59 P.M.)

* * * * 8-14 * 2

その月の第2火曜日

* * * 13-16 * * 0

日曜日の午後1時と午後5時の間

* * * * * 31 *

その月の最後の日

* * * * 15 4 1

次に日曜日になる4月15日

0 0 0 1 * * 2-6;0 0 0 2 * * 1,7

平日の午前1時および週末の午前2時

cronに似た文字列がスケジュールの定義に使用されます。書式は、次のBNF構文で定義されます。

schedule := millisecond second minute hour dayOfMonth month
dayOfWeek

secondフィールドを指定するためのBNF構文は次のとおりです。

second   := * | secondList
secondList := secondItem [, secondList]
secondItem := secondValue | secondRange
SecondRange := secondValue - secondValue

ミリ秒、分、時、日、月、曜日に対する同様のBNF文を2番目の構文から取得できます。各フィールドの値は、以下の範囲の正の整数で指定します。

milliSecondValue := 0-999
milliSecondValue := 0-999
secondValue   := 0-59
minuteValue   := 0-59
hourValue    := 0-23
dayOfMonthValue := 1-31
monthValue    := 1-12
dayOfWeekValue  := 1-7

注意:
これらの値は、monthValueを除いて、java.util.Calendarクラスで使用するのと同じ範囲です。monthValueのjava.util.Calendarの範囲は、1-12ではなく0-11です。

この構文を使用すると、2つの時間の間のすべての時間を示す値の範囲で各フィールドを表すことができます。たとえば、dayOfWeekフィールドの2-6は、月曜から金曜まで(双方の曜日を含む)を示します。また、カンマ区切りのリストで各フィールドを指定することもできます。たとえば、分フィールドの0,15,30,45は、1時間内の15分おきの値を示します。さらに、個々の値と値の範囲の組合せで各フィールドを定義することもできます。たとえば、時フィールドの9-17,0は、午前9時と午後5時の間と深夜12時を示します。

補足のセマンティクスは以下のとおりです。

- セミコロン(;)で区切って複数のスケジュールが指定されている場合、次のスケジュール時間は、最も早い値を戻すスケジュールを基に決定されます。この使い方としては、曜日を基に変更されるスケジュールを指定する場合などがあります(下記の最後の例を参照)。

- dayOfWeekの値1は日曜日。

- 値*は、そのフィールドのあらゆる時間を示します。たとえば、月フィールドの*は、毎月という意味です。時フィールドの*は、毎時という意味です。

- 値l、つまりlast (大文字と小文字の区別はない)は、そのフィールドで使用できる値で最も大きな値を示します。

- 日に対して月の最大値を超える値を指定すると、その月の最大値が指定されます。たとえば、うるう年の2月に対して31を指定した場合、スケジューラは、29と見なしてスケジューリングします。これは、月フィールドを31に設定すると、その月の最後の日が指定されるということです。

- ミリ秒が指定される場合、1秒内で最も近い50番目の値に丸められます。値は0、19、39、59、...、979、および999です。したがって、0 - 40は0 - 39に丸められ、50 - 999は39 - 999に丸められます。

注意:
このクラスの静的メソッドのいずれか1つに対するメソッド・パラメータとしてCalendarが指定されない場合、使用されるカレンダは、デフォルトのjava.util.TimeZoneおよびデフォルトのjava.util.Localeがあるjava.util.GregorianCalendarです。

JMSスケジュール・インタフェース

weblogic.jms.extensions.scheduleクラスには、反復時間式に一致する次のスケジュール時間を戻すメソッドがあります。この式は、TimeToDeliverOverrideと同じ構文を使用します。ミリ秒で返される時間は、相対でも絶対でもかまいません。

Scheduleクラスの詳細は、weblogic.jms.extensions.ScheduleのJavadocを参照してください。

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を定義できます。

public static Calendar nextScheduledTime(
String schedule,
Calendar calendar
) throws ParseException {

次のメソッドを使用すると、現在の時間の後の次のスケジュール時間を定義できます。

public static Calendar nextScheduledTime(
String schedule,
) throws ParseException {

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を絶対ミリ秒で定義できます。

public static long nextScheduledTimeInMillis(
String schedule,
long timeInMillis
) throws ParseException

次のメソッドを使用すると、指定した時間の後の次のスケジュール時間を相対ミリ秒で定義できます。

public static long nextScheduledTimeInMillisRelative(
String schedule,
long timeInMillis
) throws ParseException {

次のメソッドを使用すると、現在の時間の後の次のスケジュール時間を相対ミリ秒で定義できます。

public static long nextScheduledTimeInMillisRelative(
String schedule
) throws ParseException {

接続の管理

以下の節では、接続を管理する方法について説明します。

- 接続例外リスナーの定義

- 接続メタデータへのアクセス

- 接続の開始、停止、クローズ

接続例外リスナーの定義

例外リスナーは、接続に問題が発生するとアプリケーションに非同期的に通知します。このメカニズムは、通知されない限り接続がメッセージの消費を待ち続ける場合に役立ちます。

注意:
例外リスナーの目的は、接続によってスローされたすべての例外をモニターすることではなく、本来なら配信されない例外を配信することです。

接続に対する例外リスナーを定義するには、次のConnectionメソッドを使用します。

public void setExceptionListener(
ExceptionListener listener
) throws JMSException

接続に対するExceptionListenerオブジェクトを指定しなければなりません。

JMSプロバイダは、接続の問題を発見すると、次のExceptionListenerメソッドを使用して例外リスナー(定義されている場合)に通知します。

public void onException(
JMSException exception
)

JMSプロバイダは、このメソッドを呼び出すときに、問題を説明する例外を指定します。

接続に対する例外リスナーにアクセスするには、次のConnectionメソッドを使用します。

public ExceptionListener getExceptionListener(
) throws JMSException

接続メタデータへのアクセス

特定の接続に関連付けられているメタデータにアクセスするには、次のConnectionメソッドを使用します。

public ConnectionMetaData getMetaData(
) throws JMSException

このメソッドは、JMSメタデータへのアクセスに使用するConnectionMetaDataオブジェクトを返します。次の表に、JMSメタデータのタイプと、それらにアクセスするために使用できるgetメソッドを示します。

表6-2 JMSメタデータ

JMSメタデータ

getメソッド

バージョン

public String getJMSVersion(
) throws JMSException

メジャー・バージョン

public int getJMSMajorVersion(
) throws JMSException

マイナー・バージョン

public int getJMSMinorVersion(
) throws JMSException

プロバイダ名

public String getJMSProviderName(
) throws JMSException

プロバイダ・バージョン

public String getProviderVersion(
) throws JMSException

プロバイダ・メジャー・バージョン

public int getProviderMajorVersion(
) throws JMSException

プロバイダ・マイナー・バージョン

public int getProviderMinorVersion(
) throws JMSException

JMSXプロパティ名

public Enumeration getJMSXPropertyNames(
) throws JMSException

ConnectionMetaDataクラスの詳細は、javax.jms.ConnectionMetaDataのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionMetaData.html)を参照してください。

接続の開始、停止、クローズ

メッセージのフローを制御するために、次のstart()メソッドとstop()メソッドをそれぞれ使用して、接続を一時的に開始および停止できます。

start()メソッドとstop()メソッドの詳細は以下のとおりです。

public void start(
) throws JMSException

public void stop(
) throws JMSException

新しく作成された接続は停止しています。接続が開始されるまで、メッセージは受信されません。一般に、他のJMSオブジェクトは、「JMSアプリケーションの設定」で説明するとおり、接続が開始される前からメッセージを処理するよう設定されます。メッセージは、停止している接続上に作成することはできますが、停止している接続に届けることはできません。

接続が開始されていれば、stop()メソッドを使用して接続を停止できます。このメソッドは、次の手順を実行します。

- すべてのメッセージの配信を中断します。接続が再起動されるか、そのメッセージに関連付けられている存続時間に達するまで、メッセージの受信を待っているアプリケーションは何も返しません。

- 現在メッセージを処理しているすべてのメッセージ・リスナーが完了するまで待機します。

一般に、JMSプロバイダは接続を作成するときに大量のリソースを割り当てます。接続が使用されなくなったら、その接続をクローズしてリソースを解放する必要があります。接続をクローズするには、次のメソッドを使用します。

public void close(
) throws JMSException

このメソッドは、次の手順を実行して系統的にシャットダウンを行います。

- 保留中のすべてのメッセージの受信を終了させます。アプリケーションは、クローズ時にメッセージを受信できない場合はメッセージまたはnullを戻す場合があります。

- 現在メッセージを処理しているすべてのメッセージ・リスナーが完了するまで待機します。

- 処理中のトランザクションを、そのトランザクション・セッション上でロールバックします(こうしたトランザクションが外部JTAユーザー・トランザクションの一部である場合を除く)。JTAユーザー・トランザクションの詳細は、「JTAユーザー・トランザクションの使い方」を参照してください。

- クライアントが確認応答を行うセッションの確認応答は強制しません。確認応答を強制しないことにより、キューおよび信頼性の高い処理が要求される恒久サブスクリプション用のメッセージが失われなくなります。

接続をクローズすると、関連付けられているすべてのオブジェクトがクローズされます。受信メッセージのacknowledge()メソッドを除いて、接続で作成または受信されたメッセージ・オブジェクトは引続き使用できます。クローズされた接続をクローズしても影響はありません。

注意:
クローズされた接続のセッションから受信したメッセージを確認応答しようとすると、IllegalStateExceptionがスローされます。

セッションの管理

以下の節では、セッションを管理する方法について説明します。

- セッション例外リスナーの定義

- セッションのクローズ

セッション例外リスナーの定義

例外リスナーは、セッションに問題が発生すると、クライアントに非同期的に通知します。これは、通知されない限りセッションがメッセージの消費を待ち続ける場合に役立ちます。

注意:
例外リスナーの目的は、セッションによってスローされたすべての例外をモニターすることではなく、本来なら通知されない例外を通知することです。

セッションに対する例外リスナーを定義するには、次のWLSessionメソッドを使用します。

public void setExceptionListener(
ExceptionListener listener
) throws JMSException

セッションに対するExceptionListenerオブジェクトを指定しなければなりません。

JMSプロバイダは、セッションの問題を発見すると、次のExceptionListenerメソッドを使用して例外リスナー(定義されている場合)に通知します。

public void onException(
JMSException exception
)

JMSプロバイダは、このメソッドを呼び出すときに、問題を説明する例外を指定します。

セッションに対する例外リスナーにアクセスするには、次のWLSessionメソッドを使用します。

public ExceptionListener getExceptionListener(
) throws JMSException

注意:
1つのセッションに対して1つのスレッドしか存在しないので、例外リスナーとメッセージ・リスナー(非同期メッセージ配信用に使用される)を同時に実行することはできません。そのため、問題が発生したときにメッセージ・リスナーが実行されている場合、そのメッセージ・リスナーが実行を完了するまで例外リスナーはブロックされます。メッセージ・リスナーの詳細は、「メッセージの非同期受信」を参照してください。

セッションのクローズ

接続と同じように、JMSプロバイダはセッションを作成するときに大量のリソースを割り当てます。セッションが使用されなくなったら、そのセッションをクローズしてリソースを解放することをお薦めします。セッションをクローズするには、次のSessionメソッドを使用します。

public void close(
) throws JMSException

注意:
close()メソッドは、セッション・スレッドとは別個のスレッドから呼び出すことができる唯一のSessionメソッドです。

このメソッドは、次の手順を実行して系統的にシャットダウンを行います。

- 保留中のすべてのメッセージの受信を終了させます。アプリケーションは、クローズ時にメッセージを受信できない場合はメッセージまたはnullを戻す場合があります。

- 現在メッセージを処理しているすべてのメッセージ・リスナーが完了するまで待機します。

- 処理中のトランザクションをロールバックします(こうしたトランザクションが外部JTAユーザー・トランザクションの一部である場合を除く)。JTAユーザー・トランザクションの詳細は、「JTAユーザー・トランザクションの使い方」を参照してください。

- クライアントが確認応答を行うセッションの確認応答は強制しません。これにより、キューおよび信頼性の高い処理が要求される恒久サブスクリプション用のメッセージが失われなくなります。

セッションをクローズすると、関連付けられているすべてのプロデューサとコンシューマもクローズされます。

注意:
onMessage()メソッド呼出し内でclose()メソッドを発行する場合、システム管理者は接続ファクトリを構成するときに「メッセージの短縮を許可」チェック・ボックスを選択しなければなりません。

宛先の管理

以下の節では、宛先の作成と削除の方法について説明します。

- 宛先の動的作成

- 宛先の動的削除

宛先の動的作成

宛先を動的に作成する方法については、以下のトピックを参照してください。

- 第7章「JMSモジュール・ヘルパーを使用したアプリケーションの管理」

- 一時的な宛先の使い方

宛先の動的作成に関する手順については、以降の節で説明します。

宛先の動的削除

次のいずれかの方法を使用して、JMS宛先(キューまたはトピック)を動的に削除できます。

- JMSModuleHelperクラス(第7章「JMSモジュール・ヘルパーを使用したアプリケーションの管理」を参照)

- 管理コンソール

- ユーザー定義JMXアプリケーション

JMSサーバーは削除された宛先をリアル・タイムに削除します。従って、削除を有効にするためにJMSサーバーを再デプロイする必要はありません。宛先の動的削除に関する手順については、以降の節で説明します。

宛先を削除するための事前条件

宛先の削除を正常に完了するには、次の事前条件が満たされている必要があります。

- 削除する宛先は分散宛先のメンバーであってはなりません。詳細は、第9章「分散宛先の使用」を参照してください。

- 削除する宛先は他の宛先のエラー宛先であってはなりません。詳細については、「配信されなかったメッセージに対するエラー宛先の構成」を参照してください。

これらの事前条件のいずれかが満たされていない場合、削除は実行できません。

宛先削除後の動作

宛先を削除する場合、以下の動作とセマンティクスが適用されます。

- 既存メッセージの物理的な削除 - 削除した宛先のすべての恒久サブスクライバが永続的に削除されます。削除した宛先に格納されているすべてのメッセージ(永続および非永続)が、メッセージング・システムから永続的に削除されます。

- プロデューサ、コンシューマ、およびブラウザの作成不可 - 宛先の削除後に、削除した宛先のプロデューサ、コンシューマ、またはブラウザをアプリケーションで作成することはできません。作成しようとすると、宛先が存在しない場合と同様に、アプリケーションはInvalidDestinationExceptionを受け取ります。

- コンシューマのクローズ - 削除した宛先の既存のコンシューマがすべてクローズされます。コンシューマのクローズによってConsumerClosedExceptionが生成され、親セッションのExceptionListener (存在する場合)に配信されます。この例外には「Destination was deleted」と示されます。
コンシューマがクローズされた時点でコンシューマに未処理のreceive()処理がある場合、その処理は取り消され、呼出し側はメッセージが存在しないことを示すnullを受け取ります。アプリケーションでclose()以外の実行を試みると、クローズされたコンシューマのIllegalStateExceptionが発生します。

- ブラウザのクローズ - 削除した宛先のブラウザがすべてクローズされます。アプリケーションでclose()以外の実行を試みると、クローズされたブラウザのIllegalStateExceptionが発生します。ブラウザのクローズにより、ブラウザに関連付けられたすべての列挙値が暗黙的にクローズされます。

- 列挙値のクローズ - 削除した宛先の列挙値がすべてクローズされます。列挙値がクローズされた後の動作は、列挙値のクローズ前に実行した最後の呼出しによって異なります。hasMoreElements()の呼出しでtrueの値が返され、以降にnextElement()を呼び出していない場合は、列挙により次の要素を列挙できることが保証されます。その結果、詳細が生成されます。クローズ前の最後の呼出しがhasMoreElements()を呼び出し、返された値がtrueであった場合は、以下の動作が適用されます。

- nextElement()の最初の呼出しではメッセージが返されます。

- 以降のnextElement()の呼出しではNoSuchElementExceptionがスローされます。

- nextElement()の呼出し前にhasMoreElements()を呼び出すと、trueが返されます。

- nextElement()の最初の呼出し前にhasMoreElements()を呼び出すと、falseが返されます。

ある特定の列挙値が一度も呼び出されていないか、クローズ前の最後の呼出しがnextElement()を呼び出した場合、またはクローズ前の最後の呼出しがhasMoreElements()を呼び出し、返された値がfalseであった場合には、以下の動作が適用されます。

- hasMoreElements()の呼出しではfalseが返されます。

- nextElement()の呼出しではNoSuchElementExceptionがスローされます。

- 送信ブロック処理の取消し - 削除した宛先に対して送信された送信ブロック処理がすべて取り消されます。割当てを待機している送信処理はResourceAllocationExceptionを受け取ります。

- コミットしていないトランザクションには影響しない - 宛先を削除しても、コミットしていない既存のトランザクションには影響しません。削除した宛先に関連付けられたコミットしていない作業は、トランザクションの一部として完了できます。ただし、宛先は削除されているため、すべての処理(ロールバック、コミットなど)で実際に実行されるのは関連付けられたメッセージの削除です。

削除された宛先のトラブルシューティングに使用するメッセージのタイムスタンプ

永続メッセージがある宛先が、削除されてからすぐに再作成され、そのときJMSサーバーが動作中でなかった場合、JMSサーバーは宛先のバージョン番号(構成ファイルconfig.xmlのCreationTimeフィールドを使用)と永続メッセージ内の宛先バージョン番号を比較します。この場合、古い宛先に残っている永続メッセージのバージョン番号は、config.xmlファイルにある再作成された宛先のバージョン番号よりも古い番号になります。JMSサーバーが再起動すると、残っている永続メッセージは破棄されます。

ただし、永続メッセージのバージョン番号が、再作成された宛先のconfig.xmlにあるバージョン番号よりも新しい場合は、宛先が削除されてから(JMSサーバーが動作中でない状態で)再作成されたときにシステム・クロックがロールバックされたか、異なるconfig.xmlが使用されています。この場合、JMSサーバーの起動が失敗します。永続メッセージを保存するために、永続メッセージ内のバージョン番号に一致するバージョン番号(CreationTimeフィールド)をconfig.xmlに設定できます。または、config.xmlのバージョン番号を、永続メッセージ内のバージョン番号よりも新しい番号に変更できます。このようにすると、JMSサーバーは再起動時にメッセージを削除できます。

削除した宛先の統計

削除した宛先およびホストするJMSサーバーに関する統計は、メッセージが物理的に削除されたときに更新されます。ただし、別の処理の結果が出るまで削除が遅れるメッセージもあります。このようなメッセージには、トランザクションで送受信されるメッセージや、クライアントが受信する確認応答されていない非トランザクション・メッセージが含まれます。

一時的な宛先の使い方

一時的な宛先を使用することで、サーバー定義の宛先の構成と作成に伴うシステム管理のオーバーヘッドを発生させずに、必要に応じてアプリケーションで宛先を作成できます。

JMSアプリケーションでは、JMSReplyToヘッダー・フィールドを使用して、リクエストにレスポンスを戻すことができます。送信側アプリケーションでは、オプションとして、メッセージのJMSReplyToヘッダー・フィールドをその一時的な宛先の名前に設定することで、使用している一時的な宛先を別のアプリケーションに対して公開できます。

一時的な宛先は、「一時的な宛先の削除」の説明のとおりにdelete()メソッドを使用して削除されない限り、現在の接続が継続している間だけ存在します。

サーバーが再起動すると、メッセージは使用できなくなるので、すべてのPERSISTENTメッセージは自動的にNON_PERSISTENTメッセージになります。そのため、一時的な宛先は、再起動によるデータの消失が許されないビジネス・ロジックには適していません。

注意:
一時的な宛先は、JMSサーバーの「一時的なテンプレートをホスト」属性ではデフォルトで有効化されています。ただし、一時的な宛先を特定の設定で作成する場合は、一時的なテンプレートのデフォルト値を、JMSサーバーの一時的なテンプレートおよび「一時的なテンプレートを含むモジュール」属性を使用して変更する必要があります。詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJMSサーバーの一般的なプロパティの構成に関する項を参照してください。

以降の節では、一時的なキュー(PTP)または一時的なトピック(Pub/Sub)の作成方法について説明します。

一時的なキューの作成

次のQueueSessionメソッドを使用して、一時的なキューを作成できます。

public TemporaryQueue createTemporaryQueue(
) throws JMSException

たとえば、現在の接続が継続している間だけ存在するTemporaryQueueへの参照を作成するには、次のメソッド呼出しを使用します。

QueueSender = Session.createTemporaryQueue();

一時的なトピックの作成

次のTopicSessionメソッドを使用して、一時的なトピックを作成できます。

public TemporaryTopic createTemporaryTopic(
) throws JMSException

たとえば、現在の接続が継続している間だけ存在する一時的なトピックへの参照を作成するには、次のメソッド呼出しを使用します。

TopicPublisher = Session.createTemporaryTopic();

一時的な宛先の削除

一時的な宛先の使用が終了したら、次のTemporaryQueueメソッドまたはTemporaryTopicメソッドを使用して宛先を削除し、関連リソースを解放できます。

public void delete(
) throws JMSException

恒久サブスクリプションの設定

WebLogic JMSでは、恒久サブスクリプションおよび非恒久サブスクリプションがサポートされています。

恒久サブスクリプションの場合、WebLogic JMSでは、メッセージはサブスクライバに配信されるか、または期限切れになるまで永続ファイルまたはデータベースに格納されます。この場合、メッセージの配信時にサブスクライバがアクティブな状態でなくてもかまいません。サブスクライバを表すJavaオブジェクトが存在していれば、サブスクライバはアクティブであるとみなされます。恒久サブスクリプションは、Pub/Subメッセージングのみでサポートされています。

注意:
恒久サブスクリプションは、分散トピックに対しては作成できません。ただし、分散トピックのメンバーに対して恒久サブスクリプションを作成することはできます。こうすると、他のトピック・メンバーは、恒久サブスクリプションを持つメンバーにメッセージを転送します。分散トピックの使用方法については、第9章「分散宛先の使用」を参照してください。

非恒久サブスクリプションの場合、WebLogic JMSでは、メッセージはアクティブ・セッションを持つアプリケーションにのみ配信されます。アプリケーションがリスニングしていない間にトピックへ送信されたメッセージは、二度とそのアプリケーションに配信されません。つまり、非恒久サブスクリプションは、そのサブスクライバ・オブジェクトが存在している間だけ存続します。デフォルトでは、サブスクライバは非恒久です。

以降の節で説明する内容は、次のとおりです。

- 永続ストアの定義

- クライアントIDポリシーの設定

- クライアントIDの定義

- 共有サブスクリプション・ポリシーの作成

- 恒久サブスクリプション用のサブスクライバの作成

- ベスト・プラクティス:問題が発生したJMS ClientIDは常に閉じる

- 恒久サブスクリプションの削除

- 恒久サブスクリプションの変更

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

永続ストアの定義

メッセージがサブスクライバに配信されるか、または期限切れになるまでWebLogic JMSがそのメッセージを保持できるようにするためには、永続ファイルまたはデータベース・ストアを構成してJMSサーバーに割り当てる必要があります。

- 「ストア」ノードを使用して、JMSファイル・ストアまたはJMS JDBCバッキング・ストアを作成します。

- 「JMSサーバー」>「構成」>「全般」タブのストア・フィールドのドロップダウン・リストから構成済みのストアを選択してJMSサーバーに割り当てます。

注意:
2つのJMSサーバーで同じバッキング・ストアを使用することはできません。

クライアントIDポリシーの設定

クライアントIDポリシーは、1つ以上のJMS接続がクラスタ内で同一のクライアントIDを使用できるかどうかを指定します。このポリシーの有効な値は次のとおりです。

- RESTRICTED: デフォルトです。このポリシーを使用する接続は、クラスタ内で特定のクライアントIDの所定の時間に1つのみ存在できます(接続が所定のクライアントIDを使用してすでに存在する場合、このポリシーを同一クライアントIDと併用して新しい接続を作成しようとする試行は、例外を表示して失敗します)。

- UNRESTRICTED: このポリシーを使用して作成された接続は、他の制限/無制限接続がすでに同一クライアントIDを使用する場合でも、任意のクライアントIDを指定できます。恒久サブスクリプションが無制限クライアントIDを使用して作成されるとき、そのサブスクリプションはweblogic.jms.extensions.WLSession.unsubscribe(Topic topic, String name)を使用してのみクリーンアップできます。『Oracle WebLogic Server JMSのプログラミング』の「恒久サブスクリプションの管理」も参照してください。

(使用するアプリケーションのアーキテクチャに排他的クライアントIDが必要にならないかぎり)特にサブスクリプション(恒久/非恒久)を共有する場合は、新しいアプリケーションに対してはクライアントIDポリシーをUnrestrictedを設定することをお薦めします。異なるクライアントIDポリシーを使用して作成されたサブスクリプションは、常に単独のサブスクリプションとして扱われます。『Oracle WebLogic Server MBeanリファレンス』のClientIdPolicyに関する項を参照してください。

WebLogicコンソールを使用して接続ファクトリ上でクライアントIDポリシーを設定する場合、Oracle WebLogic Server管理コンソール・ヘルプの同一クライアントIDを使用した複数接続の構成に関する項を参照してください。接続ファクトリ設定は、『Oracle WebLogic Server APIリファレンス』のWLConnectionインタフェースのsetClientIDPolicyメソッドを使用して、プログラム的にオーバーライドできます。

高可用性アプリケーションの設計に必要な、高度な概念および共通分散トピック(UDT)の機能の詳細は、「共有サブスクリプションおよびクライアントIDポリシー」を参照してください。

クライアントIDの定義

恒久サブスクリプションをサポートするには、接続に対してクライアントIDを定義する必要があります。

注意:
JMSクライアントIDは、WebLogicセキュリティ・レルムでのユーザー認証で使用されるWebLogic Serverユーザー名とは必ずしも一致しません。JMSアプリケーションに適合していれば、JMSクライアントIDをWebLogic Serverユーザー名に設定することは当然可能です。

クライアントIDは、以下の2つの方法で設定できます。

- 最初の方法は、クライアントIDを使用する接続ファクトリを構成することです。WebLogic JMSでは、この方法は各クライアントIDの構成時に別々の接続ファクトリの定義を追加することになります。アプリケーションでは、JNDIでそれ自身のトピック接続ファクトリがルックアップされ、それを使用して自身のクライアントIDを含む接続が作成されます。Oracle WebLogic Server管理コンソール・ヘルプを参照してください。

- または、望ましい方法として、接続を作成してからアプリケーションで次のConnectionメソッドを呼び出して、接続にクライアントIDを設定する方法もあります。

public void setClientID(
String clientID
) throws JMSException

この代替方法を使用する場合は、デフォルトの接続ファクトリを使用すると(アプリケーションに適合している場合)、構成情報を変更する必要がありません。ただし、恒久サブスクリプションに対応しているアプリケーションの場合は、トピック接続を作成したらすぐにsetClientID()を呼び出すようにする必要があります。

クライアントIDが接続に対してすでに定義されている場合は、IllegalStateExceptionがスローされます。指定したクライアントIDが別の接続に対してすでに定義されている場合は、InvalidClientIDExceptionがスローされます。

注意:
setClientID()メソッドを使用してクライアントIDを指定する場合には、重複したクライアントIDが例外のスローなしに指定されてしまう危険性があります。たとえば、2つの異なる接続に対して、同じ値を持つクライアントIDが同時に設定されると、競合状態のまま、同じ値が両方の接続に割り当てられる場合があります。このような重複の危険性を回避するには、構成時にクライアントIDを指定します。

クライアントIDを表示し、クライアントIDがすでに定義されているかどうかをテストするには、次のConnectionメソッドを使用します。

public String getClientID(
) throws JMSException

注意:
恒久サブスクリプションのサポートは、Pub/Subメッセージング・モデル固有の機能なので、クライアントIDはトピック接続でしか使用できません。キュー接続にもクライアントIDがありますが、JMSでは使用されません。
恒久サブスクリプションは、一時的なトピックに対しては作成しないでください。一時的なトピックは、現在の接続が継続している間だけ存在するように設計されているからです。

共有サブスクリプション・ポリシーの作成

サブスクリプション共有ポリシーは、サブスクライバがサブスクリプションを同一接続上の他のサブスクリプションを共有できるかどうかを指定します。このポリシーの有効な値は次のとおりです。

- Exclusive: デフォルトです。この接続ファクトリを使用して作成されるすべてのサブスクライバは、サブスクリプションを他のサブスクリプションと共有できません。このポリシーを使用してWebLogic Server 10.3.4.0以前の機能を保持できます。

- Sharable: この接続ファクトリを使用して作成されたサブスクライバは、サブスクライバが同一の接続ファクトリまたは異なる接続ファクトリのどちらを使用して作成されたかに関係なく、サブスクリプションを他のサブスクライバと共有できるようになります。コンシューマは、同一のクライアントIDおよびクライアントIDポリシーを持つ場合にのみ非永続サブスクリプションを共有できます。また、同一のクライアントID、クライアントIDポリシー、およびサブスクリプション名を持つ場合にのみ永続スクリプトを共有できます。

WebLogic JMSアプリケーションは、javax.jms.Connectionインスタンスをweblogic.jms.extension.WLConnectionにキャストしてsetSubscriptionSharingPolicy(String)を呼び出すことによって、接続ファクトリ構成上で指定されるサブスクリプション共有ポリシーをオーバーライドできます。

共有可能なサブスクリプション共有ポリシーを使用する大半のアプリケーションは、同一クライアントIDを使用する複数の接続が存続できることを保証するために無制限クライアントIDポリシーも使用できます。

同一クライアントIDおよびサブスクリプション名を持つ2つの恒久サブスクリプションは、異なるクライアントIDポリシーを持つ場合、2種類の独自のサブスクリプションとして扱われます。同様に、同一クライアントIDを持つ2つの共有可能な非恒久サブスクリプションは、異なるクライアントIDポリシーを持つ場合、2種類の独自のサブスクリプションとして扱われます。

サブスクリプション共有ポリシーを使用する方法の詳細は、次を参照してください。

- Oracle WebLogic Server管理コンソール・ヘルプの接続ファクトリ・サブスクリプション共有ポリシーの構成に関する項。

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

恒久サブスクリプション用のサブスクライバの作成

以下のTopicSessionメソッドを使用して、恒久サブスクリプション用のサブスクライバを作成できます。

public TopicSubscriber createDurableSubscriber(
Topic topic,
String name
) throws JMSException

public TopicSubscriber createDurableSubscriber(
Topic topic,
String name,
String messageSelector,
boolean noLocal
) throws JMSException

サブスクライバを作成するトピックの名前と恒久サブスクリプションの名前を指定する必要があります。

注意:
恒久サブスクリプションの名前に含めることのできない文字は、カンマ(,)、等号(=)、コロン(:)、アスタリスク(*)、パーセント記号(%)、および疑問符(?)です。

また、メッセージをフィルタ処理するためのメッセージ・セレクタ、およびnoLocalフラグ(この節で後述)を指定することもできます。メッセージ・セレクタの詳細は、「メッセージのフィルタ処理」を参照してください。messageSelectorを指定しない場合、デフォルトではすべてのメッセージが検索されます。

アプリケーションでは、JMS接続を使用して同じトピックに対してパブリッシュとサブスクライブの両方を実行できます。トピック・メッセージはすべてのサブスクライバに配信されるので、アプリケーションは自身がパブリッシュしたメッセージを受信する可能性があります。これを防ぐために、JMSアプリケーションはnoLocalフラグをtrueに設定できます。noLocal値は、デフォルトではfalseになっています。恒久サブスクリプションはファイルまたはデータベース内に格納されます。

ベスト・プラクティス: 問題が発生したJMS ClientIDは常に閉じる

問題が発生したJMS接続については、ベスト・プラクティスとして、アプリケーションでJVMガベージ・コレクションを使用してクリーンアップするのではなく、JMSクライアントで常にclose()メソッドを呼び出してクリーンアップすることをお薦めします。これは、JMS自動再接続機能では、問題が発生したJMS接続への参照が保持されるため、恒久サブスクリプションのClientIDに関しては特に重要です。したがって、常にconnection.close()を使用して接続をクリーンアップします。また、接続リソースを確実にクリーンアップするため、finallyブロックを使用することも検討してください。このようにしない場合、接続を使用可能な状態に維持するためにシステム・リソースが割り当てられてしまいます。

次のコード・スニペットでは、close()およびfinallyをJMSクライアントで使用して問題が発生した接続リソースをクリーンアップする例を示しています。

JMSConnection con = null;
try {
con = cf.createConnection();
con.setClientID("Fred");
// Do some I/O stuff;
}
finally {
if (con != null) con.close();
}

JMS自動再接続機能の詳細は、「JMSクライアントの自動フェイルオーバー」を参照してください。

恒久サブスクリプションの削除

恒久サブスクリプションを削除するには、次のTopicSessionメソッドを使用します。

public void unsubscribe(
String name
) throws JMSException

削除する恒久サブスクリプションの名前を指定する必要があります。

以下の条件のいずれかに当てはまる場合は、恒久サブスクリプションを削除できません:

- TopicSubscriberがセッションでまだアクティブです。

- 恒久サブスクリプションで受信したメッセージがトランザクションの一部であるか、またはセッションでまだ確認応答されていません。

注意:
管理コンソールを使用して恒久サブスクリプションを削除することもできます。恒久サブスクリプションの管理については、「恒久サブスクリプションの管理」を参照してください。

恒久サブスクリプションの変更

恒久サブスクリプションを変更するには、次のステップを実行します:

1. 必要に応じて、「恒久サブスクリプションの削除」の手順に従って恒久サブスクリプションを削除します。
この手順は省略可能です。この手順が明示的に実行されない場合は、次の手順で恒久サブスクリプションが再作成されるときに暗黙的に削除が行われます。

2. 「恒久サブスクリプション用のサブスクライバの作成」で説明されているメソッドを使用して、同じ名前の恒久サブスクリプションを再作成します。ただし、トピック名、メッセージ・セレクタ、noLocalのいずれかには異なる値を指定します。
新しい値に基づいて、恒久サブスクリプションが再作成されます。

注意:
恒久サブスクリプションを再作成する場合には、重複した名前を持つ恒久サブスクリプションを作成しないよう注意してください。たとえば、使用できないJMSサーバーから恒久サブスクリプションを削除しようとすると、削除は失敗します。続いて、別のJMSサーバーで同じ名前の恒久サブスクリプションを作成すると、最初のJMSサーバーが使用可能になったときに予期しない結果が生じることがあります。元の恒久サブスクリプションが削除されていないため、最初のJMSサーバーが再び使用可能になると、重複した名前の2つの恒久サブスクリプションが存在することになります。

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

管理コンソールまたはパブリックな実行時APIを使用して、恒久トピック・サブスクライバをモニターおよび管理できます。恒久サブスクライバ上のすべてのメッセージを表示、参照したり、ほとんどのメッセージを操作したりすることもできます。こうした管理機能には、メッセージの参照(ソート目的)、メッセージの操作(移動、削除など)、メッセージのインポートとエクスポートなどがあります。詳細は、『Oracle WebLogic Server JMSの構成と管理』のJMSメッセージの管理に関する項を参照してください。

メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照

WebLogic JMSには、メッセージの識別および転送を定義できる一連の標準ヘッダー・フィールドが用意されています。さらに、プロパティ・フィールドを使用すると、標準セットを拡張した、アプリケーション固有のヘッダー・フィールドをメッセージ内に含めることができます。メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドを使用して、通信しているプロセス間で情報をやり取りできます。

データをメッセージ本文ではなくプロパティ・フィールドに含める主要な理由は、メッセージ・セレクタを使用したメッセージのフィルタ処理をサポートするためです。XMLメッセージ拡張機能以外では、メッセージ・セレクタからメッセージ本文のデータにアクセスすることはできません。たとえば、プロパティ・フィールドを使用して、あるメッセージに高い優先度を割り当てると仮定します。その場合、このプロパティ・フィールドにアクセスし、至急の優先度が指定されたメッセージだけを選択するメッセージ・セレクタを含むメッセージ・コンシューマを作成できます。セレクタの詳細は、「メッセージのフィルタ処理」を参照してください。

メッセージ・ヘッダー・フィールドの設定

JMSメッセージには、常にメッセージと共に送信されるヘッダー・フィールドの標準セットが含まれます。これらはメッセージを受信するメッセージ・コンシューマで利用でき、また、一部のフィールドはメッセージを送信するメッセージ・プロデューサで設定できます。メッセージを受信したら、ヘッダー・フィールドの値は変更できます。

ヘッダー・フィールドの値を変更(オーバーライド)する際は、メッセージ・フィールドがJMSサブシステムによってオーバーライドされる場合があることを考慮に入れる必要があります。たとえば、プロデューサで優先順位を設定するとメッセージの優先順位に影響しますが、send()メソッドに提供された値はプロデューサの設定をオーバーライドします。同様に、宛先で設定した値は、プロデューサによって設定された値や、send()メソッドに提供された値をオーバーライドします。ヘッダー・フィールドの値を検証するには、send()メソッドの後にメッセージに対して問合せを実行するしかありません。

標準メッセージ・ヘッダー・フィールドの詳細は、「メッセージ・ヘッダー・フィールド」を参照してください。

次の表に、Messageクラスのsetメソッドとgetメソッドを、サポートされているデータ型ごとに示します。

注意:
set()メソッドを使用して設定されたヘッダー・フィールド値は、send()メソッドによってオーバーライドされる場合もあります(次表参照)。

表6-3 JMSヘッダー・フィールド・メソッド

ヘッダー・フィールド

setメソッド

getメソッド

JMSCorrelationID

public void setJMSCorrelationID(
String correlationID
) throws JMSException

public String getJMSCorrelationID(
) throws JMSException

public byte[] getJMSCorrelationIDAsBytes(
) throws JMSException

JMSDestinationFoot 1

public void setJMSDestination(
Destination destination
) throws JMSException

public Destination getJMSDestination(
) throws JMSException

JMSDeliveryMode1

public void setJMSDeliveryMode(
int deliveryMode
) throws JMSException

public int getJMSDeliveryMode(
) throws JMSException

JMSDeliveryTime1

public void setJMSDeliveryTime(
long deliveryTime
) throws JMSException

public long getJMSDeliveryTime(
) throws JMSException

JMSDeliveryMode1

public void setJMSDeliveryMode(
int deliveryMode
) throws JMSException

public int getJMSDeliveryMode(
) throws JMSException

JMSMessageID1

public void setJMSMessageID(
String id
) throws JMSException

注意: setメソッドだけでなく、weblogic.jms.extensions.JMSRuntimeHelperクラスには、WebLogic JMS 6.0以前のJMSMessageID形式をWebLogic JMS 6.1の形式に(またはWebLogic JMS 6.1の形式をそれ以前の形式に)変換する、以下のメソッドも用意されています。

public void oldJMSMessageIDToNew(
String id,
long timeStamp
) throws JMSException

public void newJMSMessageIDToOld(
String id,
long timeStamp
) throws JMSException

public String getJMSMessageID(
) throws JMSException

JMSPriority1

public void setJMSPriority(
int priority
) throws JMSException

public int getJMSPriority(
) throws JMSException

JMSRedelivered1

public void setJMSRedelivered(
boolean redelivered
) throws JMSException

public boolean getJMSRedelivered(
) throws JMSException

JMSRedeliveryLimit1

public void setJMSRedeliveryLimit(
int redelivered
) throws JMSException

public int getJMSRedeliveryLimit(
) throws JMSException

JMSReplyTo

public void setJMSReplyTo(
Destination replyTo
) throws JMSException

public Destination getJMSReplyTo(
) throws JMSException

JMSTimeStamp1

public void setJMSTimeStamp(
long timestamp
) throws JMSException

public long getJMSTimeStamp(
) throws JMSException

JMSType

public void setJMSType(
String type
) throws JMSException

public String getJMSType(
) throws JMSException

脚注 1 send()メソッドが実行されている場合、対応するset()メソッドは、メッセージ・ヘッダー・フィールドに影響を与えません。ヘッダー・フィールド値が設定されている場合は、send()メソッドの処理中に、このヘッダー・フィールド値がオーバーライドされます。

WL_HOME\samples\server\examples\src\examples\jms\senderディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)に収められているWebLogic Server付属のexamples.jms.sender.SenderServletの例では、送信するメッセージのヘッダー・フィールドを設定する方法、および送信後にメッセージのヘッダー・フィールドを表示する方法を示します。

たとえば、send()メソッドの後に置く次のコードは、WebLogic JMSによってメッセージに割り当てられたメッセージIDを表示します。

System.out.println("Sent message " +
msg.getJMSMessageID() + " to " +
msg.getJMSDestination());

メッセージ・プロパティ・フィールドの設定

プロパティ・フィールドを設定するには、適切なsetメソッドを呼び出して、プロパティ名と値を指定します。プロパティ・フィールドを参照するには、適切なgetメソッドを呼び出して、プロパティ名を指定します。

送信側アプリケーションはメッセージにプロパティを設定でき、受信側アプリケーションはそのプロパティを表示できます。受信側アプリケーションがプロパティを変更するには、まず次のclearProperties()メソッドを使用してプロパティを消去する必要があります。

public void clearProperties(
) throws JMSException

このメソッドは、メッセージ・ヘッダー・フィールドおよびメッセージ本文は消去しません。

注意:
JMS用にJMSXというプロパティ名の接頭辞が予約されています。接続メタデータには、JMSXプロパティのリストが含まれています。getJMSXPropertyNames()メソッドを使用して、列挙リストとして、このリストにアクセスできます。詳細については、「接続メタデータへのアクセス」を参照してください。
プロバイダ固有のプロパティ用にJMS_というプロパティ名の接頭辞が予約されています。この接頭辞は標準のJMSメッセージングでは使用できません。

プロパティ・フィールドは、boolean、byte、double、float、int、long、short、stringの各データ型のいずれかに設定できます。次の表に、Messageクラスのsetメソッドとgetメソッドを、サポートされているデータ型ごとに示します。

表6-4 メッセージ・プロパティのデータ型ごとのsetメソッドおよびgetメソッド

データ型

setメソッド

getメソッド

boolean

public void setBooleanProperty(
String name,
boolean value
) throws JMSException

public boolean getBooleanProperty(
String name
) throws JMSException

byte

public void setByteProperty(
String name,
byte value
) throws JMSException

public byte getByteProperty(
String name
) throws JMSException

double

public void setDoubleProperty(
String name,
double value
) throws JMSException

public double getDoubleProperty(
String name
) throws JMSException

float

public void setFloatProperty(
String name,
float value
) throws JMSException

public float getFloatProperty(
String name
) throws JMSException

int

public void setIntProperty(
String name,
int value
) throws JMSException

public int getIntProperty(
String name
) throws JMSException

long

public void setLongProperty(
String name,
long value) throws JMSException

public long getLongProperty(
String name
) throws JMSException

short

public void setShortProperty(
String name,
short value
) throws JMSException

public short getShortProperty(
String name
) throws JMSException

String

public void setStringProperty(
String name,
String value
) throws JMSException

public String getStringProperty(
String name
) throws JMSException

上記の表で説明したsetメソッドおよびgetメソッド以外にも、setObjectProperty()メソッドおよびgetObjectProperty()メソッドを使用して、プロパティのデータ型の具体的なプリミティブ値を使用できます。具体的な値が使用されている場合、プロパティのデータ型はコンパイル時ではなく、実行時に決定されます。有効なオブジェクトのデータ型は、boolean、byte、double、float、int、long、short、およびstringです。

次のMessageメソッドを使用して、すべてのプロパティ・フィールド名にアクセスできます。

public Enumeration getPropertyNames(
) throws JMSException

このメソッドは、すべてのプロパティ・フィールド名を列挙して返します。その後、プロパティ・フィールドのデータ型に基づいて、上記の表で説明されている適切なgetメソッドにプロパティ・フィールド名を渡すことで、各プロパティ・フィールドの値を取り出すことができます。

表6-5は、メッセージ・プロパティの変換チャートです。この表から、読込み可能なデータ型を、書き込まれたデータ型に基づいて識別できます。左端以外の列のいずれかに挿入されている「可」は、左端の列にリストされている、メッセージが書き込まれたプロパティの各データ型に対して、各列の一番上にリストされているデータ型としてメッセージを読み込むことができるということを意味しています。

表6-5 メッセージ・プロパティの変換チャート

書き込まれたプロパティのデータ型

boolean

byte

double

float

int

long

short

String

boolean

はい

いいえ

いいえ

いいえ

いいえ

いいえ

いいえ

はい

byte

いいえ

はい

いいえ

いいえ

はい

はい

はい

はい

double

いいえ

いいえ

はい

いいえ

いいえ

いいえ

いいえ

はい

float

いいえ

いいえ

はい

はい

いいえ

いいえ

いいえ

はい

int

いいえ

いいえ

いいえ

いいえ

はい

はい

いいえ

はい

long

いいえ

いいえ

いいえ

いいえ

いいえ

はい

いいえ

はい

Object

はい

はい

はい

はい

はい

はい

はい

はい

short

いいえ

いいえ

いいえ

いいえ

はい

はい

はい

はい

String

はい

はい

はい

はい

はい

はい

はい

はい

次のMessageメソッドを使用して、プロパティの値が設定されているかどうかをテストできます。

public boolean propertyExists(
String name
) throws JMSException

プロパティ名を指定すると、メソッドはそのプロパティが存在するかどうかを示すブール値を返します。

たとえば、次のコードは、2種類のStringプロパティと1種類のintプロパティを設定します。

msg.setStringProperty("User", user);
msg.setStringProperty("Category", category);
msg.setIntProperty("Rating", rating);

メッセージ・プロパティ・フィールドの詳細は、「メッセージ・プロパティ・フィールド」またはjavax.jms.MessageのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Message.html)を参照してください。

メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの参照

注意:
参照できるのは、キューのメッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドだけです。トピックのメッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドは参照できません。

以下のQueueSessionメソッドを使用して、キューにあるメッセージのヘッダー・フィールドおよびプロパティ・フィールドを参照できます。

public QueueBrowser createBrowser(
Queue queue
) throws JMSException

public QueueBrowser createBrowser(
Queue queue,
String messageSelector
) throws JMSException

参照するキューを指定する必要があります。また、参照するメッセージをフィルタ処理するメッセージ・セレクタを指定することもできます。メッセージ・セレクタの詳細は、「メッセージのフィルタ処理」を参照してください。

キューを定義すると、以下のQueueBrowserメソッドを使用して、キュー・ブラウザに関連付けられたキュー名およびメッセージ・セレクタにアクセスできるようになります。

public Queue getQueue(
) throws JMSException

public String getMessageSelector(
) throws JMSException

さらに、次のQueueBrowserメソッドを使用して、メッセージを参照するための列挙値にアクセスできます。

public Enumeration getEnumeration(
) throws JMSException

WL_HOME\samples\server\examples\src\examples\jms\queueディレクトリ(WL_HOMEはWebLogic Platformのインストール先の最上位ディレクトリ)にあるWebLogic Server付属のexamples.jms.queue.QueueBrowserサンプルは、受信メッセージのヘッダー・フィールドへのアクセス方法を示したものです。

たとえば、次のQueueBrowserの例からの引用コードでは、QueueBrowserオブジェクトを作成します。

qbrowser = qsession.createBrowser(queue);

次のコードは、QueueBrowserサンプルで定義されているdisplayQueue()メソッドからの引用です。この例では、QueueBrowserオブジェクトを使用して、キューのメッセージをスキャンする場合に使用される列挙値を取得します。

public void displayQueue(
) throws JMSException
{
Enumeration e = qbrowser.getEnumeration();
Message m = null;

if (! e.hasMoreElements()) {
System.out.println("There are no messages on this queue.");
} else {

System.out.println("Queued JMS Messages: ");
while (e.hasMoreElements()) {
m = (Message) e.nextElement();
System.out.println("Message ID " + m.getJMSMessageID() +
" delivered " + new Date(m.getJMSTimestamp())
" to " + m.getJMSDestination());
}
}

キュー・ブラウザが使用されていない場合は、キュー・ブラウザをクローズしてリソースを解放する必要があります。詳細については、「オブジェクト・リソースの解放」を参照してください。

QueueBrowserクラスの詳細は、javax.jms.QueueBrowserのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueBrowser.html)を参照してください。

メッセージのフィルタ処理

多くの場合、アプリケーションでは、配信されるすべてのメッセージが通知される必要はありません。メッセージ・セレクタを使用すると、不要なメッセージをフィルタ処理できるので、ネットワーク・トラフィックへの影響が最小限になり、パフォーマンスが向上します。

メッセージ・セレクタは、以下のように動作します。

- 送信側アプリケーションでは、標準化された方法でメッセージを説明したり分類したりするためのメッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドが設定されます。

- 受信側アプリケーションでは、単純な問合せ文字列を指定することで、アプリケーションで受信するメッセージがフィルタ処理されます。

メッセージ・セレクタはメッセージの内容(本文)を参照することができないため、情報の一部をメッセージ・プロパティ・フィールドに複製することもできます(XMLメッセージの場合を除く)。

キュー・レシーバまたはトピック・サブスクライバの作成時に、それぞれQueueSession.createReceiver()メソッドまたはTopicSession.createSubscriber()メソッドの引数としてセレクタを指定します。キュー・レシーバおよびトピック・サブスクライバの作成については、「ステップ5: メッセージ・プロデューサとメッセージ・コンシューマを作成する」を参照してください。

WebLogic JMSは、状態または現在の処理状態を処理中のメッセージに割り当てます。このような状態をセレクタとして使用できます。有効なメッセージ状態の詳細は、『Oracle WebLogic Server APIリファレンス』のweblogic.jms.extensions.JMSMessageInfoに関する項を参照してください。

以降の節では、SQL文とXMLセレクタ・メソッドを使用してメッセージ・セレクタを定義する方法、およびメッセージ・セレクタを更新する方法について説明します。ヘッダー・フィールドおよびプロパティ・フィールドの設定の詳細は、それぞれ「メッセージ・ヘッダー・フィールドおよびメッセージ・プロパティ・フィールドの設定と参照」、「メッセージ・プロパティ・フィールドの設定」を参照してください。

SQL文を使用したメッセージ・セレクタの定義

メッセージ・セレクタはブール式です。これは、SQL select文のwhere句と類似した構文を含む文字列から構成されます。

次の引用は、セレクタ式の例を示します。

salary > 64000 and dept in ('eng','qa')

(product like 'WebLogic%' or product like '%T3')
and version > 3.0

hireyear between 1990 and 1992
or fireyear is not null

fireyear - hireyear > 4

次の例では、キュー・レシーバの作成時に、優先度が6未満のメッセージをフィルタで除外するセレクタを設定する方法を示します。

String selector = "JMSPriority >= 6";
qsession.createReceiver(queue, selector);

次の例では、トピック・サブスクライバの作成時に、同様のセレクタを設定する方法を示します。

String selector = "JMSPriority >= 6";
qsession.createSubscriber(topic, selector);

メッセージ・セレクタ構文の詳細は、javax.jms.MessageのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/Message.html)を参照してください。

XMLセレクタ・メソッドを使用したXMLメッセージ・セレクタの定義

XMLメッセージ・タイプの場合、メッセージ・セレクタの定義には、前節で説明したSQLセレクタ式だけでなく、次のメソッドを使用することもできます。

String JMS_BEA_SELECT(String type, String expression)

JMS_BEA_SELECTは、WebLogic JMS SQL構文の組込み関数です。構文タイプとXPath式を指定します。構文タイプは、xpath (XML Path Language)に設定する必要があります。XML Path Languageは、XML Path Language (XPath)のドキュメントで定義されており、XML Path LanguageのWebサイトhttp://www.w3.org/TR/xpathで入手できます。

注意:
XMLメッセージの構文には十分注意してください。不正なXMLメッセージ(終了タグの欠落など)はどのXMLセレクタとも一致しません。

以下の環境では、メソッドはnull値を返します。

- メッセージによって解析されない場合

- メッセージによって解析されるが、要素がない場合

- メッセージによって解析され、要素も存在するが、メッセージに値が含まれていない場合(例: <order></order>)

たとえば、次のようなXMLの引用があります。

<order>
<item>
<id>007</id>
<name>Hand-held Power Drill</name>
<description>Compact, assorted colors.</description>
<price>$34.99</price>
</item>
<item>
<id>123</id>
<name>Mitre Saw</name>
<description>Three blades sizes.</description>
<price>$69.99</price>
</item>
<item>
<id>66</id>
<name>Socket Wrench Set</name>
<description>Set of 10.</description>
<price>$19.99</price>
</item>
</order>

次の例では、上記の引用にある2番目の項目の名前を取り出す方法を示します。メソッド呼出しは、Mitre Sawという文字列を返します。

String sel = "JMS_BEA_SELECT('xpath', '/order/item[2]/name/text()') = 'Mitre Saw'";

二重引用符と単一引用符、およびスペースの使い方に注意してください。xpath、XMLタブ、および文字列値が単一引用符で囲まれていることに注意してください。

次の例では、上記の引用にある3番目の項目のIDを取り出す方法を示します。メソッド呼出しは、66という文字列を返します。

String sel = "JMS_BEA_SELECT('xpath', '/order/item[3]/id/text()') = '66'";

メッセージ・セレクタの表示

次のMessageConsumerメソッドを使用して、メッセージ・セレクタを表示できます。

public String getMessageSelector(
) throws JMSException

このメソッドは、現在定義されているメッセージ・セレクタ、またはメッセージ・セレクタが定義されていない場合はnullのいずれかを返します。

トピック・サブスクライバのメッセージ・セレクタへの索引付けによるパフォーマンス最適化

アプリケーションの一部のクラスでは、WebLogic JMSでトピック・サブスクライバのメッセージ・セレクタに索引を付けることで最適化できます。通常、それらのアプリケーションはサブスクライバ数が多く、各サブスクライバに一意の識別子(ユーザー名など)が設定されています。また、単独のサブスクライバまたはサブスクライバのリストへメッセージを迅速に送信できる必要があります。一般的な例としては、各サブスクライバが異なるユーザーに対応し、各メッセージに1つまたは複数のターゲット・ユーザーのリストが含まれるインスタント・メッセージング・アプリケーションがあります。

最適化されたサブスクライバのメッセージ・セレクタをアクティブ化するには、サブスクライバはセレクタに以下の構文を使用する必要があります。

"identifier IS NOT NULL"

identifierは、あらかじめ定義されたJMSメッセージ・プロパティではない任意の文字列です(たとえば、JMSCorrelationIDでもJMSTypeでもない文字列)。複数のサブスクライバが同じ識別子を共有できます。

WebLogic JMSでは、このメッセージ・セレクタ構文を、内部サブスクライバ索引を構築するためのヒントとして使用します。構文に従っていないメッセージ・セレクタ、または追加のOR句およびAND句を含むメッセージ・セレクタも受け付けられますが、最適化はアクティブ化されません。

このメッセージ・セレクタ構文を使用してサブスクライバを登録すると、トピックにパブリッシュされるメッセージは、1つまたは複数の識別子をメッセージのユーザー・プロパティに追加することにより、特定のサブスクライバをターゲットにすることができます。次に例を示します。

// Set up a named subscriber, where "wilma" is the name of
// the subscriber and subscriberSession is a JMS TopicSession.
// Note that the selector syntax used activates the optimization.

TopicSubscriber topicSubscriber =
subscriberSession.createSubscriber(
(Topic)context.lookup("IMTopic"),
"Wilma IS NOT NULL",
/* noLocal= */ true);

// Send a message to subscribers "Fred" and "Wilma",
// where publisherSession is a JMS TopicSession. Subscribers
// with message selector expressions "Wilma IS NOT NULL"
// or "Fred IS NOT NULL" will receive this message.

TopicPublisher topicPublisher =
publisherSession.createPublisher(
(Topic)context.lookup("IMTopic");

TextMessage msg =
publisherSession.createTextMessage("Hi there!");
msg.setBooleanProperty("Fred", true);
msg.setBooleanProperty("Wilma", true);

topicPublisher.publish(msg);

注意:
最適化されたメッセージ・セレクタとメッセージ構文は、標準のJMS APIに基づいています。そのため、この構文を使用したアプリケーションは、最適化されたメッセージ・セレクタがないWebLogic JMSのバージョンや、WebLogic JMS以外の製品でも動作します。ただし、これらのバージョンの場合、この拡張機能を備えたバージョンに比べてパフォーマンスは劣ります。
メッセージ・セレクタを最適化しても、MULTICAST_NO_ACKNOWLEDGE確認応答モードを使用しているアプリケーションには効果がありません。このようなアプリケーションは、メッセージの選択がサーバー側ではなくクライアント側で行われるため、拡張の必要性はありません。

XMLメッセージの送信

注意:
このリリースでは、ストリーミングはサポートされていません。サポートされるのは、XMLドキュメントのテキスト表現とDOM表現のみです。

WebLogic Server JMS APIでは、XMLメッセージを送信するためのドキュメント・オブジェクト・モデル(DOM)のネイティブ・サポートも提供されています。

以下の節では、XMLメッセージの拡張サポートを提供するWebLogic JMS APIの拡張機能について説明します。

- WebLogic XML API

- String表現の使用

- DOM表現の使用

WebLogic XML API

String表現とDOM表現の間のXML変換には、以下のWebLogic XML APIを使用できます。

- XMLMessage - XMLコンテンツを含むメッセージの送信に使用します。

- WLSession.createXMLMessage - XMLメッセージの作成に使用します。

XMLMessageのペイロードは、あるXML表現を使用して設定し、別の表現を使用して取得できます。たとえば、XMLMessageの本文をString表現を使用して設定し、DOM表現を使用して取得することも可能です。

String表現の使用

string型を使用してXMLメッセージをパブリッシュするには、次の手順に従います。

1. XMLをStringWriterにシリアライズします。

2. StringWriterのtoStringを呼び出し、それをmessage.setTextに渡します。

3. メッセージをパブリッシュします。

DOM表現の使用

XMLメッセージをDOM表現を使用して送信すると、Stringとしてメッセージを送信する場合に比べパフォーマンスがかなり向上します。DOM表現を使用してXMLメッセージをパブリッシュするには、次の手順に従います。

1. 必要に応じて、XMLソースからDOMドキュメントを生成します。

2. DOMドキュメントをXMLMessage.setDocumentに渡します。

3. メッセージをパブリッシュします。

7 JMSモジュール・ヘルパーを使用したアプリケーションの管理

この章では、weblogic.jms.extensions.JMSModuleHelperを使用して、JMSサーバー、ストア・アンド・フォワード・エージェント、およびJMSシステム・リソースをプログラム的に作成および管理する方法について説明します。

- JMSModuleHelperを使用したJMSシステム・リソースの構成

- JMSサーバーとストア・アンド・フォワード・エージェントの構成

- JMSModuleHelperのサンプル・コード

- JMSModuleHelper使用時のベスト・プラクティス

JMSModuleHelperを使用したJMSシステム・リソースの構成

JMSModuleHelperは、システム・モジュールやJMSリソース(キュー、トピックなど)の管理に使用する以下のAPIシグネチャを提供します。

- リソースの作成

- リソースの作成と変更

- リソースの削除

- リソースの検索と変更

- テンプレートを使用した検索

システム・モジュールとそれに含まれるJMSリソースを管理するには、ドメインMBeanを提供するか、API署名内の管理サーバーに初期コンテキストを提供します。JMSシステム・リソースの詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの基本JMSシステム・リソースの構成に関する項を参照してください。

JMSサーバーとストア・アンド・フォワード・エージェントの構成

JMSModuleHelperは、JMSサーバーとストア・アンド・フォワード・エージェントの管理に使用する以下のメソッドAPIを提供します。

- JMSサーバーとストア・アンド・フォワード・エージェントの作成

- JMSサーバーとストア・アンド・フォワード・エージェントの削除

- JMSサーバーとストア・アンド・フォワード・エージェントのデプロイメント

- JMSサーバーとストア・アンド・フォワード・エージェントのアンデプロイメント

JMSサーバーとストア・アンド・フォワード・エージェントを管理するには、ドメインMBeanを提供するか、APIシグネチャ内の管理サーバーに初期コンテキストを提供します。詳細については、以下を参照してください。

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプの基本JMSシステム・リソースの構成に関する項。

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプのストア・アンド・フォワード・サービスの概要に関する項。

JMSModuleHelperのサンプル・コード

この節では、JMSシステム・リソース・モジュールを作成および削除するサンプル・コードを示します。

JMSシステム・リソースの作成

このモジュールには、接続ファクトリとトピックが含まれています。

例7-1 JMSシステム・リソースの作成

.
.
.
private static void createJMSUsingJMSModuleHelper(Context ctx){
System.out.println(
"\n\n.... Configure JMS Resource for C API Topic Example ....\n\n");

try {

MBeanHome mbeanHome =
(MBeanHome) ctx.lookup(MBeanHome.ADMIN_JNDI_NAME);
DomainMBean domainMBean = mbeanHome.getActiveDomain();
String domainMBeanName = domainMBean.getName();
ServerMBean[] servers = domainMBean.getServers();

String jmsServerName = "examplesJMSServer";

//
// create a JMSSystemResource "CapiTopic-jms"
//
String resourceName = "CapiTopic-jms";
JMSModuleHelper.createJMSSystemResource(
ctx,
resourceName,
servers[0].getName());
JMSSystemResourceMBean jmsSR =
JMSModuleHelper.findJMSSystemResource(
ctx,
resourceName);
JMSBean jmsBean = jmsSR.getJMSResource();
System.out.println("Created JMSSystemResource " + resourceName);

//
// create a JMSConnectionFactory "CConFac"
//
String factoryName = "CConFac";
String jndiName = "CConFac";
JMSModuleHelper.createConnectionFactory(
ctx,
resourceName,
factoryName,
jndiName,
servers[0].getName());
JMSConnectionFactoryBean factory =           jmsBean.lookupConnectionFactory(factoryName);
System.out.println("Created Factory " + factory.getName());

//
// create a topic "CTopic"
//
String topicName = "CTopic";
String topicjndiName = "CTopic";
JMSModuleHelper.createTopic(
ctx,
resourceName,
jmsServerName,
topicName,
topicjndiName);

TopicBean topic = jmsBean.lookupTopic(topicName);
System.out.println("Created Topic " + topic.getName());
} catch (Exception e) {
System.out.println("Example configuration failed :" + e.getMessage());
e.printStackTrace();
}
}
.
.
.

JMSシステム・リソースの削除

次のコードは、JMSシステム・リソースを削除します。

例7-2 JMSシステム・リソースの削除

.
.
.
private static void deleteJMSUsingJMSModuleHelper(Context ctx ) {

System.out.println("\n\n.... Remove JMS System Resource for C API Topic Example ....\n\n");

try {

MBeanHome mbeanHome =
(MBeanHome) ctx.lookup(MBeanHome.ADMIN_JNDI_NAME);
DomainMBean domainMBean = mbeanHome.getActiveDomain();
String domainMBeanName = domainMBean.getName();
ServerMBean[] servers = domainMBean.getServers();

String jmsServerName = "examplesJMSServer";

//
// delete JMSSystemResource "CapiTopic-jms"
//
String resourceName = "CapiTopic-jms";
JMSModuleHelper.deleteJMSSystemResource(
ctx,
resourceName
);
} catch (Exception e) {
System.out.println("Example configuration failed :" + e.getMessage());
e.printStackTrace();
}
}
.
.
.

JMSModuleHelper使用時のベスト・プラクティス

この節では、JMSModuleHelperを使用してJMSサーバーおよびリソースを構成するときのベスト・プラクティスを示します。

- MBeanオブジェクトを操作する前に、Null MBeanオブジェクト(サーバー、JMSサーバー、モジュールなど)をトラップします。

- メソッド呼出しの作成または削除は、例外をスローせずに失敗する可能性があります。また、例外がスローされても、それが必ずしもメソッド呼出しの失敗を示しているとは限りません。

- JMSサーバーでの宛先の作成とJNDIネームスペースへの情報の伝播には、時間がかかる場合があります。複数のサーバーを使用している環境では、伝播の遅延が増大します。JNDIルックアップを実行するよりも、createQueue()メソッドまたはcreateTopic()メソッドを使用して、それぞれキューまたはトピックの存在をテストすることをお薦めします。この方法によって、伝播固有の遅延を、ある程度回避できます。
たとえば、次に示すfindQueue()メソッドは、動的に作成されたキューにアクセスしようとしますが、アクセスに失敗すると再試行まで、指定された間隔スリープします。無限ループを回避するために、再試行の最大回数が設定されています。

private static Queue findQueue (
QueueSession queueSession,
String jmsServerName,
String queueName,
int retryCount,
long retryInterval
) throws JMSException
{
String wlsQueueName = jmsServerName + "/" + queueName;
String command = "QueueSession.createQueue(" +
wlsQueueName + ")";
long startTimeMillis = System.currentTimeMillis();
for (int i=retryCount; i>=0; i--) {
try {
System.out.println("Trying " + command);
Queue queue = queueSession.createQueue(wlsQueueName);
System.out.println(command + "succeeded after " +
(retryCount - i + 1) + " tries in " +
(System.currentTimeMillis() - startTimeMillis) +
" millis.");
return queue;
} catch (JMSException je) {
if (retryCount == 0) throw je;
}
try {
System.out.println(command + "> failed, pausing " +
retryInterval + " millis.");
Thread.sleep(retryInterval);
} catch (InterruptedException ignore) {}
}
throw new JMSException("out of retries");
}

この場合、JMSModuleHelperクラス・メソッドの後にfindQueue()メソッドを呼び出すことで、動的に作成されたキューを使用可能になり次第、取り出すことができます。例:

JMSModuleHelper.createPermanentQueueAsync(ctx, domain, jmsServerName,
queueName, jndiName);
Queue queue = findQueue(qsess, jmsServerName, queueName,
retry_count, retry_interval);

8 WebLogic JMSでのマルチキャストの使い方

この章では、WebLogic JMSマルチキャストを使用することによって、後でメッセージをクラスタ内のサブスクライバに転送する、指定したホストのグループにメッセージを配信する方法について説明します。

- マルチキャストを使用する利点

- マルチキャストを使用する上での制限事項

- WebLogic Serverでのマルチキャストの構成

マルチキャストを使用する利点

マルチキャストには、次のような利点があります。

- ホスト・グループにメッセージをほとんどリアルタイムに配信できます。

- メッセージをクラスタ内のトピック・サブスクライバに配信する場合にJMSサーバーで必要になるリソース量が削減されるので、スケーラビリティが向上します。

マルチキャストを使用する上での制限事項

マルチキャストには、次のような制限があります。

- マルチキャストでは、ホスト・グループの全メンバーに対するメッセージの配信は保証されません。確実な配信とリカバリが必要なメッセージについては、マルチキャストを使用しないでください。

- WebLogic Serverの様々なバージョンとの相互運用性を確保するために、ホストより前のリリースのWebLogic Serverをクライアントにインストールすることはできません。すべてのクライアントにホストと同じバージョンかそれより上のバージョンをインストールする必要があります。

マルチキャストを使用すると便利な例としては、株価表示があります。最新の株価を入手する場合に重要になるのは、信頼性よりもタイムリな配信です。全部または一部の内容が配信されなくても、リアルタイムの株価情報にアクセスするときに、クライアントは簡単に情報の再送信をリクエストできます。クライアントでは情報のリカバリは必要とされません。回復された情報が再配信される頃には、その情報は古くて価値のないものになっています。

WebLogic Serverユニキャストの使用

WebLogic Serverでは、マルチキャスト以外の方法でクラスタのメッセージングおよび通信を処理することもできます。ユニキャストは、マルチキャストのようなネットワーク間構成を必要としない単純な構成です。加えて、マルチキャスト・アドレスの競合によって発生する可能性がある潜在的なネットワーク・エラーが低減されます。

JMSトピックは、クラスタ・アドレスに依存しない独自のマルチキャスト・アドレスに対してメッセージをパブリッシュするので、マルチキャスト向けに構成されたJMSトピックでもユニキャスト向けに構成されたWebLogicクラスタにアクセスできます。ただし、以下の点を考慮に入れてください。

- ユニキャスト・クラスタが使用できるようにルーター・ハードウェアを構成すると、JMSマルチキャスト・サブスクライバが機能しない場合があります。

- JMSマルチキャスト・サブスクライバは、マルチキャスト・アクセスが可能なネットワーク・ハードウェア構成を必要とします。

詳細は、『Oracle WebLogic Serverクラスタの使用』の「クラスタでの通信」を参照してください。

WebLogic Serverでのマルチキャストの構成

次の図に、マルチキャストの設定に必要な手順を示します。

図8-1 マルチキャストの設定

「図8-1 マルチキャストの設定」の説明

注意:
マルチキャストは、Pub/Subメッセージング・モデル、および非恒久サブスクライバのみでサポートされています。
マルチキャスト・セッションおよびマルチキャスト・コンシューマに関するモニター統計は提供されません。

マルチキャストの前提条件

マルチキャストを設定する前に、マルチキャストをサポートするよう、次のように接続ファクトリおよび宛先を構成する必要があります。

- 各接続ファクトリについては、システム管理者が、マルチキャスト・セッションに存在できる未処理のメッセージの最大数と、最大数に達した場合に最新のメッセージと最古のメッセージのどちらを破棄するかを構成します。メッセージが最大数に達すると、DataOverrunExceptionがスローされ、メッセージは自動的に破棄されます。これらの属性は、動的に構成することもできます(「マルチキャストの構成属性の動的構成」を参照)。

- 各宛先については、マルチキャスト・アドレス(IP)、ポート、TTL (存続時間)の各属性を指定します。TTL属性の設定の詳細は、「例: マルチキャストTTL (存続時間)」を参照してください。

注意:
マルチキャストIPアドレス、ポート、存続時間の各属性を構成する場合は、ネットワーク管理者に相談の上、適切な値を設定することを強くお薦めします。

詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックのマルチキャスト・パラメータの構成に関する項を参照してください。

ステップ1: JMSアプリケーション、マルチキャスト・セッション、およびトピック・サブスクライバを設定する

「JMSアプリケーションの設定」に説明されているとおりにJMSアプリケーションを設定します。ただし、セッションを作成する際は、「ステップ3: 接続を使用してセッションを作成する」に説明されているように、acknowledgeModeの値をMULTICAST_NO_ACKNOWLEDGEに設定して、セッションがマルチキャスト・メッセージを受信するように指定します。

注意:
マルチキャストは、Pub/Subメッセージング・モデル、および非恒久サブスクライバのみでサポートされています。マルチキャスト・セッションで恒久サブスクライバを作成しようとすると、JMSExceptionがスローされます。

たとえば、次のメソッドは、Pub/Subメッセージング・モデル用のマルチキャスト・セッションの作成方法を示します。

JMSModuleHelper.createPermanentQueueAsync(ctx, domain, jmsServerName,
queueName, jndiName);
Queue queue = findQueue(qsess, jmsServerName, queueName,
retry_count, retry_interval);

注意:
クライアント側では、マルチキャスト・セッションごとに、ソケットからメッセージを取り出すための専用のスレッドが1つ必要になります。そのため、JMSクライアント側のスレッド・プール・サイズを増やして調整する必要があります。

さらに、「TopicPublisherとTopicSubscriberの作成」の説明に従って、トピック・サブスクライバを作成します。

たとえば、次のコードは、トピック・サブスクライバの作成方法を示します。

tsubscriber = tsession.createSubscriber(myTopic);

注意:
指定した宛先がマルチキャストをサポートするよう構成されていない場合、createSubscriber()メソッドは失敗します。

ステップ2: メッセージ・リスナーを設定する

マルチキャストのトピック・サブスクライバでは、メッセージを非同期に受信することしかできません。マルチキャスト・セッションで同期メッセージを受信しようとすると、JMSExceptionがスローされます。

「メッセージの非同期受信」の説明に従って、トピック・サブスクライバに対してメッセージ・リスナーを設定します。

たとえば、次のコードは、メッセージ・リスナーの設定方法を示します。

tsubscriber.setMessageListener(this);

メッセージを受信すると、WebLogic JMSでは、宛先から送信されたメッセージのシーケンスがトラッキングされます。マルチキャスト・サブスクライバのメッセージ・リスナーがシーケンスの異なるメッセージを受信すると、その結果、1つまたは複数のメッセージがスキップされ、そのセッションのExceptionListenerにSequenceGapExceptionがスローされます。スキップされたメッセージは、その後配信されても破棄されます。たとえば、次の図では、サブスクライバは2つの宛先から同時にメッセージを受信しています。

図8-2 マルチキャストにおけるシーケンスのずれ

「図8-2 マルチキャストにおけるシーケンスのずれ」の説明

宛先1からメッセージ「4」を受信すると、SequenceGapExceptionがスローされ、シーケンスの異なるメッセージが受信されたことがアプリケーションに通知されます。その後、メッセージ「3」が配信されても、それは破棄されます。

注意:
やり取りされるメッセージ数が多くなるほど、SequenceGapExceptionが発生する危険性も大きくなります。

マルチキャストの構成属性の動的構成

システム管理者は、構成時に、マルチキャストをサポートするよう、各接続ファクトリに対して以下の情報を構成します。

- マルチキャスト・セッションに存在できる未処理のメッセージの最大数を指定する、最大メッセージ数

- メッセージが最大数に達した場合に、最新のメッセージと最古のメッセージのどちらを破棄するかを指定する、超過時のポリシー

メッセージが最大数に達すると、DataOverrunExceptionがスローされ、メッセージは超過時のポリシーに基づいて自動的に破棄されます。また、Sessionクラスのsetメソッドを使用して、最大メッセージ数と超過時のポリシーを設定する方法もあります。

次の表に、Sessionクラスのsetメソッドとgetメソッドを、動的構成が可能な属性ごとに示します。

表8-1 メッセージ・プロデューサのsetメソッドおよびgetメソッド

属性

setメソッド

getメソッド

最大メッセージ数

public void setMessagesMaximum(
int messagesMaximum
) throws JMSException

public int getMessagesMaximum(
) throws JMSException

超過時のポリシー

public void setOverrunPolicy (
int overrunPolicy
) throws JMSException

public int getOverrunPolicy(
) throws JMSException

注意:
setメソッドを使用して設定された値は、構成された値よりも優先されます。

Sessionクラスのメソッドの詳細は、weblogic.jms.extensions.WLSessionのJavadocを参照してください。これらのマルチキャスト構成属性の詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックのマルチキャスト・パラメータの構成に関する項を参照してください。

例: マルチキャストTTL (存続時間)

注意:
次の図は、マルチキャストTTL (存続時間)宛先構成属性が、ルーターを経由したメッセージの配信に影響する様子を説明するための単純な例です。マルチキャストTTL属性を構成する場合は、ネットワーク管理者に相談してから、適切な値を設定することをお薦めします。
マルチキャストTTLは、メッセージの存続時間に依存しません。

次の例では、マルチキャストTTL宛先構成属性が、ルーターを経由したメッセージの配信に影響する様子を示します。

詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのトピックのマルチキャスト・パラメータの構成に関する項を参照してください。

次のようなネットワーク図があります。

図8-3 マルチキャストTTLの例

「図8-3 マルチキャストTTLの例」の説明

この図では、ネットワークは3つのサブネットで構成されています。サブネットAにはマルチキャスト・パブリッシャがあり、サブネットBおよびCにはそれぞれ1台ずつマルチキャスト・サブスクライバがあります。

マルチキャストTTL属性が0に設定されている(メッセージはルーターを経由できず、現在のサブネットにしか配信されないことを示す)場合は、サブネットAにあるマルチキャスト・パブリッシャでメッセージがパブリッシュされても、メッセージはどのマルチキャスト・サブスクライバにも配信されません。

マルチキャストTTL属性が1に設定されている(メッセージは1台のルーターを経由できることを示す)場合、サブネットAにあるマルチキャスト・パブリッシャでメッセージがパブリッシュされると、サブネットBにあるマルチキャスト・サブスクライバでメッセージが受信されます。

同様に、マルチキャストTTL属性が2に設定されている(メッセージは2台のルーターを経由できることを示す)場合、サブネットAにあるマルチキャスト・パブリッシャでメッセージがパブリッシュされると、サブネットBおよびCにあるマルチキャスト・サブスクライバでメッセージが受信されます。

9 分散宛先の使用

この章では、可用性の高い(HA)アプリケーションを設計する上で必要となる分散宛先の概念と機能について説明します。

- 分散宛先とは

- 分散宛先を使用する理由

- 分散宛先の作成

- 分散宛先の種類

- 分散宛先の使用

- 分散宛先でのメッセージドリブンBeanの使用

- 分散宛先の一般的な使用例

分散宛先とは

分散宛先は、クライアントから単一の論理的な宛先としてアクセスできる宛先(キューまたはトピック)のセットです。分散宛先は、以下の特性を備えています。

- 独自のJNDIによって参照されます。

- 通常、分散宛先のメンバーはクラスタ内の複数のサーバーに分散されており、各宛先メンバーは別々のJMSサーバーに属しています。

分散宛先を使用する理由

分散宛先を使用するアプリケーションは、単純な宛先を使用するアプリケーションより可用性が高くなります。WebLogic JMSは、クラスタ内の分散宛先のメンバーのためのロード・バランシングとフェイルオーバーの機能を備えているからです。一度適切に構成すると、プロデューサとコンシューマがその分散宛先に対してメッセージを送受信できるようになります。WebLogic JMSは、分散宛先のすべてのメンバー間でメッセージングの負荷を分散します。サーバーの障害で宛先メンバーがアクセスできなくなった場合、トラフィックはセット内の他のアクセス可能な宛先メンバーにリダイレクトされます。宛先メンバーのロード・バランシングの詳細は、『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」を参照してください。

分散宛先の作成

分散宛先は、システム管理者が管理コンソールを使用して作成します。詳細は、『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」を参照してください。

分散宛先の種類

WebLogic Serverでは、以下の2種類の分散宛先がサポートされます。

- 共通分散宛先

- 重み設定された分散宛先

共通分散宛先

共通分散宛先(UDD)では、各メンバーには、すべての分散宛先パラメータ(重み、セキュリティ、永続性、ページング、割り当てなどに関するパラメータ)の一貫した構成が設定されます。

Oracleでは、UDDを使用することを推奨しています。UDDを使用すると、宛先のメンバーを作成したり指定したりする必要がなくなるためです。代わりに、WebLogic Serverによって、UDDの対象となるJMSサーバー上に必要なメンバーが均等に作成されます。この機能により、新しいメンバーを追加したりメンバーを削除したりしたときに、UDDが動的に更新されます。

たとえば、UDDをクラスタにターゲット指定した場合、そのクラスタ内のすべてのJMSサーバーにUDDメンバーが構成されます。新しいJMSサーバーを追加すると、UDDに新しいUDDメンバーが動的に追加されます。同様に、JMSサーバーを削除すると、対応するUDDメンバーがUDDから削除されます。これにより、構成エラーによるボトルネックが解消され、アプリケーションの可用性を高めることができます。詳細は、『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」を参照してください。

重み設定された分散宛先

注意:
重み設定された分散宛先は、WebLogic Server 10.3.4.0では非推奨です。共通分散宛先を使用することをお薦めします。

重み設定された分散宛先では、各メンバーには、すべての分散宛先パラメータ(重み、セキュリティ、永続性、ページング、割り当てなどに関するパラメータ)の一貫した構成が設定されません。

Oracleでは、重み設定された分散宛先をUDDに変換することを推奨しています。これは、重み設定によって追加のメッセージ負荷や容量をサポートするメンバーを作成すると、管理上の柔軟性が失われることがあるためです。重み設定された宛先は、メンバーの構成に一貫性がないためクラスタに矛盾なくデプロイすることができず、予期しない管理上の問題やアプリケーションの問題につながる可能性があります。

詳細は、『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」を参照してください。

分散宛先の使用

分散宛先は、物理的なJMS宛先メンバー(キューまたはトピック)のセットで、単一のJNDI名でアクセスされます。そのため、JNDIを使用することで分散宛先をルックアップできます。javax.jms.Destinationインタフェース(http://download.oracle.com/javaee/5/api/javax/jms/Destination.html)が実装され、プロデューサ、コンシューマ、およびブラウザの作成に使用できます。

分散宛先の参照の取得については、「宛先のルックアップ方法」を参照してください。

- 分散キューの使用

- レプリケートされた分散トピックの使用

- パーティション化された分散トピックの使用

分散キューの使用

分散キューは、一連の物理的なJMSキューのメンバーです。したがって、分散キューはQueueSender、QueueReceiver、およびQueueBrowserを作成するために使用できます。分散キューが複数の物理的キューを表すという事実は、アプリケーションには全く意識されません。

キューのメンバーはどこにでも配置できますが、単一のサーバー・クラスタ内にあるJMSサーバーからサービスを受ける必要があります。分散キューに送信されるメッセージは、分散キューの一連のメンバー内にある物理的キューの1つだけに送られます。キューのメンバーに届いたメッセージは、そのキューのメンバーのコンシューマのみが受信できるようになります。

この節では、分散キューの使用について説明します。

- キューの転送

- QueueSender

- QueueReceiver

- QueueBrowser

キューの転送

キューのメンバーがメッセージをキューの他のメンバーに転送できるようにするには、管理コンソールの「転送の遅延」属性を構成します。この属性は、コンシューマではなく、メッセージだけを持つ分散キューのメンバーが、コンシューマを持つキューの他のメンバーにメッセージを転送するときに待機する時間を秒単位で定義します。デフォルトでは、分散キューのメンバー間で転送する場合、配信回数がリセットされます。「ResetDeliveryCountOnForward」を参照してください。

QueueSender

キュー・センダーを作成した後、作成時に提供したキューが分散キューであった場合は、センダーを使用してメッセージが作成されるたびに、どのキューのメンバーがそのメッセージを受信するかの判断が下されます。各メッセージは単一の物理的キューのメンバーに送信されます。

メッセージが複製されることは一切ありません。このため、メッセージは送信元のキューのメンバーのみから受信できます。メッセージの受信前にその物理的キューが使用できなくなった場合は、そのキューのメンバーがオンラインに復帰するまでこのメッセージを受信できなくなります。

メッセージを分散キューに送信して、その分散キューのキュー・レシーバがメッセージを受信することを期待するだけでは十分とは言えません。メッセージは1つの物理的キューのメンバーだけに送信されるため、そのキューのメンバーで受信またはリスニングするキュー・レシーバが存在する必要があります。

注意:
コンシューマを持たない分散キューに対するロード・バランシングのヒューリスティックについては、『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」を参照してください。

QueueReceiver

キュー・レシーバを作成する際は、提供したキューが分散キューの場合、単一の物理的キューのメンバーが作成時にレシーバとして選ばれます。作成されたQueueReceiverは、キュー・レシーバがキュー・メンバーのアクセスを失うまでそのキュー・メンバーに固定されます。この時点で、コンシューマは次のようにJMSExceptionを受信します。

- キュー・レシーバが同期レシーバである場合は、例外がユーザーに直接返されます。

- キュー・レシーバが非同期レシーバである場合は、例外がConsumerClosedExceptionの内部に配信され、それがコンシューマ・セッションに定義されているExceptionListener (存在する場合)に配信されます。

このような例外を受信した場合、アプリケーションは自分のキュー・レシーバを終了し、再作成できます。分散キュー内で他のキュー・メンバーを使用できる場合は、新しいキュー・レシーバが作成され、これらのキュー・メンバーのいずれかに固定されます。他のキュー・メンバーを使用できない場合、キュー・レシーバの再作成はできないため、後で作成を試みる必要があります。

注意:
コンシューマを持たない分散キューに対するロード・バランシングのヒューリスティックについては、『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」を参照してください。

QueueBrowser

キュー・ブラウザを作成する際は、提供されているキューが分散キューの場合、単一の物理的キューのメンバーが作成時にブラウザとして選ばれます。作成されたキュー・ブラウザは、レシーバがキュー・メンバーのアクセスを失うまでそのキュー・メンバーに固定されます。その時点でキュー・ブラウザを呼び出した場合は、JMSExceptionが発行されます。列挙を呼び出した場合は、NoSuchElementExceptionが返されます。

注意:
キュー・ブラウザは固定されているキュー・メンバーのみを閲覧できます。分散キューが作成時に指定されている場合でも、キュー・ブラウザが分散宛先内の他のキュー・メンバーのメッセージを表示または閲覧することはできません。

レプリケートされた分散トピックの使用

分散トピックは、一連の物理的なJMSトピックのメンバーです。このため、分散トピックはTopicPublisherとTopicSubscriberを使用して作成できます。分散トピックが複数の物理的トピックを表すという事実は、アプリケーションには全く意識されません。

注意:
恒久サブスクライバ(DurableTopicSubscriber)は、分散トピックに対しては作成できません。ただし、分散トピックのメンバーに対して恒久サブスクリプションを作成することはできます。こうすると、他のトピック・メンバーは、恒久サブスクリプションを持つトピック・メンバーにメッセージを転送します。

トピック・メンバーはどこにでも配置できますが、単一のWebLogic Server、またはクラスタ内の任意の数のサーバーによってサービスを受ける必要があります。分散トピックに送信されたメッセージは、分散トピック・セット内のトピック・メンバーすべてに送信されます。このため、分散トピックのすべてのサブスクライバは、分散トピック用にパブリッシュされたメッセージを受信できます。

分散宛先のトピック・メンバーに直接パブリッシュされたメッセージ(つまりパブリッシャが宛先を指定しなかったメッセージ)も、その分散トピックのメンバーすべてに転送されます。これには、最初に分散トピックをサブスクライブしたサブスクライバと、その特定のトピック・メンバーにたまたま割り当てられているサブスクライバが含まれます。つまり、特定の分散トピックのメンバーにメッセージをパブリッシュすると、それが分散トピックの他のメンバーすべてに自動的に転送されます。これは、分散トピックにメッセージをパブリッシュすると、その分散トピックのメンバーすべてにメッセージが自動的に転送されることと同じです。特定の分散宛先メンバーのルックアップについては、「分散宛先メンバーへのアクセス」を参照してください。

この項では、分散トピックの使用について説明します。

- TopicPublisher

- TopicSubscriber

- 分散トピックへのメッセージドリブンBeanのデプロイ

TopicPublisher

トピック・パブリッシャを作成する際、提供されている宛先が分散宛先である場合には、その分散宛先に送信されるメッセージは次のように、分散トピックのアクセス可能なトピック・メンバーすべてに送信されます。

- 1つまたは複数の分散トピック・メンバーにアクセスできず、送信するメッセージが非永続的である場合、メッセージはアクセス可能なトピック・メンバーのみに送信されます。

- 1つまたは複数の分散トピック・メンバーにアクセスできず、送信するメッセージが永続的である場合、メッセージは格納され、アクセスできなかったメンバーにアクセスできるようになったときに転送されます。ただし、トピック・メンバーにJMSストアが構成されている場合は、メッセージの永続的な保管のみが行われます。

注意:
永続ストアを利用している分散メンバーに対しては、最初にメッセージを転送するためにあらゆる努力がなされます。ただし、分散メンバーがいずれもストアを利用していない場合でも、メッセージは『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」で説明されるように、選択されているロード・バランシング・アルゴリズムに従って、いずれかのメンバーに送信されます。

- 分散トピック・メンバーすべてにアクセスできない場合(メッセージが永続的であるか非永続的であるかにかかわらず)は、パブリッシャがメッセージを送信しようとしたときにJMSExceptionが発行されます。

TopicSubscriber

トピック・サブスクライバを作成するとき、提供されているトピックが分散トピックの場合、トピック・サブスクライバはその分散トピックにパブリッシュされたメッセージを受信します。トピック・サブスクライバが分散トピックのトピック・メンバーの1つまたは複数にアクセスできない場合は、メッセージが永続的であるか非永続的であるかに応じて次の事態が発生します。

- アクセスできない1つまたは複数の分散トピック・メンバーにパブリッシュされた永続メッセージは、これらのメンバーがアクセス可能になったときに、これらのメンバーのトピック・サブスクライバによって受信されます。ただし、トピック・メンバーにJMSストアが構成されている場合は、メッセージの永続的な保管のみが行われます。

- アクセスできない分散トピック・メンバーにパブリッシュされた非永続メッセージは、そのトピック・サブスクライバには送信されません。

注意:
JMSストアが分散トピック・メンバーをホストするJMSサーバー用に構成されている場合は、そのメンバーの宛先に関連付けられているすべての分散トピック・システム・サブスクライバが恒久サブスクリプションとして処理されます。これは、トピック・メンバーにJMSストアが明示的に構成されていない場合も同様です。したがって、これらの分散トピック・サブスクライバに送信されるすべてのメッセージをメモリーに保存すると、メモリーやディスクが予想以上に消費されるおそれがあります。分散宛先をデプロイする場合のベスト・プラクティスとしてお薦めする設計は、恒久メッセージ用のJMSストアがある場合でも、非恒久メッセージ用のJMSストアがない場合でも、すべてのメンバー宛先を同じように構成することです。たとえば、すべての分散トピック・サブスクライバを非恒久にした上で、一部のメンバー宛先に暗黙的にJMSストアを構成し、それらに関連付けられたJMSサーバーがJMSストアを使用するようにしたい場合は、各メンバー宛先のStoreEnabled属性を明示的にFalseに設定してJMSサーバーの設定をオーバーライドする必要があります。

最終的に、トピック・サブスクライバは物理的なトピック・メンバーに固定されます。そのトピック・メンバーにアクセスできなくなった場合は、次のようにトピック・サブスクライバにJMSExceptionが発行されます。

- トピック・サブスクライバが同期サブスクライバである場合は、例外がユーザーに直接返されます。

- トピック・サブスクライバが非同期サブスクライバである場合は、例外がConsumerClosedExceptionの内部に配信され、それがコンシューマ・セッションに定義されているExceptionListener (存在する場合)に配信されます。

このような例外を受信した場合、アプリケーションはトピック・サブスクライバを終了して再作成できます。分散トピック内のその他のトピック・メンバーにアクセス可能な場合は、新しいトピック・サブスクライバが作成され、これらのトピック・メンバーのいずれかに固定されます。他のトピック・メンバーにアクセスできない場合、トピック・サブスクライバの再作成はできないため、後で作成を再試行する必要があります。

分散トピックへのメッセージドリブンBeanのデプロイ

MDBxをトピック上でデプロイする方法の詳細は、『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』の分散トピックを使用したMDBの構成およびデプロイに関する項を参照してください。

パーティション化された分散トピックの使用

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

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

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

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

パーティション化された分散トピックの使用に関する詳細は、拡張パブリッシュ/サブスクライブ・アプリケーションの開発に関する項を参照してください。

分散宛先メンバーへのアクセス

分散宛先とそのメンバーにアクセスする方法については、「宛先のルックアップ方法」を参照してください。

分散宛先のフェイルオーバー

注意:
キュー・プロデューサが作成された分散キュー・メンバーに障害が発生したが、プロデューサのJMS接続が存在するWebLogic Serverインスタンスがまだ実行されている場合、プロデューサは閉じられず、WebLogic JMSはロード・バランシング・オプションが有効になっているかどうかに関係なく別の分散キュー・メンバーにフェイルオーバーします。たとえば、WebLogicクラスタにWLSServer1、WLSServer2、およびWLSServer3があり、WLServer2に接続しているとします。サーバーWLSServer 2に障害が発生すると、プロデューサは残りのクラスタ・メンバーの1つにフェイルオーバーします。詳細は、『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」を参照してください。

障害が発生した分散宛先に接続されているクライアントをフェイルオーバーさせる方法としては、クライアント・コードに再接続ロジックを記述して、onExceptionを捕捉したら分散宛先に接続されるようにする方法が簡単です。

分散宛先でのメッセージドリブンBeanの使用

メッセージドリブンBean (MDB)は、JMSメッセージ・リスナー(イベントのかわりにメッセージを受信することを除いてイベント・リスナーと同様)として機能します。MDBの詳細は、以下を参照してください。

- 『Oracle Fusion Middleware Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』の「MDBとメッセージング・モデル」

- 『Oracle Fusion Middleware Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』の「MDBのデプロイ」

分散宛先の一般的な使用例

以下の節では、分散宛先を使用する場合の一般的な例を示します。

- 生成の最大化

- 可用性の最大化

- メッセージのスタック

生成の最大化

メッセージの生成を最大にするには、分散宛先の各メンバーをプロデューサとコンシューマに関連付けることをお薦めします。次の図は、ロード・バランシングを使用せず、共通分散宛先を使用して効率的に最大のメッセージ生成と高可用性を実現する方法を示しています。

図9-1 ペアになっているプロデューサとコンシューマ

「図9-1 ペアになっているプロデューサとコンシューマ」の説明

この場合、UDD1は2つの物理的なメンバー、D1およびD2で構成された共通分散宛先です。それぞれの物理的な宛先にはプロデューサとコンシューマのペアがあり、メッセージは実線のとおりに、効率的にプロデューサから宛先メンバーを介してコンシューマに渡されます。順序付けを使用している場合は、予期される順序単位ごとにプロデューサが必要です。「分散宛先で順序単位を使用する」を参照してください。

可用性の最大化

この節では、メッセージの可用性を最大にする方法について説明します。

キューの使用

プロデューサをコンシューマとペアにするのが理想的ですが、この方法が適切でない場合もあります。メッセージの消費速度は、アプリケーションのメッセージ・スループットを決定する制約要因です。メンバー宛先間でロード・バランシングを使用することにより、コンシューマの可用性を向上できます。この場合、コンシューマはプロデューサとペアになっていませんが、受信メッセージは次の使用可能なコンシューマにロード・バランシング・アルゴリズムに従ってロード・バランシングされます。

注意:
順序単位機能の組み合わせによっては、競合する順序単位メッセージ・ストリームが不足することがあります。これには、順序単位名が異なる処理中メッセージの数よりコンシューマの数が多くなったために、リソースが十分に利用されなくなった場合も含まれます。システムのパフォーマンスを最適化し、リソースが十分に利用されない状態を防ぐには、最大の負荷でアプリケーションをテストする必要があります。

トピックの使用

分散トピックを使用すると、各メンバー宛先はメッセージを分散トピックの他のすべてのメンバーに転送します。

図9-2 分散トピックの使用

「図9-2 分散トピックの使用」の説明

この場合、UDD1は2つの物理的なメンバー、D1およびD2で構成された共通分散宛先です。それぞれの物理的な宛先にはプロデューサとコンシューマのペアがあります。各コンシューマはプロデューサ1およびプロデューサ2から送信されるメッセージを受信します。

メッセージのスタック

この場合、プロデューサはUDDの1つのメンバーにメッセージを送信しますが、メッセージを受信できるコンシューマがありません。これは通常、プロデューサが宛先の1つ(D1)にメッセージを送信し、コンシューマが別の宛先(D2)のメッセージをリスニングしている場合に生じます。

図9-3 メッセージのスタック

「図9-3 メッセージのスタック」の説明

UDD1は2つの物理的なメンバー、D1およびD2で構成された共通分散宛先です。D1にはプロデューサがあり、D2にはコンシューマがあります。プロデューサとコンシューマのペアを使用するか、または宛先で転送を構成して、このような構成は回避してください。

10 メッセージ順序単位の使用

この章では、WebLogic JMSを使用する場合に、メッセージ順序単位を使用して厳格なメッセージ順序を指定する方法について説明します。

- メッセージ順序単位とは

- 順序単位によるメッセージ処理について

- メッセージ順序単位のケース・スタディ

- 順序単位の作成方法

- 現在の順序の取得

- メッセージ順序単位の高度なトピック

- メッセージ順序単位の制限事項

メッセージ順序単位とは

メッセージ順序単位はWebLogic Serverの付加価値機能です。スタンドアロンのメッセージ・プロデューサや、単体として動作するプロデューサのグループは、この機能を使用して複数のメッセージを処理順序に応じた1つの単位にグループ化できます。この単位を順序単位と呼び、この単位からのすべてのメッセージはその作成順に従って処理されます。

順序単位によるメッセージ処理について

以下の節では、JMS仕様に記述されているメッセージ処理と、WebLogic Serverのメッセージ順序単位機能を使用して拡張したメッセージ処理を比較します。

- JMS仕様に準拠したメッセージ処理

- 順序単位によるメッセージ処理

- 順序単位によるメッセージ配信

JMS仕様に準拠したメッセージ処理

Java Message Service仕様(http://www.oracle.com/technetwork/java/jms/index.html)ではメッセージ配信の順序付けが規定されていますが、この順序付けは非常に厳格に適用されます。プロデューサの単一のインスタンスとコンシューマの単一のインスタンスの間の順序が定義されますが、以下のような一般的な状況は考慮されていません。

- 1つのキューにある多数のコンシューマ。第9章「分散宛先の使用」を参照してください。

- 単一のプロデューサとして動作する、単一のアプリケーション内の複数のプロデューサ。第9章「分散宛先の使用」を参照してください。

- メッセージのリカバリまたはトランザクションのロールバック(これらの場合、同じプロデューサからの別のメッセージが、他のコンシューマに配信されて処理される可能性があります)。「処理中にメッセージが遅延した場合の処理」を参照してください。

- フィルタおよび宛先ソート・キーの使用。「メッセージ順序単位の高度なトピック」を参照してください。

順序単位によるメッセージ処理

メッセージ順序単位機能を使用すると、メッセージ・プロデューサや単体として動作するプロデューサのグループが、複数のメッセージを1つの単位にグループ化してメッセージを作成順に処理することが可能になります。単一のメッセージのメッセージ処理は、メッセージが確認応答、コミット、回復、またはロールバックされたときに完了します。メッセージのメッセージ処理が完了するまでは、その順序単位の残りの未処理メッセージがブロックされます。

この項では、メッセージ順序単位を使用した場合のJMS確認応答モードの規則(http://www.oracle.com/technetwork/java/jms/index.html)について説明します。

- 確認応答モードがCLIENT_ACKNOWLEDGE、AUTO_ACKNOWLEDGE、またはDUPS_OK_ACKNOWLEDGEである場合、順序単位のメッセージは並行処理されません。

- コンシューマをクローズすると、セッションの確認応答に関係なく、現在のメッセージ処理が完了します。

- CLIENT_ACKNOWLEDGE - アプリケーションがMessage.acknowledgeおよびSession.recoverを呼び出すと、順序単位内でどのメッセージの処理が完了したかが示されます。

- AUTO_ACKNOWLEDGE - receiveの呼出しからセッションが正常に返されたとき、または呼び出されたMessageListenerからセッションが正常に返されたときに、セッションが自動的にクライアントによるメッセージの受信を確認応答します。

- 非同期モード:正常な完了またはonMessage(msg)の例外は、メッセージが正常に処理されたタイミングを示します。

- 同期モード:特定のコンシューマ(たとえばコンシューマA)では、consumerA.receive、consumerA.setMessageListener、またはconsumerA.closeが発生したときにconsumerA.receiveが完了します。

- DUPS_OK_ACKNOWLEDGE - receiveの呼出しからセッションが正常に返されたとき、または呼び出されたMessageListenerからセッションが正常に返されたときに、セッションが自動的にクライアントによるメッセージの受信を確認応答します。

- 非同期モード:正常な完了またはonMessage(msg)の例外は、メッセージが正常に処理されたタイミングを示します。

- 同期モード:特定のコンシューマ(たとえばコンシューマA)では、consumerA.receive()、consumerA.setMessageListener()、またはconsumerA.close()が発生したときにconsumerA.receive()が完了します。

- NO_ACKNOWLEDGE - セッションは、処理の順序を保証しません。メッセージは、使用可能な別のコンシューマで並行処理できます。

順序単位によるメッセージ配信

メッセージ順序単位では、以下の規則に従ってメッセージが配信されます。

- 順序単位のメンバー・メッセージは、作成された順番でキュー・コンシューマに配信されます。順序単位内でのメッセージの順序は、ソート条件、優先順位、およびフィルタには影響されません。ただし、未コミットのメッセージにRedelivery Delayまたは期限切れになっていないTimetoDeliverタイマーが設定されている場合は、それ以降のメッセージが遅延します。

- 順序単位メッセージは、一度に1つずつ処理されます。1つのメッセージの処理が完了したら、順序単位内の次のメッセージが配信されます。

- 分散キューに送信された順序単位メッセージは、分散キューの1つの物理メンバー上にのみ存在します。詳細については、「分散宛先で順序単位を使用する」を参照してください。

- 同じ順序単位からの未コミットまたは未応答のメッセージはすべて、同じトランザクション(トランザクション非対応の場合は同じJMSSession)に存在しなければなりません。順序単位内の1つのメッセージが未コミットまたは未応答である場合、他のメッセージは同じトランザクションまたはJMSSessionにのみ配信されます。これにより、同じ順序単位からのすべての未応答メッセージが1つの回復可能な処理内に保持され、ロールバックや回復に関係なく順序を維持できます。

- キューに同じ順序単位からの複数のメッセージがある場合、それらがすべて処理されるまでは、そのキューに次のメッセージを配信したり、キュー・コンシューマにそれらのメッセージを配信したりすることはできません。
たとえば、メッセージがM_1からMnまであるとします。

- トランザクションの一部として、トランザクションはロールバックされます(処理は完了)。メッセージM_1からMnは、任意の利用可能なコンシューマに配信されます。

- トランザクション外では、メッセージは回復されます(処理は完了)。メッセージM_1からMnは、任意の利用可能なコンシューマに配信されます。

- トランザクション外では、メッセージは認識されます(処理は完了)。未配信のメッセージMn+1は、任意の利用可能なコンシューマに配信されます。

メッセージ順序単位のケース・スタディ

この節では、オンライン書店への本の注文に基づいて、メッセージ順序単位の単純なケース・スタディを行います。

- Joeによる本の注文

- Joeの注文の処理

- メッセージ順序単位による問題解決

Joeによる本の注文

XYZオンライン書店は、JMSを使用して顧客の注文を処理する単純な処理設計を実装しています。JMS処理システムは、以下から構成されます。

- キュー(Queue1)に送信するメッセージ・プロデューサ

- Queue1からのメッセージを処理する複数のメッセージドリブンBean (MdbX、MdbYなど)

- 注文および注文のステータス情報を格納するデータベース(myDB)

Joeは、XYZオンライン書店の自分のアカウントにログインして欲しい本を検索します。本を選び、会計に進んで、販売トランザクションを完了します。ここでJoeは、以前に同じ本を買っていたことに気付き、注文を取り消します。ところが1週間後、その本がJoeのもとに届いてしまいます。

Joeの注文の処理

Joeの注文シナリオでは、注文の取消しメッセージが、注文メッセージよりも前に処理されました。その結果、買いたくなかった本が届けられてしまいました。ここでは、Joeの注文が処理された手順について説明します。

次の図とそれに対応する各アクションは、Joeの注文がどのように処理されたかを示します。

図10-1 Joeの注文のワークフロー

「図10-1 Joeの注文のワークフロー」の説明

1. Joeが、ショッピング・カートから注文ボタンをクリックします。

2. 注文メッセージ(メッセージA)がQueue1に配置されます。

3. Joeが注文を取り消します。

4. 注文取消しメッセージ(メッセージB)がQueue1に配置されます。

5. MdbXがQueue1からメッセージAを取得します。

6. MdbYがQueue1からメッセージBを取得します。

7. MdbYが取消しメッセージをデータベースに書き込みます。対応する注文メッセージがないため、どの注文メッセージもデータベースから削除されません。

8. MdbXが注文メッセージをデータベースに書き込みます。

9. 本の発送を処理するアプリケーションがデータベースを読み取り、注文メッセージを見てJoeの家への発送を開始します。

Java Message Service仕様(http://www.oracle.com/technetwork/java/jms/index.html)にはメッセージ配信の順序付けが規定されていますが、プロデューサの単一のインスタンスとコンシューマの単一のインスタンスの間でのメッセージ配信の順序付けしか規定されていません。Joeのケースでは、Queue1のメッセージを複数のメッセージドリブンBean (MDB)が消費できるため、メッセージの処理順序はまったく保証されなくなっていました。

メッセージ順序単位による問題解決

Joeの注文に関わるすべてのメッセージが常に正しく処理されるようにするには、XYZ書店のシステム管理者がユーザー・セッションに基づいてメッセージ順序単位を構成して、ユーザー・セッションからのすべてのメッセージに順序単位名属性を持たせ、値としてセッションIDを設定します。「順序単位の作成方法」を参照してください。WebLogic Serverでは順序単位内のメッセージが並行処理されることはないため、Joeのユーザー・セッションの間に作成されたすべてのメッセージは作成された順番どおりに処理されます。

次の図とそれに対応する各アクションは、メッセージ順序単位を使用した場合にJoeの注文がどのように処理されるかを示します。

図10-2 順序単位を使用した場合のJoeの注文のワークフロー

「図10-2 順序単位を使用した場合のJoeの注文のワークフロー」の説明

1. Joeが、ショッピング・カートから注文ボタンをクリックします。

2. 注文メッセージ(メッセージA)がQueue1に配置されます。

3. Joeが注文を取り消します。

4. 注文取消しメッセージ(メッセージB)がQueue1に配置されます。

5. MdbXがQueue1からメッセージAを取得します。

6. MdbYがQueue1からメッセージBを取得します。

7. MdbYのメッセージBは、MdbXが注文メッセージを応答確認するまではブロックされます。「処理中にメッセージが遅延した場合の処理」を参照してください。

8. メッセージAがコミットされ、データベースに書き込まれます。

9. メッセージBがコミットされ、データベースに書き込まれます。
対応する注文メッセージが存在するため、Joeの注文はデータベースから削除され、本が届けられることはありません。

順序単位の作成方法

以下の節では、メッセージ順序単位を作成する方法について説明します。「順序単位によるメッセージ配信」および「メッセージ順序単位の高度なトピック」も参照してください。

- 順序単位をプログラム的に作成する

- 順序単位を管理者が作成する

- 順序単位のネーミング・ルール

順序単位をプログラム的に作成する

WLMessageProducerインタフェースのsetUnitOfOrder()メソッドを使用して、プロデューサを順序単位名に関連付けます。

次の例では、順序単位名属性の値がmyUOOnameに設定されます。

getProducer().setUnitOfOrder("myUOOname");

プロデューサを順序単位名に関連付けると、プロデューサをクローズするか、プロデューサと順序単位の関連付けが解消されるまで、このプロデューサが送信するすべてのメッセージは順序単位として処理されます。

次のコードでは、プロデューサと順序単位の関連付けの例を示します。

例10-1 WLMessageProducerインタフェースを使用した順序単位の作成

.
.
.
queue = (Queue)(ctx.lookup(destName));
qsender = (WLMessageProducer) qs.createProducer(queue);
qsender.setUnitOfOrder();
uooname = qsender.getUnitOfOrder();
System.out.println("Using UnitOfOrder :" + uooname);
.
.
.

順序単位を管理者が作成する

ここでは、JMS接続ファクトリやJMS宛先を構成して、メッセージ順序単位を有効にする方法について説明します。

接続ファクトリと宛先の順序単位を構成する

以下のいずれかの方法で、JMS接続ファクトリと宛先を構成してメッセージ順序単位を有効にします。

- 接続ファクトリを構成して、常にユーザー生成の順序単位名を使用するようにします。この場合、その接続ファクトリから作成されたすべてのプロデューサで順序単位が有効化されます。Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの順序単位パラメータの構成に関する項を参照してください。

- 接続ファクトリを構成して、セッションごとに常にシステム生成の順序単位名を使用するようにします。Oracle WebLogic Server管理コンソール・オンライン・ヘルプの接続ファクトリの順序単位パラメータの構成に関する項を参照してください。

- クライアントからWLProducer.setUnitOfOrder(name)を呼び出して、プロデューサの接続ファクトリの初期設定を変更します。

- スタンドアロンの宛先または分散宛先を構成して、常にシステム生成の順序単位名を使用するようにします。管理コンソール・オンライン・ヘルプの以下のトピックを参照してください。

- 「トピックに関する詳細なパラメータの構成」

- 「キューに関する詳細なパラメータの構成」

- 「共通分散トピック - 詳細パラメータの構成」

- 「共通分散キュー - 詳細パラメータの構成」

- 「JMSテンプレートに関する詳細なパラメータの構成」

従来のJMSアプリケーションと相互運用する場合には、接続ファクトリまたは宛先に管理的に順序単位を構成する必要があります。この方法は、コードを変更することなく、メッセージが作成順に処理されるようにするための単純なメカニズムを提供します。

順序単位のネーミング・ルール

順序単位は、名前属性によって特定されます。宛先内では、順序単位名属性に同じ値が設定されているメッセージが、同じ順序単位に属します。名前は、システムからでもアプリケーションからでも指定できます。同じ順序単位内のすべてのメッセージは、同じ名前を共有します。「順序単位の作成方法」を参照してください。

順序単位の名前属性は、以下の規約に準拠させる必要があります。

- 順序単位名属性の有効な値は、nullでも空でもない文字列でなければなりません。

- システム生成の順序単位名は、タイムスタンプ・ベースで統計的に一意になります。

- アプリケーションからは、独自の順序単位名を指定できます。たとえば、WebLogic Integrationアプリケーションではワークフロー名を使用したり、Webサービス・アプリケーションでは会話名を使用したりできます。

- メッセージ順序単位には、独自のネームスペースがあります。順序単位は、他の名前付きオブジェクトに対して一意にする必要はありません。たとえば、Fooというキューが存在する場合でも、Fooという順序単位名は有効です。

- メッセージ順序単位のスコープは、単一の宛先に限定されます。2つの宛先のそれぞれの順序単位を同じ名前にしても構いません。

- 1つまたは複数のプロデューサが、同じ文字列を使用して順序単位を作成することで、同じ順序単位名のメッセージを送信できます。
したがって、システム生成の順序単位名は、複数のプロデューサで使用できます。このパラダイムは、アプリケーションによって割り当てられた順序単位名にもそのまま適用できます。情報が一元的にシリアライズされているのが最も効率的です。したがって、順序単位名としては会話IDのようなプロパティのみを格納するようにしてください。このパラダイムは、メッセージが順序単位非対応のJMSプロバイダ(WebLogic 9.0より前のリリースやWebLogic以外のJMSプロバイダ)で送信された場合には適用されません。

現在の順序の取得

順序単位名は、配信されたメッセージから抽出されます。次に例を示します。

msg.getStringProperty("JMS_BEA_UnitOfOrder");

メッセージ順序単位の高度なトピック

以下の節では、より高度で複雑な状況での順序単位によるメッセージ処理方法について説明します。

- 処理中にメッセージが遅延した場合の処理

- フィルタのせいでメッセージを配信できない場合の処理

- 宛先ソート・キーを使用している場合の処理

- 分散宛先で順序単位を使用する

- トピックで順序単位を使用する

- JMSメッセージ管理で順序単位を使用する

- WebLogicストア・アンド・フォワードで順序単位を使用する

- WebLogicメッセージング・ブリッジで順序単位を使用する

処理中にメッセージが遅延した場合の処理

メッセージ処理の間には、通常であればメッセージの処理順序が変更されるような状況が数多く発生します。以下に、メッセージの配信準備を整えることができない典型的なメッセージ処理状態を示します。

- メッセージが、コミットされていないトランザクション内にあります。

- メッセージのTimeToDeliver値により、TimeToDeliver間隔が経過するまでメッセージを配信できません。

- コンシューマが回復またはロールバックを呼び出したため、RedeliveryDelay間隔が経過するまではメッセージを再配信できません。

たとえば、メッセージAとメッセージBが同じ順序単位に届き、上に挙げたような状況でメッセージAを配信できないとします。この場合、メッセージBの配信を遅延させる要因がなくても、順序単位内のメッセージAが配信されるまではメッセージBを配信することはできません。

フィルタのせいでメッセージを配信できない場合の処理

フィルタと順序単位を使用すると、予期しない動作が発生することがあります。たとえば、メッセージAからZが、同じキューの同じ順序単位にあるとします。Consumer1にはフィルタが設定されており、メッセージA、B、およびCがそのフィルタ条件を満たすため、これらのメッセージがConsumer1に配信されます。

1. メッセージDからZは、メッセージA、B、およびCが確認応答されるまでは配信できません。

2. メッセージA、B、およびCが確認応答または回復されます。

3. メッセージDがメッセージ配信システムから利用可能な状態になります。

4. メッセージDはフィルタ条件を満たさないため、Consumer1に配信されることはありません。

5. メッセージEからZは、メッセージDが処理されるまでは配信できません。

- メッセージDを含むトランザクションは、ロールバックされる必要があります。

- メッセージDが処理されると、メッセージEからZを配信できます。

詳細については、「メッセージのフィルタ処理」を参照してください。

宛先ソート・キーを使用している場合の処理

宛先ソート・キーは、メッセージが順序単位の一部でない場合や、同じ順序単位の一部でない場合に、コンシューマにメッセージを配信する順序を制御します。

たとえば、届いたメッセージAおよびBがキュー上の同じ順序単位に含まれており、優先度の降順でソートされていて優先度はメッセージAよりメッセージBのほうが高いとします。

メッセージBのほうがメッセージAよりも優先度が高くても、これらのメッセージは同じ順序単位に含まれているため、メッセージAが処理されるまではメッセージBを配信できません。次に届いたメッセージCは、順序単位が設定されていないか、メッセージAと同じ順序単位には含まれていないとします。この場合、メッセージCの優先度設定とメッセージAの優先度設定によって配信順序が決まります。『Oracle WebLogic Server JMSの構成と管理』の「基本JMSシステム・リソースの構成」を参照してください。

分散宛先で順序単位を使用する

すでに「JMS仕様に準拠したメッセージ処理」で説明したように、Java Message Service仕様(http://www.oracle.com/technetwork/java/jms/index.html)では、アプリケーションで分散キューを使用している場合、メッセージ配信の順序付けは保証されません。WebLogic JMSでは、分散宛先がターゲット指定されている複数のメッセージに同じ順序単位が設定されている場合は、それらのメッセージを同じ分散宛先メンバーに転送します。メンバーは、宛先の順序単位構成に基づいて選択されます。

- パス・サービスを使用する

- ハッシュ・ベースのルーティングを使用する

パス・サービスを使用する

WebLogicパス・サービスを構成すると、順序単位に含まれるメッセージをその宛先リソース(共通分散宛先のメンバー)にルーティングするために必要な情報を格納する永続マップを提供できます。共通分散宛先のWebLogicパス・サービスが構成されていない場合、メンバー宛先へのルーティング・パスは、分散キューの実行時のロード・バランシング・ヒューリスティックに基づいて決定されます。

ハッシュ・ベースのルーティングを使用する

WebLogicパス・サービスが構成されていない場合、メンバー・キューへのデフォルトのルーティング・パスは、メッセージ順序単位名と共通分散キュー・メンバーのハッシュ・コードに基づいて選択されます。このルーティング・メカニズムの利点は、分散キュー・メンバーへのルートがすばやく計算され、クラスタ内の永続ストレージを必要としない点です。

メッセージ順序単位とハッシュ・ベースのルーティングを実装する際には、以下のことに留意してください。

- 順序単位が関連付けられている分散キュー・メンバーが分散キューから削除されると、新しいメッセージは別の分散キュー・メンバーに送信され、古いメッセージとそのメッセージとの継続性は失われます。

- 順序単位が関連付けられている分散キュー・メンバーにアクセスできない場合は、メッセージを送信しているプロデューサがJMSOrderExceptionをスローし、メッセージは別の分散キュー・メンバーにはルーティングされません。この例外がスローされるのは、JMSメッセージ・システムが必要なサービス品質を満たすことができないからです。特定の順序単位に対しては、1つの分散宛先メンバーだけがメッセージを消費できます。

共通分散宛先でのルーティングを構成する

メッセージ順序単位を使用して、共通分散宛先でのパス・サービスまたはハッシュ・ベースのルーティング・メカニズムを構成する場合は、以下のトピックのいずれかを参照してください。

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプの共通分散トピック - 詳細パラメータの構成に関する項

- Oracle WebLogic Server管理コンソール・オンライン・ヘルプの共通分散キュー - 詳細パラメータの構成に関する項

トピックで順序単位を使用する

順序単位を割り当てても、同じトピック上の2つのサブスクライバによるメッセージの並行処理は可能です。トピックの個々のサブスクライバには独自の宛先とメッセージ・リストがあるため、コンシューマが1つのキューと同様に、メッセージは生成時に割り当てられた順序単位に従ってすべてのサブスクライバによって処理されます。

順序単位と分散トピック

アプリケーションが分散トピックのメンバーに直接送信を行う場合、物理的トピック間のメッセージのルーティングが、順序単位に影響を与える可能性があります。処理の順序が正しくなるようにするには、メッセージが論理分散トピックを介して送信される(つまり、宛先が分散トピックのJNDI名を使用して取得される)ことをアプリケーションで保証する必要があります。その結果、WebLogic Serverでは、同じ順序単位を持つメッセージであれば、その分散トピック・メンバーへのパスが同じであることが保証されます。

順序単位、トピック、およびメッセージドリブンBean

WebLogic ServerメッセージドリブンBeanの実装は、単一のトピック・サブスクリプションおよびJMSセッションの着信メッセージ・ストリームの並行処理を可能にするため、EJBおよびJMS仕様の要件に準拠していません。この並行処理では、順序単位は考慮されないため、処理が正しく順序付けられていることを保証する必要があります。正しく順序付けするには、2つの方法があります。1つは各メッセージをそれ専用のJTAトランザクション内で処理する方法で、もう1つはプール・サイズを1に設定して並行処理を無効にする方法です。

トピックおよびメッセージドリブンBeanで順序単位を使用する場合は、以下のいずれかを行う必要があります。

- JTAトランザクションを使用する
または

- プール・サイズを1に設定する

まず、JTAトランザクションを使用するようMDBを構成します。万一トランザクションのオーバーヘッドが許容できない場合は、プール・サイズを1に設定します。

JTAトランザクションを使用する

最も簡単な方法は、JTAトランザクションを使用することです。この方法は、処理オーバーヘッドが生じますが、WebLogic Serverには高度に最適化されたトランザクション・エンジンが存在するため通常は低く抑えられ、アプリケーションは順序単位が異なるメッセージを並行処理することでメリットを得ることができます。アプリケーションの使用例によっては、JTAトランザクションが有効な場合があります。たとえば、JMSメッセージの送信やデータベースの更新など、他の操作との原子性を維持した相互作用を保証することが必要な場合です。

プール・サイズを1に設定する

プール・サイズを1に設定すると、より効率的な非トランザクション・メッセージングを使用できますが、並行処理では非常に大きな効果をもたらします。

JMSメッセージ管理で順序単位を使用する

JMSメッセージ管理を使用すると、JMSの管理者は実行中のJMSサーバー内のほとんどのメッセージを移動したり削除したりできます。つまり、管理者は「順序単位によるメッセージ配信」に示した配信規則を侵害することができます。

たとえば、順序単位fooに属すメッセージA、B、C、およびDが生成されて宛先D1に送信された場合、以下の点に留意してください。

- メッセージCおよびDを宛先D2に移動すると、両方の宛先からのメッセージが並行して処理される可能性があります。

- メッセージBおよびCを宛先D2に移動すると、メッセージAとメッセージBおよびCが並行して処理される可能性があります。メッセージAが処理された後に、メッセージDが配信可能になります。

メッセージ順序の維持に依存するアプリケーションでは、1つの順序単位内のすべてのメッセージを単一のグループとして移動するのがベスト・プラクティスです。

順序単位の配信規則が維持されるようにするには、次の手順を使用します:

1. ソース宛先とターゲット宛先を休止させます。

2. 移動する順序単位内のすべてのメッセージを選択します。

3. 選択したメッセージをターゲット宛先に移動します。必要に応じて、メッセージを処理したい順序にソートします。

4. ソース宛先とターゲット宛先を再開します。

詳細は、『Oracle WebLogic Server JMSの構成と管理』の「WebLogic JMSのトラブルシューティング」を参照してください。

WebLogicストア・アンド・フォワードで順序単位を使用する

WebLogicストア・アンド・フォワードでは、メッセージ順序単位がサポートされます。たとえば、Fooという順序単位のメッセージを送信するストア・アンド・フォワード・プロデューサがあるとします。このプロデューサは、切断して別の接続で再接続すると、Fooという順序単位を作成してメッセージの送信を継続します。再接続の前と後に送信されたすべてのメッセージは、同じストア・アンド・フォワード・エージェントを介して転送されます。『Oracle WebLogic Serverストア・アンド・フォワードの構成と管理』を参照してください。

WebLogicメッセージング・ブリッジで順序単位を使用する

ソース宛先とターゲット宛先の両方がWebLogic Server 9.0以降のメッセージング・ブリッジ・インスタンスである場合は、メッセージング・ブリッジのPreserveMsgPropertyを有効にすると、順序単位名を維持してプロデューサの順序単位を設定できます。Oracle WebLogic Server WebLogic Tuxedo Connector管理ガイドを参照してください。

メッセージ順序単位の制限事項

この節では、順序単位を使用する際に考慮すべきその他の一般情報を示します。

- ブラウザの列挙値には、現在のキュー・メッセージがブラウザによって受信されるべき順序で格納されます。ここでいう「現在」とは、配信可能になっているメッセージを指します。通常は、順序単位内の最初のメッセージが配信可能になっています。同じ順序単位内の後続のメッセージは配信可能にはなっていません。

- 順序単位機能の組み合わせによっては、競合する順序単位メッセージ・ストリームが不足することがあります。これには、順序単位名が異なる処理中メッセージの数よりコンシューマの数が多くなったために、リソースが十分に利用されなくなった場合も含まれます。システムのパフォーマンスを最適化し、リソースが十分に利用されない状態を防ぐには、最大の負荷でアプリケーションをテストする必要があります。

- このリリースのWebLogic Serverメッセージ順序単位では、順序単位非対応のJMSプロバイダ(WebLogic 9.0より前のリリースやWebLogic以外のJMSプロバイダ)に接続されているクライアントはサポートされません。

11 作業単位メッセージ・グループの使用

この章では、WebLogic JMSを使用する場合に、作業単位メッセージ・グループを使用してメッセージのグループを指定する方法について説明します。

- 作業単位メッセージ・グループとは

- 作業単位によるメッセージ処理について

- 作業単位メッセージ・グループの作成方法

- メッセージ作業単位の高度なトピック

- UOWメッセージ・グループの制限事項

作業単位メッセージ・グループとは

多くのアプリケーションでは、メッセージ順序単位(UOO)によって提供されるグループよりも限定的なグループの定義が必要になります。作業単位メッセージ・グループでは、アプリケーションがJMSメッセージを送信すると、その一部がグループとして識別され、JMSコンシューマがそれらのメッセージをグループとして処理できるようになります。たとえば、JMSプロデューサでメッセージが1つの単位として処理されるように、1つのクライアントに中断なしで配信する必要のあるメッセージの集合を指定できます。また、すでに完了した単位がある場合に、別の単位の完了を待つためにクライアントがブロックされることはありません。

注意:
同一のJMSメッセージで、メッセージ順序単位と作業単位の両方の機能を使用すると、プログラム・エラーが発生します。

以下の節では、メッセージ作業単位を使用して、WebLogic JMSの使用時にメッセージの厳格なグループ化を提供する方法について説明します。

- 作業単位によるメッセージ処理について

- 作業単位メッセージ・グループの作成方法

- メッセージ作業単位の高度なトピック

- UOWメッセージ・グループの制限事項

作業単位によるメッセージ処理について

ここでは、UOWメッセージ・グループの基本的な概念について説明します。

UOWに関連する基本用語

表11-1に、UOWの定義に使用する用語をまとめます。

表11-1 作業単位に関する用語

用語

定義

作業単位(UOW)

1つの単位として処理する必要のあるJMSメッセージのセット。

UOW構成メッセージ

UOWの一部となるメッセージ。WebLogic JMSでメッセージをUOWの一部として識別するには、そのメッセージに「UOWメッセージ・プロパティを設定するプロデューサの記述方法」で説明するJMSプロパティが設定されている必要があります。

UOWプロデューサ

作業を複数に分割する必要のあるプロデューサ(たとえば、UOWのクリエータ)。「メッセージ作業単位のケース・スタディ」で説明するように、複数のプロデューサを同時に使用して、UOWメッセージの複数の構成メッセージを処理できます。

現実に、あるUOWプロデューサでUOWを途中まで処理し、別のプロデューサでUOWメッセージを完成させることが可能です。その際も、構成メッセージの整合性は同様の厳格さで維持されます(たとえば、重複の検出など)。

中間宛先

構成メッセージを1つの単位としてではなく別々に処理するコンシューマのための宛先。UOWにおいて、中間宛先を特別に構成する必要はありません。

中間宛先に届いた構成メッセージは、他の構成メッセージが届くのを待つことなく処理できます。また、中間宛先が分散宛先である場合でも、特別なルーティングを発生させる必要はありません。「中間宛先のUOWコンシューマおよびプロデューサの記述方法」を参照してください。

最終宛先

UOW全体を処理するコンシューマのための宛先。宛先を最終宛先として指定するには、スタンドアロンの宛先、分散宛先、またはJMSテンプレートで「作業単位(UOW)メッセージ処理ポリシー」パラメータを使用します。最終宛先の構成を参照してください。

使用可能/表示可能なメッセージ

消費の準備が整い、先行するメッセージの受信を保留しているメッセージを指すJMS用語。たとえば、JMSメッセージは生成時間になるまで使用可能になりません。また、トランザクションの一部として送信されたJMSメッセージは、トランザクションがコミットされるまでは表示可能になりません。

UOWメッセージを処理する場合のルール

UOWメッセージには、以下のルールが適用されます。

- ルール1 :すべてのメッセージを処理しなければならない
UOW内のメッセージは、すべてのメッセージが最終宛先で使用できる状態になるまでは使用できません。

- ルール2 :メッセージの並べ替え
メッセージは、最終宛先に届いた順序に関係なく、UOWプロデューサに指定されている順序に並べ替えられます。

- ルール3 :間隔なしで配信される
メッセージのグループは、間隔なしでユーザーに配信されます。つまり、グループ内のすべてのメッセージは、別のグループからのメッセージやグループに属していないメッセージより前にユーザーに配信されます。

- ルール4 :単一のコンシューマで消費する
グループ内のすべてのメッセージは、同じコンシューマに配信されます。

メッセージ作業単位のケース・スタディ

この節では、複数の企業の様々な商品をオンラインで注文する場合を例に、メッセージ作業単位の単純なケース・スタディを行います。

オンライン・ショップで様々な商品を注文する

Megazonオンライン・ショップには、JMSを使用して顧客からの様々な商品の注文を処理するための処理設計が実装されています。一部の商品の注文は、Megazonの提携企業にルーティングする必要があります。たとえば、本の注文はMegazonで直接処理できますが、特定の電化製品や家庭用品の注文の一部は提携企業に再ルーティングしなければなりません。MegazonはUOWを使用するように構成されているため、注文された商品をUOWメッセージとして中間宛先にルーティングして処理してから、注文を構成するすべてのUOWメッセージを最終宛先に集めて最終的な請求処理が行われます。

MegazonのJMS処理システムは、以下から構成されます。

- 1つのUOWプロデューサ。注文を履行するための構成メッセージに必要なUOWプロパティを設定し、適切な中間宛先や最終宛先に送信します。

- 本以外の注文に使用する複数の中間宛先。中間宛先では、UOW最終宛先にルーティングされる前のUOW構成メッセージが、コンシューマ・クライアントやプロデューサ・クライアントによって処理されます。

- 1つのUOW最終宛先。最終宛先では、構成メッセージを集めて最終的な処理を行います。

ここでは、顧客JillがMegazonのアカウントにログインして、休暇に向けた買い物をするとします。彼女は、本、フラッシュ・ドライブ、MP3プレーヤ、ラーヴァ・ランプを注文して精算を済ませます。

メッセージ作業単位による注文処理の仕組み

注文を受け付けたJMSプロデューサ・クライアントは、Jillの注文に関わるメッセージが1単位として処理されるようにするため、注文メッセージにUOWプロパティを設定して、それらがこの注文単位の一部であることを示します。設定されたUOWメッセージ・プロパティは、UOWメッセージが最終宛先にルーティングされる前に、中間宛先(Gadget Planet、Widget World、およびDesperate Housewares)をリスニングするすべてのコンシューマ・クライアントやプロデューサ・クライアントによってコピーされます。また、Megazonのシステム管理者は、最終宛先の「作業単位(UOW)メッセージ処理ポリシー」パラメータを「単一のメッセージ配信」に設定しておく必要があります。「作業単位メッセージ・グループの作成方法」を参照してください。

次の図とそれに対応する各アクションは、メッセージ作業単位を使用した場合にJillの注文がどのように処理されるかを示します。

図11-1 作業単位を使用した場合のJillの注文のワークフロー

「図11-1 作業単位を使用した場合のJillの注文のワークフロー」の説明

1. Jillが、ショッピング・カートから注文ボタンをクリックします。

2. この注文が、同一の一意のUOW名を使用する3つのメッセージに分割されます。

- SEQ#1は、中間キューGadget Planetにルーティングされ、コンシューマによってフラッシュ・ドライブの注文が処理されます。処理されたSEQ#1はプロデューサに渡され、中間キューWidget Worldにルーティングされます。Widget WorldのコンシューマによってMP3プレーヤの注文が処理された後、最終的な請求処理のためMegazon最終キューにルーティングされます。

- SEQ#2は、中間キューDesperate Housewaresにルーティングされ、そこでコンシューマがラーヴァ・ランプの注文を処理してからSEQ#1をプロデューサに渡し、プロデューサがそれを最終的な請求処理のためにMegazon最終処理キューにルーティングします。

- SEQ#3は、Megazon最終キューに直接ルーティングされ、本の注文処理と最終的な請求処理が行われます。

3. Megazon最終キューでは、集められた3つのUOWメッセージからObjectMessageリストが作成されます。このリストは、Megazonの請求コンシューマ・クライアントに配信されます。

4. Jillが、すべての注文が処理されたことを示す請求書を受け取ります。

作業単位メッセージ・グループの作成方法

以下の節では、メッセージ作業単位を作成する方法について説明します。

- UOWメッセージ・プロパティを設定するプロデューサの記述方法

- 中間宛先のUOWコンシューマおよびプロデューサの記述方法

- 最終宛先の構成

- 最終宛先のUOWコンシューマの記述方法

UOWメッセージ・プロパティを設定するプロデューサの記述方法

UOWでは、プロデューサによって複数に分割された作業を別々に処理することができます。これらの複数のメッセージは、最終的には1つにまとめられます。構成メッセージは、1つのメッセージの一部として配信するか複数のメッセージとして配信するかに関係なく、個別のメッセージと同様の仮想的な単一メッセージとして捉えるほうが簡単に理解できます。

WebLogic JMSでメッセージをUOWの一部として識別するには、そのメッセージに表11-1に示すJMSプロパティを設定する必要があります。これらのプロパティは、プロデューサ・クライアントによって設定されます。

表11-2 作業単位プロパティ

タイプ

説明

JMS_BEA_UnitOfWork

JMSの標準のプロパティ設定メカニズムによって設定される文字列プロパティ。例:

message.setStringProperty("JMS_BEA_UnitOfWork", "MyUnitOfWorkName")

名前の競合を防ぐため、UOW IDを再利用しないようにする必要があります。たとえば、メッセージが消失した場合または再転送された場合に、別のUOWの一部として認識される可能性があります。そのため、OracleではJava UUID (Universally Unique Identifier)を使用することを推奨しています。http://download.oracle.com/javase/1.5.0/docs/api/java/util/UUID.htmlを参照してください。

JMS_BEA_UnitOfWorkSequenceNumber

JMSの標準のプロパティ設定メカニズムによって設定される整数プロパティ。例:

message.setIntProperty("JMS_BEA_UnitOfWorkSequenceNumber", 5)

有効な値は1以上の整数です

JMS_BEA_IsUnitOfWorkEnd

JMSの標準のプロパティ設定メカニズムによって設定されるブール・プロパティ。例:

message.setBooleanProperty("JMS_BEA_IsUnitOfWorkEnd", true)

このプロパティをtrueに設定すると、このメッセージが作業単位内で最後になります。このプロパティがfalseに設定された場合または存在しない場合、メッセージは作業単位内で最後にはなりません。

UnitOfWorkプロパティを設定しない場合、SequenceNumberおよびEndは無視されます。

UOWプロデューサのサンプル・コード

次に示すクライアントのサンプル・コードでは、表11-1に定義されているUOWプロパティを設定しています。

例11-1 サンプルUOWプロデューサのメッセージ・プロパティ

for (int i=1; i<=100; i++)
{
sendMsg.setStringProperty("JMS_BEA_UnitOfWork","joule");
sendMsg.setIntProperty("JMS_BEA_UnitOfWorkSequenceNumber",i);
if (i == 100)
{
System.out.println("set the end of message flag for message # " + i);
sendMsg.setBooleanProperty("JMS_BEA_IsUnitOfWorkEnd",true);
}
qSender.send(sendMsg, DeliveryMode.PERSISTENT,7,0);
}

UOW例外

JMSメッセージを最終宛先に送信する際に、プロデューサに対して以下の例外がスローされる可能性があります。UOW例外がスローされた場合、そのUOWメッセージは配信されません。

最後のJMS例外を除くすべての例外はJMSExceptionのサブクラスで、weblogic.jms.extensionsパッケージに含まれています。

- BadSequenceNumberException - この例外は、(a)メッセージにUnitOfWorkが設定されているにもかかわらずSequenceNumberが設定されていない場合、または(b) SequenceNumberにゼロ以下の値が設定されている場合にスローされます。

- OutOfSequenceRangeException - この例外は、(a)送信されたメッセージのシーケンス番号が、同じUOW内で最後のメッセージとしてマークされているメッセージのシーケンス番号より大きい場合、または(b)送信されたメッセージのシーケンス番号が、同じUOW内のすでに届いているメッセージのシーケンス番号より小さいにもかかわらず、そのメッセージが最後のメッセージとしてマークされている場合にスローされます。

- DuplicateSequenceNumberException - この例外は、プロデューサが同じUOW内で以前に送信したメッセージと同じシーケンス番号で別のメッセージを送信した場合にスローされます。

- JMSException - メッセージにUnitOfOrderプロパティ・セットとUnitOfWorkプロパティ・セットの両方が設定されている場合には、JMS例外がスローされます。

注意:
ベスト・プラクティスとしては、新しいUOWのすべての構成メッセージが、UOWプロデューサによって単一のトランザクションで送信されるようにプログラミングすることを心がけてください。このようにすると、すべての作業が完了しているか、すべての作業が完了していないか、どちらかの状態にしかなりません。たとえば、UOWプロデューサが例外を受け取ったり、UOWの途中でクラッシュしたりした場合、現在のUOWを取り消したければトランザクション全体をロールバックできます。その結果、障害後に各メッセージをどのように処理するかをアプリケーションで判断する必要がなくなります。

中間宛先のUOWコンシューマおよびプロデューサの記述方法

中間宛先は、コンポーネント・メッセージを1つの単位としてではなく別々に処理するコンシューマのための宛先です。中間宛先のプロデューサやコンシューマの記述には、JMS ForwardHelper例外APIを使用します。これは、着信メッセージから送信メッセージにコピーする必要のあるメッセージ・プロパティの数が多いためです。たとえば、UOWの動作を制御するメッセージ・プロパティなどをコピーする必要があります。

次に示す中間コンシューマのサンプル・コードでは、表11-2に定義されているUOWプロパティをコピーしています。

例11-2 UOW中間宛先のサンプル・クライアント・コード

msg = qReceiver1.receive();
try
{
text = msg.getText();
TextMessage forwardmsg = qsess.createTextMessage();
forwardmsg.setText(text);
forwardmsg.setStringProperty("JMS_BEA_UnitOfWork",
msg.getStringProperty("JMS_BEA_UnitOfWork"));
forwardmsg.setIntProperty("JMS_BEA_UnitOfWorkSequenceNumber",
msg.getIntProperty("JMS_BEA_UnitOfWorkSequenceNumber"));
if (tm.getBooleanProperty("JMS_BEA_IsUnitOfWorkEnd"))
forwardmsg.setBooleanProperty("JMS_BEA_IsUnitOfWorkEnd",
msg.getBooleanProperty("JMS_BEA_IsUnitOfWorkEnd"));
qsend.send(forwardmsg);
}

このサンプルでは、3つのUOWプロパティを着信メッセージから送信メッセージにコピーしています。

最終宛先の構成

宛先を最終宛先として指定するには、スタンドアロンの宛先、分散宛先、またはJMSテンプレートで「作業単位(UOW)メッセージ処理ポリシー」パラメータを使用します。他にも、未完了の作業の最終宛先での有効期限を設定するためのパラメータがあります。

これらの高度なオプションは管理コンソールから設定できます。すべてのタイプの宛先(DestinationBean APIでも可能)、またはJMSテンプレート(TemplateBean APIでも可能)の全般構成のページを使用して設定します。

表11-3 作業単位の構成オプション

フィールド名/MBean名

説明

作業単位(UOW)メッセージ処理ポリシー

UnitOfWorkHandlingPolicy

宛先の作業単位(UOW)機能を有効にするかどうかを指定します。

- パススルー - デフォルトでは、宛先はメッセージをUOWの一部として扱いません。

- 単一のメッセージ配信 - このオプションは、UOWコンシューマがこの最終宛先で構成メッセージを受信する場合にのみ選択します。このオプションを選択すると、UOW構成メッセージはリストとして形成され、java.util.listを含むObjectMessageとして消費されます。

不完全なUOWメッセージの有効期間

IncompleteWorkExpirationTime

未完了のUOW内の配信不能なメッセージが期限切れになるまでの最長時間(ミリ秒)を指定します。このオプションが設定されたメッセージは、配信不能メッセージ用に定義されている有効期限ポリシーに従います。メッセージの有効期限は、最初のUOWメッセージが届いた時点から開始されます。

このフィールドは、作業単位処理ポリシーが「単一のメッセージ配信」に設定されている場合にのみ有効です。値を -1に設定すると、UOWメッセージは期限切れになりません。

注意: 最終宛先での有効期限を構成しないと、いずれかの構成メッセージが(A)送信またはコミットされない場合、(B)期限切れになった場合、または(C)手動で削除された場合に、UOWメッセージが最終宛先で無期限に待機する可能性があります。

管理コンソールで、スタンドアロンの宛先、分散宛先、またはJMSテンプレートに作業単位パラメータを構成する手順については、Oracle WebLogic Server管理コンソール・オンライン・ヘルプにある次の項を参照してください。

- 「トピックに関する詳細なパラメータの構成」

- 「キューに関する詳細なパラメータの構成」

- 「共通分散トピック - 詳細パラメータの構成」

- 「共通分散キュー - 詳細パラメータの構成」

- 「JMSテンプレートに関する詳細なパラメータの構成」

これらのパラメータの詳細は、Oracle WebLogic Server MBeanリファレンスのDestinationBeanとTemplateBeanに関する項を参照してください。

UOWメッセージの最終分散宛先へのルーティング

「順序単位のルーティング」フィールドでは、共通分散宛先のUOWメッセージのルーティングを、パス・サービスで行うかハッシュ・ベースで行うかを指定します。UOOの場合と同様、UOW最終宛先が分散宛先である場合も、UOW内のすべてのメッセージを同じ分散宛先メンバーにルーティングする必要があります。UOOのルーティング・メカニズムの詳細は、「分散宛先で順序単位を使用する」を参照してください。

ただし、基本的なUOOルーティングとUOWルーティングはまったく同じではありません。厳密には、単一のUOO内のすべてのメッセージを同じメンバーにルーティングする必要はなく、そのUOOに未消費のメッセージがない場合は、新しく届いたメッセージをどのメンバーにルーティングしても構いません。一方UOWでは、UOW全体が同じ物理的宛先に届くまでは、消費とは無関係にメッセージのルーティングが保証されている必要があります。

最終宛先のUOWコンシューマの記述方法

次に示すUOWコンシューマのサンプル・コードでは、最終宛先をリスニングするコンシューマによって、送信されたすべての構成メッセージが最終的なUOWメッセージに含まれていることを検証する方法を示します。

例11-3 UOW最終宛先のサンプル・クライアント・コード

{
msg = qReceiver1.receive();
if (msg != null)
{
count++;
System.out.println"Message received: " + msg);
//Check that this one message contains all the messages sent.
ArrayList msgList = (ArrayList)(((ObjectMessage)msg).getObject());
numMsgs = msgList.size();
System.out.println("no. of messages in the msg = " + numMsgs);
}
} while (msg != null);

メッセージ作業単位の高度なトピック

以下の節では、より高度で複雑な状況での作業単位によるメッセージ処理方法について説明します。

メッセージ・プロパティの処理

UOWでは、複数のメッセージが最終的に1つにまとめられます。この点は、メッセージが1つのメッセージとして配信されるかどうかには関係ありません。たとえば、各メッセージにそれぞれ別の有効期限が設定されている場合でも、いずれかのメッセージの期限が切れるとすべてのメッセージが配信されません。したがって、ベスト・プラクティスとしては、UOWを構成するメッセージができる限り均一になるようにメッセージ・プロデューサを構成する必要があります。

構成メッセージは、1つのメッセージの一部として配信するか複数のメッセージとして配信するかに関係なく、個別のメッセージと同様の仮想的な単一メッセージとして捉えるほうが簡単に理解できます。たとえば、メッセージは連続的に認識する必要があるため、UOWによるメッセージの並べ替え機能は、仮想メッセージの正しい配置を決定する機能と考えることができます。メッセージの選択の場合も同じです。コンシューマは、グループ全体を認識するか、まったく認識しないかのどちらかでなければなりません。WebLogic JMSでは、「コンシューマA」にすべてのメッセージを配信することを決定する前に、「コンシューマA」が仮想メッセージを認識していなければなりません。

システム生成のプロパティ

仮想メッセージの一部のフィールドは、構成メッセージとは無関係に設定される必要があります。たとえば、仮想メッセージは、配信回数の値を構成メッセージから取得することはできません。以下に、このようなシステム生成のプロパティ値を示します。

- タイムスタンプ

- 配信回数(再配信)

- 宛先

最後の構成メッセージのプロパティ

上記以外のメッセージ・プロパティは、構成メッセージから派生します。ただし、派生の方法は、それぞれのプロパティの特性に応じて異なります。派生方法の1つは、構成メッセージのプロパティの値を直接取得する方法です(これで、プロパティ値が異なる構成メッセージの処理が簡略化されます)。簡略化のため、UOW内の最後のメッセージを値を派生させるためのメッセージとして使用します。たとえば、仮想メッセージの優先順位は、最後のメッセージとしてマークされている(JMS_BEA_IsUnitOfWorkEndプロパティがtrueに設定されている)メッセージの優先順位と同じになります。

以下に、UOW内の最後のメッセージのプロパティ値から派生する仮想メッセージ・プロパティを示します。

- メッセージID

- 相関ID

- 優先順位

- ユーザー・プロパティ

- ユーザーID

構成メッセージの不均一性

もう1つの派生方法は、構成メッセージの不均一性に対処するため、すべての構成メッセージを同じ値に変換する方法です。たとえば、先に触れたように、有効期限が統一されていないのは合理的ではありません。以下に、この方法で処理されるメッセージ・プロパティ値を示します。

- 配信モード

- 有効期限

ReplyToメッセージ・プロパティ

ReplyToプロパティの値は、仮想メッセージには反映されません。このプロパティは、メッセージの選択や並べ替えには使用されず、アプリケーションでしか使用しないため無視されます。

UOWと共通分散宛先

「UOWメッセージの最終分散宛先へのルーティング」で説明したように、「順序単位のルーティング」フィールドはUOWメッセージのルーティング・メカニズムを指定するために使用します。分散宛先でのUOWにはもう1つ要件があり、すべての宛先メンバーのUOW処理ポリシーに同じ値を設定する必要があります。これ以外の構成は無効です。

ベスト・プラクティスとしては、UOW中間宛先としてトピック(特に分散トピック)を使用しないことです。このような構成では、構成メッセージが重複するおそれがあります。

UOWとストア・アンド・フォワード宛先

WebLogicストア・アンド・フォワード・サービスでもUOWがサポートされています。ただし、ストア・アンド・フォワード(SAF)インポート済み宛先を最終宛先にすることはできません。しかし、SAFは、UOOメッセージの場合と同じようにUOWメッセージのルーティング・ルールに従います。「WebLogicストア・アンド・フォワードで順序単位を使用する」を参照してください。

UOWメッセージ・グループの制限事項

この節では、UOWを使用する際に考慮すべきその他の一般情報を示します。

- WebLogic Server 9.0以前のリリースを使用して作成されたJMSクライアントでは、UOWの一部として処理されるメッセージを作成できません。

- 最終宛先のUOWメッセージはオブジェクト・メッセージであるため、JMS C JNIクライアントでは処理できません。しかし、それをUOWプロデューサとして使用したり、中間宛先で使用したりすることは可能です。

- UOWは、サイズの大きなファイル転送には適していません。お使いのメッセージング環境において、できれば最大メッセージ・サイズが最低値に設定されており、サイズの大きなデータ(大きいファイルなど)は単一のプロデューサから単一つのコンシューマにストリーミング転送されるようになっているのが理想です。UOWでは、個別のメッセージをコンシューマに渡す前にサーバー上で1つの大きなメッセージにまとめるため、このようなストリーミング転送は処理しません。

12 WebLogic JMSによるトランザクションの使い方

この章では、WebLogic JMSによるトランザクションの使い方について説明します。

- トランザクションの概要

- JMSトランザクション・セッションの使い方

- JTAユーザー・トランザクションの使い方

- メッセージドリブンBeanを使用したJTAユーザー・トランザクション

- 例: JTAユーザー・トランザクションにおけるJMSとEJB

- クロス・ドメイン・セキュリティの使用

注意:
この項で説明するJMSクラスの詳細は、Java Webサイト(http://www.oracle.com/technetwork/java/jms/index.html)にある最新のJMS仕様とJavadocを参照してください。

トランザクションの概要

トランザクションを使用すると、アプリケーションでは生成および消費されるメッセージのグループを調整し、送受信する複数のメッセージを基本単位として処理できます。

アプリケーションがトランザクションをコミットすると、トランザクション内で受信した全メッセージはメッセージング・システムから削除され、トランザクション内で送信したメッセージが実際に配信されます。アプリケーションによってトランザクションがロールバックされた場合、トランザクション内で受信したメッセージはメッセージング・システムに戻され、送信したメッセージは破棄されます。

トピック・サブスクライバによってロールバックされた受信メッセージはサブスクライバに再配信されます。キュー・レシーバによってロールバックされた受信メッセージは、コンシューマではなくキューに再配信されます。それによって、キュー内の他のコンシューマがメッセージを受信できるようにします。

たとえばオンライン・ショッピングでは、品物を選択し、それをオンライン・ショッピング・カートに入れます。注文した品物はトランザクションの一部として格納されますが、チェックアウトして注文を確定するまでユーザーの支払い義務は発生しません。ユーザーはいつでも注文を取り消し、カートを空にすることができます。取消によって、現在のトランザクション内で注文がロールバックされます。

JMSでトランザクションを使用する方法には以下の3種類があります。

- トランザクションでJMSのみを使用する場合は、JMSトランザクション・セッションを作成できます。

- EJBなどの他の処理とJMSを混在させる場合は、JMS非トランザクション・セッションでJava Transaction API (JTA)ユーザー・トランザクションを使用します。

- メッセージドリブンBeanを使用します。

以降の節では、JMSトランザクション・セッションとJTAユーザー・トランザクションの使い方について説明します。

注意:
トランザクションを使用する場合、トランザクションがコミットまたはロールバックされる前に発生する問題に対処するために、「セッション例外リスナーの定義」で説明しているようにセッション例外リスナーを定義しておくことをお薦めします。
acknowledge()メソッドは、トランザクション内で呼び出されても無視されます。recover()メソッドがトランザクション内で呼び出されると、JMSExceptionがスローされます。

JMSトランザクション・セッションの使い方

JMSトランザクション・セッションは、セッション内にあるトランザクションをサポートします。JMSトランザクション・セッションのトランザクションはセッション外には影響を及ぼしません。たとえば、セッションをロールバックしても、そのセッションの送受信がロールバックされるだけで、データベース更新はロールバックされません。JTAユーザー・トランザクションはJMSトランザクション・セッションでは無視されます。

JMSトランザクション・セッションのトランザクションは、最初の送受信処理が発生した後で暗黙的に開始され、互いに結び付けられます。トランザクションをコミットまたはロールバックすると、他のトランザクションが自動的に始まります。

システム管理者は、JMSトランザクション・セッションを使用する前に、アプリケーション開発環境の必要性に応じて、接続ファクトリの属性(トランザクション・タイムアウト)とセッション・プールの属性(トランザクション)を調整する必要があります。

JMSトランザクション・セッションの設定および使用に必要な手順を次の図に示します。

図12-1 JMSトランザクション・セッションの設定と使用

「図12-1 JMSトランザクション・セッションの設定と使用」の説明

ステップ1: JMSアプリケーションを設定し、トランザクション・セッションを作成する

「JMSアプリケーションの設定」の説明に従ってJMSアプリケーションを設定しますが、「ステップ3: 接続を使用してセッションを作成する」でセッションを作成する際に、ブール値transactedをtrueに設定してセッションをトランザクション処理されるように指定します。

たとえば、PTPおよびPub/Subメッセージング・モデルのトランザクション・セッションを作成する方法を次の各メソッドで示します。

qsession = qcon.createQueueSession(
true,
Session.AUTO_ACKNOWLEDGE
);

tsession = tcon.createTopicSession(
true,
Session.AUTO_ACKNOWLEDGE
);

定義したら、次のセッション・メソッドでセッションをトランザクション処理するかどうかを決定できます。

public boolean getTransacted(
) throws JMSException

注意:
acknowledge値はトランザクション・セッションでは無視されます。

ステップ2: 必要な処理を実行する

現在のトランザクションで必要な処理を実行します。

ステップ3: JMSトランザクション・セッションをコミットまたはロールバックする

必要な処理を実行したら、以下のメソッドのいずれかを実行してトランザクションをコミットまたはロールバックします。

トランザクションをコミットするには、次のメソッドを実行します。

public void commit(
) throws JMSException

commit()メソッドでは、現在のトランザクションの送受信メッセージがすべてコミットされます。受信メッセージはメッセージング・システムから削除されますが、送信メッセージは表示されるようになります。

トランザクションをロールバックするには、次のメソッドを実行します。

public void rollback(
) throws JMSException

rollback()メソッドでは、現在のトランザクションの送信メッセージが取り消され、受信メッセージがメッセージング・システムに戻されます。

commit()メソッドまたはrollback()メソッドがJMSトランザクション・セッション以外で発行された場合、IllegalStateExceptionがスローされます。

JTAユーザー・トランザクションの使い方

Java Transaction API (JTA)は、複数のデータ・リソースにわたるトランザクションをサポートします。JTAはWebLogic Serverの一部として実装され、トランザクション管理を実装するための標準Javaインタフェースを提供します。

トランザクションを開始、コミット、ロールバックするためのjavax.transaction.UserTransactionオブジェクト(http://www.javasoft.com/products/jta/javadocs-1.0.1/javax/transaction/UserTransaction.html)を使用してJTAユーザー・トランザクション・アプリケーションをプログラミングします。JTAユーザー・トランザクション内にJMSとEJBを混在させる場合、『Oracle WebLogic Server JTAのプログラミング』の「EJBアプリケーションのトランザクション」で説明しているとおりにEJBからトランザクションを開始することもできます。

トランザクション・セッションの開始後にJTAユーザー・トランザクションを開始できます。ただし、JTAユーザー・トランザクションはトランザクション・セッションに無視され、トランザクション・セッションはJTAユーザー・トランザクションに無視されます。

WebLogic Serverは2フェーズ・コミット(2PC)プロトコルをサポートしています。2PCでは、複数のリソース・マネージャ間で1つのJTAトランザクションを効率的に調整できるようになります。これにより、トランザクションによる更新を関連するリソース・マネージャのすべてでコミットするか、またはすべてのリソース・マネージャから完全にロールバックし、トランザクション開始前の状態に戻すことで、データの整合性が保証されます。

システム管理者は、JTAトランザクション・セッションを使用する前に、「XA接続ファクトリを有効化」チェック・ボックスをオンにして、JTAユーザー・トランザクションをサポートするように接続ファクトリを構成する必要があります。

JTAユーザー・トランザクションの設定および使用に必要な手順を次の図に示します。

図12-2 JTAユーザー・トランザクションの設定と使用

「図12-2 JTAユーザー・トランザクションの設定と使用」の説明

ステップ1: JMSアプリケーションを設定し、非トランザクション・セッションを作成する

「JMSアプリケーションの設定」の説明に従ってJMSアプリケーションを設定しますが、「ステップ3: 接続を使用してセッションを作成する」でセッションを作成する際に、ブール値transactedをfalseに設定してセッションをトランザクション処理されないように指定します。

たとえば、PTPおよびPub/Subメッセージング・モデルの非トランザクション・セッションを作成する方法を次の各メソッドで示します。

qsession = qcon.createQueueSession(
false,
Session.AUTO_ACKNOWLEDGE
);

tsession = tcon.createTopicSession(
false,
Session.AUTO_ACKNOWLEDGE
);

注意:
ユーザー・トランザクションがアクティブな場合、確認応答モードは無視されます。

ステップ2: JNDIでユーザー・トランザクションをルックアップする

アプリケーションは、JNDIを使用して、WebLogic ServerドメインのUserTransactionオブジェクトに対するオブジェクト参照を返します。

JNDIコンテキスト(context)を確立して次のようなコードを実行すると、UserTransactionオブジェクトをルックアップできます。

UserTransaction xact = ctx.lookup("javax.transaction.UserTransaction");

ステップ3: JTAユーザー・トランザクションを開始する

UserTransaction.begin()メソッドを使用してJTAユーザー・トランザクションを開始します。例:

xact.begin();

ステップ4: 必要な処理を実行する

現在のトランザクションで必要な処理を実行します。

ステップ5: JTAユーザー・トランザクションをコミットまたはロールバックする

必要な処理を実行したら、以下のcommit()またはrollback()メソッドをUserTransactionオブジェクトで実行してJTAユーザー・トランザクションをコミットまたはロールバックします。

トランザクションをコミットするには、次のcommit()メソッドを実行します。

xact.commit();

commit()メソッドを実行すると、WebLogic Serverはトランザクション・マネージャを呼びだしてトランザクションを完了し、現在のトランザクションで実行されている全処理をコミットします。トランザクション・マネージャの役割は、リソース・マネージャと協力してデータベースを更新することです。

トランザクションをロールバックするには、次のrollback()メソッドを実行します。

xact.rollback();

rollback()メソッドを実行すると、WebLogic Serverはトランザクション・マネージャを呼び出してトランザクションを取り消し、現在のトランザクションで実行されている全処理をロールバックします。

commit()またはrollback()メソッドを呼び出したら、xact.begin()を呼び出して別のトランザクションを開始することもできます。

メッセージドリブンBeanを使用したJTAユーザー・トランザクション

JMSでは非同期的に配信されるメッセージでどのトランザクションを使用するかを決定できないため、JMS非同期メッセージ配信はJTAユーザー・トランザクションではサポートされません。

ただし、メッセージドリブンBeanによるかわりの方法が提供されます。メッセージドリブンBeanでは、メッセージ配信の直前にユーザー・トランザクションを自動的に開始できます。

メッセージドリブンBeanによる非同期メッセージ配信については、『Oracle WebLogic Server Enterprise JavaBeansのプログラミング』の「メッセージドリブンEJBの設計」を参照してください。

例: JTAユーザー・トランザクションにおけるJMSとEJB

以下の例では、JNDIを使用してjavax.transaction.UserTransactionをルックアップすることにより、JTAユーザー・トランザクション内にEJBとJMSの処理が混在するようにアプリケーションを設定し、JTAユーザー・トランザクションを開始してからコミットする手順を示します。この例を実行するには、システム管理者が接続ファクトリを構成するときに、「XA接続ファクトリを有効化」チェック・ボックスをオンにする必要があります。

注意:
この単純なJTAユーザー・トランザクションの例に加えて、WL_HOME\samples\server\examples\src\examples\jta\jmsjdbcディレクトリにあるWebLogic JTA付属の例も参照してください。WL_HOMEは、WebLogic Platformのインストール先の最上位ディレクトリです。

javax.transaction.UserTransactionパッケージ(http://www.javasoft.com/products/jta/javadocs-1.0.1/javax/transaction/UserTransaction.html)を含め、適切なパッケージをインポートします。

import java.io.*;
import java.util.*;
import javax.transaction.UserTransaction;
import javax.naming.*;
import javax.jms.*;

JTAユーザー・トランザクション変数などの必要な変数を定義します。

public final static String JTA_USER_XACT=
"javax.transaction.UserTransaction";
.
.
.

ステップ1

非トランザクション・セッションを作成して、JMSアプリケーションを設定します。JMSアプリケーションの設定については、「JMSアプリケーションの設定」を参照してください。

//JMS application setup steps including, for example:
qsession = qcon.createQueueSession(false,
Session.CLIENT_ACKNOWLEDGE);

ステップ2

JNDIでUserTransactionをルックアップします。

UserTransaction xact = (UserTransaction)
ctx.lookup(JTA_USER_XACT);

ステップ3

JTAユーザー・トランザクションを開始します。

xact.begin();

ステップ4

必要な処理を実行します。

// Perform some JMS and EJB operations here.

ステップ5

JTAユーザー・トランザクションをコミットします。

xact.commit()

クロス・ドメイン・セキュリティの使用

すべての参加ドメインについて、クロス・ドメイン・セキュリティまたはセキュリティの相互運用モードのいずれかを適切に構成する必要があります。

プロセスで使用されるすべてのドメインに関して、クロス・ドメイン・セキュリティおよびセキュリティの相互運用モードの構成を統一します。どちらの設定もドメイン・レベルで設定されるため、ドメインがクロス・ドメイン・セキュリティとセキュリティの相互運用モードの両方が設定された混在モードになる可能性があります。詳細は、『Oracle WebLogic Server JTAのプログラミング』の「ドメイン間トランザクションに対するドメインの構成」を参照してください。

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

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

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

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

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

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

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

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

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

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

- 拡張トピック機能

注意:
すべてのトポロジ変更の可能性を明示的に処理するよりは、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ポリシー

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

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

- JMS宛先の可用性ヘルパーAPIを使用した分散宛先に関する拡張プログラミング

共有サブスクリプションおよびクライアント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ポリシー、およびサブスクリプション名を持つ場合にかぎり、恒久サブスクリプションを共有できます。次を参照してください。

- Oracle WebLogic Server管理コンソール・ヘルプの接続ファクトリ・サブスクリプション共有ポリシーの構成に関する項

- 『Oracle WebLogic Server MBeanリファレンス』のClientIdPolicyに関する項

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

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

サブスクリプション・キーを使用して作成される最初のサブスクライバが、サブスクリプションを作成します。同一のサブスクリプション・キーを使用して連続作成されたすべてのサブスクライバは、すべてのサブスクリプションの詳細(セレクタ、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つのコピー」設計方針

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

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

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

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

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

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

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

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

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

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

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

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

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

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

- MDBを活用してアプリケーションの設計および複雑性を簡略化します。次を参照してください。

- 『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』の分散トピック・デプロイメント・シナリオに関する項

- 『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』の分散トピックを使用したMDBの構成およびデプロイに関する項

- MDBがオプションではない場合、UNRESTRICTEDクライアントIDポリシー、SHARABLEサブスクリプション・ポリシーをパーティション化トピック(PARTITIONED転送ポリシーを持つ分散トピック)と組み合せて使用することを検討します。次を参照してください。

- 『Oracle WebLogic Server JMSの構成と管理』の無制限ClientIDの構成に関する項

- 『Oracle WebLogic Server JMSの構成と管理』の共有サブスクリプションの構成に関する項

- 『Oracle WebLogic Server JMSの構成と管理』のパーティション化された分散トピックの構成に関する項

- JMS宛先の可用性ヘルパーAPIを使用した分散宛先に関する拡張プログラミング

14 サーバー障害からのリカバリ

この章では、サーバーやネットワークの障害発生時にWebLogic JMSクライアント・アプリケーションが再接続または回復する方法、および障害後にJMSデータを移行する方法について説明します。

- JMSクライアントの自動フェイルオーバー

- WebLogic Server 9.0以前のリリースでの障害に関するプログラミングの考慮事項

- 新しいサーバーへのJMSデータの手動移行

JMSクライアントの自動フェイルオーバー

JMSクライアントの自動再接続機能では、サーバーまたはネットワークに障害が発生した場合でも、一部のJMSクライアント・オブジェクトは、使用可能な他のサーバー・インスタンスがある限りそのサーバー・インスタンスに透過的にフェイルオーバーします。たとえば、致命的なサーバー障害が発生した場合、サーバーが使用可能な状態になるとJMSクライアントが自動的に再接続を試みます。

ネットワーク接続の失敗の原因としては、一過性のもの(ネットワーク接続の一時的な中断)と一過性でないもの(サーバーのバウンスまたはネットワーク障害)が考えられます。これらの場合、一部のJMSクライアント・オブジェクトは、クラスタ内の他のサーバー・インスタンス(可能であればホスト・サーバー)での稼動を自動的に試みます。

デフォルトでは、既存のクライアント・コードを手動で構成または変更しなくても、JMSプロデューサ・セッション・オブジェクトが自動的に使用可能なサーバー・インスタンスに再接続しようとします。JMSプロデューサが自動的に再接続しないようにするには、プログラムまたは管理機能を使用して、この機能を明示的に無効にする必要があります。

また、JMSコンシューマ・セッション・オブジェクトが自動的に使用可能なサーバーに再接続するように構成することもできます。ただし、JMSコンシューマ・セッション・オブジェクトは本質的に非同期オブジェクトであるため、管理コンソールまたは公開されているWebLogic JMS APIを使用して、この機能を明示的に有効にする必要があります。

詳細については、以下の節を参照してください。

- 自動再接続の制限事項
JMSプロデューサの自動フェイルオーバー

- JMSコンシューマの自動フェイルオーバーの構成

- JMSクライアントの自動フェイルオーバーを明示的に無効にする

- 自動フェイルオーバーを使用したJMSクライアントのベスト・プラクティス

自動再接続の制限事項

自動再接続ロジックは、多数の障害シナリオでクライアントにシームレスなフェイルオーバーを提供します。ただし、メッセージ処理結果が不明でWebLogic Serverが例外をスローするいくつかの接続障害シナリオがあります。使用するアプリケーションは例外を適切に処理する必要があります。たとえば:

- メッセージの送信処理が冪等の場合、メッセージを再送信します。

- それ以外の場合、使用するアプリケーションは一部のアクションを実行する必要があります。たとえば、重複を避けるために再送信する前にメッセージがキュー上で使用可能かどうかを確認する必要があります。

注意:
宛先または分散宛先メンバーが使用できない場合、当該メンバーが使用可能になるまでメッセージの送信処理が正常に実行されたかどうかを判定できません。

次のJMSオブジェクトの暗黙的なフェイルオーバーは、WebLogic Server 9.2ではサポートされていません。

- キュー・ブラウザ(javax.jms.QueueBrowser)。

- WebLogic JMSシン・クライアント(wljmsclient.jar)は、自動的に再接続しません。

- 再接続ごとにリセットされるクライアントの統計(結果としてクライアントの履歴データは失われます)。

- ある状況下では、自動再接続は可能になりません。可能にならない場合、例外が報告されます。

- 一時的な宛先(javax.jms.TemporaryQueueおよびjavax.jms.TemporaryTopic)。

ヒント:
サーバーやネットワークに障害が発生した後でも、一時的な宛先にアクセスできることがあります。これは、サーバーのロード・バランシングの結果として、一時的な宛先が常にローカル接続ファクトリと同じサーバー・インスタンスにあるとは限らないためです。したがって、サーバーやネットワークに障害が発生した後も一時的な宛先にアクセスでき、プロデューサからのメッセージが引続き送信されている場合、自動的に再接続されたコンシューマが、障害前に接続されていたのと同じ一時宛先からのメッセージを消費できるかどうかは分かりません。

JMSプロデューサの自動フェイルオーバー

ほとんどの場合、JMSプロデューサ・アプリケーションは、使用可能な他のサーバー・インスタンスがあれば透過的にフェイルオーバーします。以下に示すWebLogic JMSプロデューサ指向のオブジェクトは、既存のクライアント・コードを手動で構成または変更しなくても、使用可能なサーバー・インスタンスへの再接続を自動的に試みます。

- 接続

- セッション

- MessageProducer

JMSクライアントが自動的に再接続しないようにするには、プログラムまたは管理機能を使用して、この機能を明示的に無効にする必要があります。詳細については、「JMSクライアントの自動フェイルオーバーを明示的に無効にする」を参照してください。

プロデューサのサンプル・コード

ネットワーク障害が発生すると、メッセージ生成用のWebLogic JMSクライアント・コードによって、使用可能なサーバーへの再接続が試行されます(例14-1のステップ3 - 8を参照)。

例14-1 メッセージ生成用のJMSクライアント・コードのサンプル

//set exception listener
1. public void onException(javax.jms.JMSException jsme) {
connection.setExceptionListener
// handle the exception, which may require checking for duplicates
// or sending the message again
}

2.  Context ctx = create WebLogic JNDI context with credentials etc.
3.   ConnectionFactory cf = ctx.lookup(JNDI name of connection factory)
4.   Destination dest     = ctx.lookup(JNDI name of destination)
// the following operations recover from network failures
5.   Connection  con      = cf.createConnection()
6.   Session     sess     = con.createSession(no transactions, ack mode)
7.   MessageProducer prod = sess.createProducer(dest)

8.   Loop over:
9.      Message msg = sess.createMessage()
// try block to handle destination availablitiy scenarios
10.     try {
prod.send(msg)}
catch (Some Destination Availability Exception e) {
//handle the exception, in most cases, the destination or member
//is not yet available, so the code should try to resend
}
//end loop

// done sending messages
11.   con.close(); ctx.close();

JMSプロデューサは、使用可能な他のサーバー・インスタンスがあれば透過的にフェイルオーバーします。これにより、クライアント・コードは上記のように単純な記述のまま保持され、ネットワーク障害の時点で再試行するクライアント・コードは不要になりました。

WebLogic JMSのデフォルトでは、MessageConsumerは再接続されません。これがプログラム的に再接続されるようにするには、setReconnectPolicyを"all"に設定したWebLogic WLConnection拡張をクライアント・アプリケーション・コードから呼び出す必要があります。詳細については、「JMSコンシューマの自動フェイルオーバーの構成」を参照してください。

再使用可能なConnectionFactoryオブジェクト

JNDIでルックアップされたConnectionFactoryオブジェクト(例14-1および例14-2のステップ1を参照)は、サーバーまたはネットワークの障害後に再度ルックアップすることなく再使用できます。ネットワーク障害には、JMSクライアントJVMと、それがJNDIルックアップの一部として接続されているリモートWebLogic Serverインスタンスとの間の障害の場合、またはJMSクライアントJVMと、JMSクライアントが後で接続する同じクラスタ内の任意のリモートWebLogic Serverインスタンスとの間の障害の場合があります。

再使用可能なDestinationオブジェクト

JNDIでルックアップされたDestinationオブジェクト(キューまたはトピック。例14-1および例14-2のステップ2を参照)は、サーバーまたはネットワークの障害後に再度ルックアップすることなく再使用できます。この点は、分散宛先への送信を行うプロデューサの場合も同様です。クライアントは、JNDIで分散宛先をルック・アップし、使用不能な分散メンバーはルック・アップされないためです。

ネットワーク障害には、クライアントJVMと、それが接続されているWebLogic Serverインスタンスとの間の障害の場合、またはそのWebLogic Serverインスタンスと、実際に宛先をホストしているWebLogic Serverインスタンスとの間の障害の場合があります。Destinationオブジェクトは、その宛先をホストしているWebLogic Serverインスタンスが再起動した後も引続き使用できます。

注意:
JMSクライアントの自動再接続時に分散宛先のコンシューマがどのように動作するかについては、「分散宛先のコンシューマ」を参照してください。

再接続されるConnectionオブジェクト

JMS Connectionオブジェクトは、クライアントJVMとリモートWebLogic Serverインスタンスとの間の物理的なネットワーク接続に1対1でマップするために使用されます。JMSクライアントの再接続機能では、ConnectionFactory.createConnection()メソッドからクライアントが取得するJMS Connectionオブジェクト(例14-1および例14-2のステップ3を参照)は、「一度に1対1」の方式で物理的なネットワーク接続にマップされます。結果として、JMSクライアントは引続き同じConnectionオブジェクトを使用している一方で、暗黙的なフェイルオーバーの後、実際には異なるWebLogic Serverインスタンスと通信している場合があります。

ネットワークが切断された後、接続が暗黙的にリフレッシュされると、その接続から派生するすべてのオブジェクト(javax.jms.Sessionオブジェクト、javax.jms.MessageProducerオブジェクトなど)も暗黙的にリフレッシュされます。リフレッシュ時には、サーバーにアクセスする接続やその派生オブジェクトでのすべての同期処理(producer.send()、connection.createSession()など)を、接続がリフレッシュされていないと判断される前に一定時間ブロックすることができます。この時間は、管理コンソールを使用して構成するか、weblogic.jms.extension.WLConnectionインタフェースのsetReconnectBlockingMillis(long) APIを使用して構成します。

再接続機能では、アプリケーションがconnection.close()を呼び出すまで、WebLogic ServerインスタンスのConnectionFactoryオブジェクトへの再接続がバックグラウンドで試行され続けます。ReconnectBlockingMillisパラメータは、接続がバックグラウンドで再試行されているときに接続を使用しようとしている同期呼出し側のタイムアウトです。

接続がリフレッシュされる前に同期呼出しがタイムアウトすると、暗黙的な再接続が行われない場合とまったく同じように動作します(同じ例外がスローされます)。つまり、同期呼出しは再接続機能のない古くなった接続で呼び出された場合と同じように動作します。

その後、呼出し側は同期呼出しを単純に再試行するか(重複メッセージのようにサービスの質は低くなるおそれがあります)、または接続のバックグラウンドでの再試行を終了するconnection.close()を呼び出すかを決定できます。

再接続されるConnectionの特殊なケース

以下では、プロデューサ接続がリフレッシュされるときに発生する可能性のある特殊なケースについて説明します。

- 恒久サブスクライバのClientIDが指定されているConnection - 「再接続ポリシー」フィールドが「なし」または「プロデューサ」に設定されている場合、ネットワークまたはサーバーの障害が発生したときにJMS ConnectionにClientIDが指定されていると、そのConnectionは自動的にはリフレッシュされません。この制限の理由は下位互換性にあります。障害の後、同じ接続名でJMS Connectionを再作成しようとする既存のJMSアプリケーションが中断されるのを回避するためです。ネットワーク障害に対して暗黙的なフェイルオーバーも実行されると、アプリケーションによる接続の作成は重複したClientIDが原因で失敗します。

注意:
ClientIDが指定されているコンシューマ接続の動作については、「恒久サブスクリプションのClientIDが指定されたコンシューマ接続」を参照してください。

- クローズされたオブジェクトはリフレッシュされない - アプリケーションがjavax.jms.Connection.close()、javax.jms.Session.close()などを呼び出した場合、そのオブジェクトとその派生オブジェクトはリフレッシュされません。同様に、JMSクライアントのConnectionが管理上の理由で破棄された場合も、そのConnectionはリフレッシュされません。

- 例外リスナーが登録されているConnection - JMS ConnectionにアプリケーションのExceptionListenerが登録されている場合、そのExceptionListenerのonException()コールバックは接続が暗黙的にリフレッシュされた場合でも呼び出されます。このコールバックは、アプリケーション・コードにネットワーク切断イベントを通知します。JMSクライアント・アプリケーション・コードは通常、onExceptionでconnection.close()を呼び出しますが、再接続機能を使用する場合はconnection.close()を呼び出さないように選択することもできます。登録済みのExceptionListenerも内部的にリフレッシュされた接続に透過的に移行され、リフレッシュされた接続で例外をリスニングします。

- 複数のConnection - 同じConnectionFactoryオブジェクトから作成された複数のJMS Connectionがある場合、再接続機能の点では、各接続は他の接続とは関係なく動作します。各接続には独自の接続ステータス、接続再試行機能などがあります。

再接続されるSessionオブジェクト

「再接続されるConnectionオブジェクト」で説明したように、JMS Connectionに関連付けられているJMS Sessionオブジェクトはリフレッシュされます(例14-1および例14-2のステップ4を参照)。確認応答モード、トランザクション・モードなどのセッション・ステートは、リフレッシュが発生するたびに保持されます。リフレッシュ後もcreateMessageProducer()などの呼出しに対して同じセッション・オブジェクトを使用できます。

再接続されるSessionの特殊なケース

以下では、Sessionが再接続されるときに発生する可能性のある特殊なケースについて説明します。

- 保留中のコミットまたはロールバックのあるトランザクション・セッション - 非トランザクションJMS Sessionと同様に、JMSトランザクション・セッションも自動的にリフレッシュされます。ただし、ネットワークの切断時にコミットまたはロールバックを保留しているSessionに送信または受信処理があった場合には、Sessionリフレッシュ後の最初のコミット呼出しはjavax.jms.TransactionRolledBackExceptionをスローして失敗します。JMS Sessionのトランザクションがネットワークのリフレッシュにまたがっている場合、そのトランザクションのコミットは(アプリケーション・コードから見て)リフレッシュの前にトランザクションの一部として実行された処理を保証できません。
Sessionリフレッシュ後のsend()やreceive()などの処理では例外はスローされません。例外がスローされるのはリフレッシュ後の最初のコミットだけです。ただし、ネットワークの切断時にJMS Sessionに保留中のトランザクション処理がなかった場合は、Sessionリフレッシュ後の最初のコミットでも例外はスローされません。Session.commit()で例外がスローされると、クライアント・アプリケーション・コードでは再度同じ(暗黙的にリフレッシュされた)JMSオブジェクトを使用するトランザクションですべての処理を単純に再試行できます。リフレッシュ前の古くなった処理は、コミットも複製もされません。

- 保留中の未応答メッセージ - Sessionのリフレッシュ前にセッションに未応答メッセージがあった場合、リフレッシュ後の最初のWLSession.acknowledge()呼出しでweblogic.jms.common.LostServerExceptionがスローされます。これは、acknowledge()呼出しによってメッセージがサーバーからまだ削除されていない可能性があることを示します。その結果、リフレッシュされたSessionが切断前に配信されたメッセージを重複して受信するおそれがあります。

再接続されるMessageProducerオブジェクト

「再接続されるConnectionオブジェクト」で説明したように、JMS Connectionに関連付けられているJMS MessageProducerオブジェクトはリフレッシュされます(例14-1のステップ5を参照)。プロデューサが非匿名である場合、つまり、特定のDestinationオブジェクト(スタンドアロンの宛先または分散宛先)専用である場合は、そのプロデューサの宛先も暗黙的にリフレッシュされます(「再使用可能なDestinationオブジェクト」を参照)。プロデューサが匿名である場合(つまり、特定のDestinationオブジェクト専用でない場合)は、そのプロデューサのsend()処理で指定されている古くなった可能性のあるDestinationオブジェクトが暗黙的にリフレッシュされます。

分散宛先の特殊ケース

分散宛先メンバーが使用不能になるのと同時に、プロデューサがメッセージを送信する可能性もあります。WebLogic JMSでは、分散宛先メンバーが使用不能であることを検知したり、メッセージを送信したときに使用不能だったことが検出されると、システムが別の分散メンバーへのメッセージの送信を再試行します。ただし、分散メンバーが使用不能になる前にメッセージが届いたかどうかを確認できない場合は、メッセージが重複して作成されるおそれがあるため再送は行われません。この場合は例外がスローされます。その例外を捕捉してメッセージを再送するかどうかを決めるのはアプリケーションの役割です。

JMSコンシューマの自動フェイルオーバーの構成

JMS Sessionを通じてJMS Connectionオブジェクトの一部になっているJMS MessageConsumerオブジェクトは、JMS接続のリフレッシュ中にリフレッシュできます(例14-2のステップ5を参照)。ただし、JMSコンシューマはステートフルで本質的に非同期なオブジェクトであるため、weblogic.jms.extension.WLConnection APIまたは管理コンソールを使用してこの機能を明示的に有効にする必要があります。

コンシューマの自動リフレッシュを明示的に有効にすると、恒久サブスクライバのClientIDが構成されている接続もリフレッシュされます(「恒久サブスクリプションのClientIDが指定されたコンシューマ接続」を参照)。ただし、リフレッシュされたコンシューマにはQueueBrowserクライアントは含まれません。「自動再接続の制限事項」で説明するように、QueueBrowserクライアントはリフレッシュされることのないクライアントです。

コンシューマ・クライアントのサンプル・コード

メッセージ・コンシューマのリフレッシュを明示的に有効にした場合、ネットワーク障害が発生すると、メッセージ消費用のWebLogic JMSクライアント・コードによって再接続が試行されます(例14-2のステップ3 - 8を参照)。

例14-2 メッセージ消費用のJMSクライアント・コードのサンプル

0.  Context ctx = create WebLogic JNDI context with credentials etc.
1.  ConnectionFactory cf = ctx.lookup(JNDI name of connection factory)
2.  Destination dest     = ctx.lookup(JNDI name of destination)
// the following operations recover from network failures
3.  Connection  con      = cf.createConnection()
(weblogic.jms.extensions.WLConnection)con).setReconnectPolicy("all")
4.  Session     sess     = con.createSession(no transactions, auto ack)
5.  MessageConsumer cons = sess.createConsumer(dest, message selector)
- also for async consumers : cons.setMessageListener(onMessage impl)
6.  con.start()
7.  Loop over:
for sync consumers: Message msg = consumer.receive()
for async consumers (in different thread): onMessage() invoked
8.  con.close(), ctx.close()

なお、デフォルトでは、接続ファクトリはMessageConsumerオブジェクトをリフレッシュしません。これがプログラム的にリフレッシュされるようにするには、setReconnectPolicyを"all"に設定したWebLogic WLConnection拡張をクライアント・アプリケーション・コードから呼び出す必要があります(例14-2のステップ3を参照)。

クライアントの自動リフレッシュ・オプションの構成

JMSクライアント再接続APIには、以下の構成パラメータが含まれています。これらのパラメータを使用して、コンシューマの再接続機能の動作を制御できます。

表14-1 JMSクライアントの自動再接続オプション

フィールド名/MBean属性

値

説明

再接続ポリシー

ReconnectPolicy

- なし

- プロデューサ(デフォルト)

- すべて

ネットワークの切断時やサーバーの再起動時に、どのJMSクライアント・オブジェクトを暗黙的にリフレッシュするかを指定します。この属性は、この接続ファクトリから派生したConnection、Session、Producer、およびConsumerの暗黙的なリフレッシュにのみ適用されます。この属性はJMSクライアント内のDestinationオブジェクトやConnectionFactoryオブジェクトは、常に暗黙的にリフレッシュされるため適用外です。また、JMSクライアント内のQueueBrowserも、リフレッシュされることのないオブジェクトであるため適用外です。

再接続ブロッキング時間

ReconnectBlockingTimeMillis

6000

任意の同期JMS呼出し(producer.send()、consumer.receive()、session.createBrowser()など)が、呼出しスレッドをブロックし続ける時間(進行中のJMSクライアント再接続をあきらめるまでの時間)を指定します。

TotalReconnectPeriodMillis

-1

ネットワークの最初の中断、または同期JMS呼出しの最後の試行のいずれかが起きた後、JMSクライアントがサーバーへの再接続を再試行し続ける時間(再試行をあきらめるまでの時間)を指定します。

管理コンソールを使用して接続ファクトリのクライアント・パラメータを構成する手順については、Oracle WebLogic Server管理コンソール・ヘルプ』の接続ファクトリのクライアント・パラメータの構成に関する項を参照してください。これらのパラメータの詳細は、『Oracle WebLogic Server MBeanリファレンス』のClientParamsBeanに関する項を参照してください。

再接続されるConsumerの一般的なケース

この節では、同期および非同期コンシューマをリフレッシュする一般的なケースについて説明します。

同期コンシューマ

同期コンシューマは、MessageConsumer.receive()、MessageConsumer.receive(timeout)、およびMessageConsume.receiveNoWait()メソッドを使用してメッセージを消費します。1番目と2番目のメソッドではアプリケーション・コードをブロックする可能性が想定されていますが、3番目のメソッドではアプリケーション・コードのブロックは想定されていません。これらのセマンティクスを維持するため、同期コンシューマ呼出しでの再接続機能の対話には以下のルールが適用されます。

- MessageConsumer.receive()- この呼出しの場合は、呼出しの間に切断されたネットワークがあると、再接続を試行するためにアプリケーション・コードがブロックされます。例外がスローされるまでの時間は、構成セクションにある「再接続ブロッキング時間」プロパティの値が最大値となります。

- MessageConsumer.receive(timeout) - この呼出しの場合は、呼出し側によって指定されたタイムアウトを最大値としてアプリケーション・コードがブロックされます。「再接続ブロッキング時間」プロパティがタイムアウトより短い場合は、再接続ブロッキング時間の設定がブロックの上限となり、「再接続ブロッキング時間」プロパティがタイムアウトより長い場合は、タイムアウトがブロックの上限となります。

- MessageConsumer.receiveNoWait() - この呼出しの場合は、JMS Connectionによる再接続処理中もアプリケーション・コードはブロックされません。「再接続ブロッキング時間」は、この呼出しには適用されません。

これらのメソッドがそれぞれのタイムアウト/待機時間に達すると、再接続されることなく同じ例外がスローされます。これらのメソッドのブロックまたは呼出しの間に再接続に成功した場合は、引続きメソッドからメッセージが返されます。ただし、回復後は、サービス品質が低下したり、似たようなセマンティクスでのメッセージ受信(たとえばメッセージの再配信)が発生したりする可能性があります。このような可能性は、Connection ExceptionListenerコールバックによるLostServerExceptionによってアプリケーションに通知されます。また、確認応答モードがAUTO_ACK以外の場合は、リフレッシュ後の最初の確認応答呼出しによってスローされるLostServerExceptionでアプリケーションに通知されます。

非同期コンシューマ

再接続のコンテキストでは、非同期コンシューマの動作は「再接続の合計期間」プロパティの設定によって制御されます。接続失敗が起こった後「再接続の合計期間」プロパティに設定されている時間内に再接続が成功した場合は、JMS Consumerに登録されているメッセージ・リスナーのonMessage()が引続き呼び出されます。ユーザーがJMS Connection (または、非同期のConsumerに対応するJMS Session)に対して明示的にclose()を呼び出した場合は、そのConsumerに対するonMessagesはそれ以降呼び出されません。Connection ExceptionListenerのonExceptionがLostServerExceptionで呼び出された場合に備え、onMessage()においてリカバリ後の動作(たとえばメッセージの再配信)を想定しておく必要があります。

再接続されるConsumerの特殊なケース

以下の節では、コンシューマがリフレッシュされるときに発生する可能性のある特殊なケースについて説明します。

分散宛先のコンシューマ

WebLogic Server 9.2より前のリリースでは、分散宛先のコンシューマは、その生存時間中は特定の宛先メンバーに固定されていました。これが当てはまるのは、分散キューのキュー・コンシューマと、分散トピックの非恒久サブスクライバです(恒久サブスクライバでは分散トピックはサポートされません)。

MessageConsumerの再接続時には、分散宛先コンシューマもリフレッシュされます。しかし、リフレッシュされたコンシューマが、古くなったコンシューマと同じ宛先を使用することはほとんどありません。つまり、アプリケーションではリフレッシュ前と同じ分散宛先コンシューマを使用していても、そのコンシューマがリフレッシュ前と同じ宛先メンバーに固定されているわけではありません。

メッセージドリブンEJB

メッセージドリブンEJB (MDB)は非同期コンシューマの一種で、独自の動作要件とリフレッシュ・フレームワークを備えています。そのため、MessageConsumerのリフレッシュに参加することは想定されておらず、他のどの方法によってもJMSクライアント再接続フレームワークの影響を受けることはありません。

恒久サブスクリプションのClientIDが指定されたコンシューマ接続

スタンドアロン・トピックの恒久サブスクリプションは、切断後の再接続によってトピックが使用可能になれば、クライアント再接続機能で生じた違いに関係なく機能します。JMSクライアント再接続フレームワークでは、そのトピックの恒久サブスクライバが暗黙的にリフレッシュされ、中断された位置から継続されます。なお、「再接続ポリシー」が「すべて」に設定されている場合は、ClientIDが指定されたJMS Connectionも自動的にリフレッシュされるため、ClientIDによってスコープが指定されている恒久サブスクリプションを自動的にリフレッシュすることは可能です。ClientIDが指定されたConnectionは、それ以外の「再接続ポリシー」設定では再接続されません。

注意:
ネットワークまたはサーバーの障害が発生したときにJMS接続にClientIDが指定されている場合、そのクライアントの再接続にかかる時間は他のクライアントに比べてかなり長くなる場合があります。たとえば、クラスタ内のJMSサーバーは、クラスタの他のメンバーからブロードキャストされるWebLogic Serverの「ハートビート」通知を待機する必要があります。詳細は、『Oracle WebLogic Serverクラスタの使用』の「クラスタのフェイルオーバーとレプリケーション」を参照してください。
WebLogic JMSでは、分散トピックでの恒久サブスクリプションはサポートされていません。したがって、リフレッシュ時の別の分散トピック・メンバーへのフェイルオーバーは問題にはなりません。

非恒久サブスクリプションとメッセージの破棄

コンシューマがトピックの非恒久サブスクライバである場合、アプリケーションからはリフレッシュ後も問題なく消費が行われているように見えても、トピックにパブリッシュされたメッセージが、コンシューマの不足などが原因で再接続中に破棄されている可能性があります。このようなメッセージの破棄は、同期非恒久サブスクライバでも非同期恒久サブスクライバでも発生します。

重複メッセージ

コンシューマのリフレッシュ機能の性質上、クライアント・アプリケーション・コードから明示的にリカバリを呼び出さなくても、メッセージの再配信が発生する可能性があります。これは、コンシューマをリフレッシュすると、暗黙的にリカバリと同等の効果が生じるためです。これが、暗黙的なコンシューマのリフレッシュがデフォルトで有効になっていない主な理由です。なお、この場合でも、問題なく確認応答されたメッセージが再配信されることはありません。

また、これも稀なケースですが、分散トピックの非恒久サブスクライバが、再配信とマークされていない重複メッセージを受信することもあります(たとえば、トピック内でメッセージが破棄されるより前にフェイルオーバーが発生した場合)。これは、リフレッシュの前後で特定のトピック・メンバーに固定されていない分散トピックの非恒久サブスクライバをリフレッシュした結果として発生します。

確認応答モードによる違い

確認応答モードの違いが原因で、コンシューマの再接続動作に差異が生じることはありません。ただし、すでに説明したように、AUTO_ACK以外の確認応答モードでは、サービスの質が低下した可能性があることをアプリケーションに通知するため、リフレッシュ後の最初の確認応答呼出しでLostServerExceptionがスローされます。

クラスタ内の移行したJMS宛先の再接続

JMSサーバーをクラスタ内の別のサーバーに移行した場合、コンシューマが必ず再接続されるとはかぎりません。コンシューマが宛先と一緒に移行されていない場合は、例外がスローされるか、コンシューマが有効でなくなったことをアプリケーションに通知するonExceptionが発生します。回避策としては、アプリケーションで例外ハンドラまたはonExceptionを使用してコンシューマをリフレッシュします。

JMSクライアントの自動フェイルオーバーを明示的に無効にする

JMSクライアントが自動的に再接続しないようにするには、プログラムまたは管理機能を使用して、この機能を明示的に無効にする必要があります。

プログラムを使用する場合

プログラムを使用してJMSクライアントが自動的に再接続しないようにするには、アプリケーションから次のコードが呼び出されるようにします。

ConnectionFactory cf = (javax.jms.ConnectionFactory)ctx.lookup
(JNDI name of connection factory)
javax.jms.Connection con = cf.createConnection();
((weblogic.jms.extensions.WLConnection)con).setReconnectPolicy("none")

詳細については、weblogic.jms.extension.WLConnection APIのsetReconnectPolicyメソッドを参照してください。

管理機能を使用する場合

管理機能を使用してJMSクライアントが自動的に再接続しないようにするには、次の手順に従ってJMS接続ファクトリの「再接続ポリシー」を無効にします。

1. 「JMS接続ファクトリ」→「構成」→「クライアント」ページに移動します。Oracle WebLogic Server管理コンソール・オンライン・ヘルプにある接続ファクトリのクライアント・パラメータの構成に関する項を参照してください。

2. 選択した接続ファクトリでJMSクライアントの再接続機能を無効にするには、「再接続ポリシー」フィールドで「なし」を選択します。
「再接続ポリシー」フィールドの詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJMS接続ファクトリ: 構成: クライアントに関する項を参照してください。

3. 「保存」をクリックします。

その他のJMS接続ファクトリ・クライアント・パラメータの詳細は、Oracle WebLogic Server MBeanリファレンスのClientParamsBeanに関する項を参照してください。

自動フェイルオーバーを使用したJMSクライアントのベスト・プラクティス

Oracleでは、JMSクライアントの自動再接続機能を使用する場合のベスト・プラクティスとして以下を推奨しています。

常に例外をキャッチ

メッセージ処理結果が不明でWebLogic Serverが例外をスローするいくつかの接続障害シナリオがあります。使用するアプリケーションは例外を適切に処理する必要があります。次を参照してください。

- 自動再接続の制限事項

- 再接続されるSessionの特殊なケース

- 分散宛先の特殊ケース

トランザクションを使用してメッセージ作業をグループ化する

関連する作業や依存関係にある作業(メッセージング作業を含む)は、トランザクション・セッション(JMS)またはユーザー・トランザクション(JTA)を使用してグループ化することをお薦めします。このようにすると、すべての作業が完了しているか、すべての作業が完了していないか、どちらかの状態になります。サーバー・インスタンスに障害が発生して転送中のメッセージが消失しても、トランザクション全体をロールバックすれば、障害後に各メッセージをどのように処理するかをアプリケーションで判断する必要はありません。

ヒント:
サーバーの再接続後は、トランザクションのコミットの失敗に注意してください。トランザクション・サブシステムがトランザクションに関係するすべての参加者にアクセスできないと、トランザクションのコミットに失敗することがあります。

JMSクライアントで必ずclose()メソッドを呼び出す

ベスト・プラクティスとして、アプリケーションではJVMガベージ・コレクションを使用してJMS接続をクリーンアップしないことをお薦めします。これは、JMS自動再接続機能ではJMS接続への参照が保持されるためです。したがって、常にconnection.close()を使用して接続をクリーンアップします。また、接続リソースを確実にクリーンアップするため、Finallyブロックを使用することも検討してください。このようにしない場合、接続を使用可能な状態に維持するためにシステム・リソースが割り当てられてしまいます。

JMSクライアント接続を閉じることに関する詳細については、「ベスト・プラクティス:問題が発生したJMS ClientIDは常に閉じる」を参照してください。

WebLogic Server 9.0以前のリリースでの障害に関するプログラミングの考慮事項

WebLogic Server 9.0以前のリリースで実行されるJMSクライアント・アプリケーションでは、サーバー障害の後にjavax.jmsオブジェクトを再確立する必要がありました。9.0以前のリリースのJMSクライアントを実行している場合は、サーバー障害の発生時に正常に終了するよう、JMSクライアントをプログラミングすることもできます。例:

表14-2 サーバー障害に関するプログラミングの考慮事項

WebLogic Serverインスタンスの障害発生時の状態

対応

障害が発生したWebLogic Serverインスタンスに接続しています。

JMSExceptionが接続例外リスナーに配信されます。サーバーを再起動または交換したらすぐに、アプリケーションを再起動する必要があります。

障害が発生したWebLogic ServerインスタンスがJMSサーバーのターゲットになっています。

ConsumerClosedExceptionがセッション例外リスナーに配信されます。失われたすべてのメッセージ・コンシューマを再確立する必要があります。

新しいサーバーへのJMSデータの手動移行

WebLogic JMSでは、移行フレームワークを使用することによって、WebLogic JMSが移行リクエストに正しく応答できるようになり、WebLogic JMSサーバーのオンラインとオフラインの切替えが順序立って行われるようになります。これには、スケジューリングされた移行だけでなく、WebLogic Serverの障害への応答としての移行も含まれます。

いったん適切に構成すると、JMSサーバーとそのすべての宛先をクラスタ内の別のWebLogic Serverへ移行できます。

新しくサーバーを起動し、表14-0のタスクのうち1つ以上を実行することで、障害が発生したWebLogic ServerからJMSデータを手動でリカバリできます。

注意:
クラッシュした、または管理サーバーからアクセスできないサーバー・インスタンスからサービスを移行する場合は、特別な考慮事項があります。移行を実行する時点で、以前アクティブだったサービスのホストに管理サーバーからアクセスできない場合は、『Oracle WebLogic Serverクラスタの使用』の「使用不能サーバーからのサービスの移行」を参照してください。

表14-3 移行タスク・ガイド

JMSアプリケーションが次を使用している場合...

次のタスクを実行します...

永続的なメッセージング - JDBCストア

- 障害が発生したサーバーにJDBCデータベース・ストアが存在している場合は、データベースを新しいサーバーに移行し、JDBC接続プールのURL属性が適切なロケーション参照を反映していることを確認します。

- 障害が発生したサーバーにJDBCデータベース・ストアが存在していない場合は、データベースへのアクセスに影響はないので、変更は不要です。

永続的なメッセージング - ファイル・ストア

ファイルを新しいサーバーに移行し、WebLogic Serverホーム・ディレクトリ内のファイルのパス名が元のサーバーにあったパス名と同じであることを確認します。

トランザクション

クラッシュ後のリカバリを容易にするため、WebLogic Serverではトランザクション・リカバリ・サービスを提供しています。このサービスでは、システムの起動時にトランザクションのリカバリが自動的に行われます。トランザクション・リカバリ・サービスでは、サーバーのトランザクションのログが記録されます。

障害の発生したサーバーからトランザクションを回復する手順の詳細は、『Oracle WebLogic Server JTAのプログラミング』の「サーバーの障害後のトランザクションのリカバリ」を参照してください。

注意:
JMS永続ストアに格納されているメッセージ数が増加するにつれて、WebLogic Serverの初期化に必要なメモリー量も増加します。WebLogic Serverの再起動中にメモリー不足で初期化が失敗した場合は、Java仮想マシン(JVM)のヒープ・サイズを、現在JMS永続ストアに格納されているメッセージ数に比例するよう増加させてから、再起動してください。

新しくWebLogic Serverを起動する方法の詳細は、「サーバーの起動と停止: クイック・リファレンス」を参照してください。障害が発生したサーバーのリカバリについては、『Oracle WebLogic Serverサーバーの起動と停止の管理』の「サーバー障害の回避とリカバリ」を参照してください。

移行可能サービスの定義の詳細は、『Oracle WebLogic Serverクラスタの使用』の「サービスの移行」を参照してください。

15 WebLogic JMS C API

この章では、WebLogic JMS C APIを使用して、JMSアプリケーションとリソースにアクセスできるCクライアントを作成するために必要な要件、設計上の原則、セキュリティの考慮事項および実装のガイドラインについて説明します。

- WebLogic JMS C APIとは

- システム要件

- 設計上の原則

- セキュリティの考慮事項

- 実装のガイドライン

WebLogic JMS C APIとは

WebLogic JMS C APIは、WebLogic JMSアプリケーションおよびリソースにアクセスできるCクライアント・アプリケーションを作成するためのアプリケーション・プログラム・インタフェースです。Cクライアント・アプリケーションでは、Javaネイティブ・インタフェース(JNI) (http://download.oracle.com/javase/1.5.0/docs/guide/jni/index.html)を使用してクライアント側のJava JMSクラスにアクセスします。図15-1を参照してください。

このリリースのWebLogic JMS C APIは、Java JMS 1.1コードの移植を容易にするため、JMSバージョン1.1仕様に準拠しています。詳細は、Oracle WebLogic Server JMS C APIリファレンスを参照してください。

図15-1 WebLogic JMS C APIクライアント・アプリケーション環境

「図15-1 WebLogic JMS C APIクライアント・アプリケーション環境」の説明

システム要件

ここでは、それぞれの環境でWebLogic JMS C APIを使用するためのシステム要件を示します。

- WebLogic JMS C APIに対してサポートされているオペレーティング・システムのリストは、Oracle Fusion Middlewareのサポートされているシステム構成のページを参照してください。『Oracle WebLogic Serverの新機能』のサポートされている構成に関する項を参照してください。

- 使用しているオペレーティング・システムでサポートされるJVM。

- 使用しているオペレーティング・システム用のANSI Cコンパイラ。

- Cクライアント・アプリケーションからJMSアプリケーションへの接続には、以下のWebLogicクライアントのいずれかを使用します。

- WebLogic Thin T3クライアントjar (wlthint3client.jar)。詳細は、『Oracle WebLogic Serverスタンドアロン・クライアントのプログラミング』のWebLogic Thin T3クライアントの開発に関する項を参照してください。

- WebLogicアプリケーション・クライアント(wlfullclient.jarファイル)。『Oracle WebLogic Serverスタンドアロン・クライアントのプログラミング』の「WebLogic JarBuilderツールの使用」を参照してください。

- WebLogic JMSシン・クライアント(wljmsclient.jarファイル)。『Oracle WebLogic Serverスタンドアロン・クライアントのプログラミング』の「WebLogic JMSシン・クライアント」を参照してください。

設計上の原則

以下の節では、WebLogic JMS C APIのアプリケーションを移植または開発する上での原則について説明します。

- ハンドルへのJavaオブジェクトのマッピング

- スレッドの利用

- 例外処理

- 型の変換

- メモリー割当てとガベージ・コレクション

- 接続のクローズ

- ヘルパー関数

ハンドルへのJavaオブジェクトのマッピング

WebLogic JMS C APIは、モジュール形式でコードを実装するハンドル・ベースのAPIです。つまり、アプリケーションではCコードのハンドルとしてJavaオブジェクトを実装します。JMSオブジェクトの実装方法の詳細はハンドル内に隠されます。ただし、Javaとは異なり、ハンドルを使用して実装したら、対応するCloseまたはDestroyメソッドを呼び出してハンドルを明示的に開放する必要があります。「メモリー割当てとガベージ・コレクション」を参照してください。

スレッドの利用

WebLogic JMS C APIから返されるハンドルがスレッド・セーフかどうかは、対応するJava型がスレッド・セーフかどうかによって決まります。例:

- javax.jms.Sessionオブジェクトはスレッド・セーフではありません。これに対応するWebLogic JMS C APIハンドルJmsSessionもスレッド・セーフではありません。

- java.jms.Connectionオブジェクトはスレッド・セーフです。これに対応するWebLogic JMS C APIハンドルJmsConnectionもスレッド・セーフです。

同時実行性制御をCクライアント・アプリケーションで管理しているかぎり、WebLogic JMS C APIが戻すすべてのオブジェクトはどのスレッドでも使用される可能性があります。

例外処理

注意:
WebLogic JMS C APIでは、整数のリターン・コードを使用します。

WebLogic JMS C APIでの例外は、実行スレッドに対してローカルです。WebLogic JMS C APIには、以下の型の例外があります。

- JavaThrowableは、クラスjava.lang.Throwableを表します。

- JavaExceptionは、クラスjava.lang.Exceptionを表します。

- JmsExceptionは、クラスjavax.jms.JMSExceptionを表します。JMSExceptionのすべての標準サブクラスは、例外の型記述子内のビットによって判別されます。型記述子は、JmsGetLastExceptionを呼び出すと返されます。

型の変換

JavaコードとCコードを相互運用する場合、主なタスクの1つになるのがC型からJava型への変換です。たとえば、short型は、JavaでもCでも2バイト・エンティティです。以下の型変換では、特別な処理が必要になります。

Integer (int)

Integer (int)は、JMS32I (4バイト符号付き値)に変換します。

Long (long)

Long (long)は、JMS64I (8バイト符号付き値)に変換します。

Character (char)

Character (char)は、short (2バイトJava文字)に変換します。

String

Stringは、JmsStringに変換します。

Java文字列は、2バイト文字の配列です。Cの文字列は、通常はUTF-8エンコードの1バイト文字の配列です。純粋なASCII文字列はUTF-8仕様にも適合します。UTF-8文字列の詳細は、www.unicode.orgを参照してください。Cプログラマにとって、すべての文字列を2バイトJavaエンコーディングに変換するのは不便です。JmsString構造体を使用すると、アプリケーションの要件に応じ、Cクライアントでネイティブ文字列またはJava文字列を使用できます。

JmsStringでは、以下の2種類の文字列がサポートされます。

- ネイティブC string (CSTRING)

- JavaString (UNISTRING)

uniOrCというUNISTRINGとCSTRINGのユニオンにはstringという文字ポインタがあり、これをNULLで終了するUTF-8エンコードのC文字列に使用できます。uniOrCユニオンは、文字列データと整数長(バイト)のvoidポインタを含むuniStringという構造体を提供します。

JmsStringのstringType要素を入力として使用する場合、文字列入力の型に応じてCSTRINGまたはUNISTRINGを設定する必要があります。対応するデータ・フィールドには、入力として使用する文字列が含まれます。

UNISTRINGエンコーディングでは、すべての2バイトが単一のJava文字としてエンコードされます。2バイト・シーケンスはビッグエンディアンです。Unicodeでは、このエンコーディングをUTF-16BEと呼びます(2バイト・シーケンスがリトルエンディアンの場合はUTF-16LE)。CSTRINGエンコーディングでは、UTF-8でエンコードされた文字列が想定されます。

JmsStringのstringType要素を出力として使用する場合、APIがmallocを使用して出力に十分なスペースを割り当てるようにするか、呼出し側でスペースを割り当てて、返された文字列がそのスペースにコピーされるようにするかを選択できます。ユニオン内の適切なフィールド(stringまたはdata)がNULLである場合は、APIがmallocを使用して出力に十分なスペースを割り当てます。この方法で割り当てたスペースは、メモリーをそれ以上使用しなくなったときに、呼出し側でfreeを使用して開放する必要があります。ユニオン内の適切なフィールド(stringまたはdata)がNULLでない場合は、JmsStringのallocatedSizeフィールドに書込み可能なバイト数が指定されている必要があります。

文字列内に出力全体を格納するための十分なスペースがない場合は、allocatedSizeに必要なスペースの量が設定され、呼び出されたAPIがJMS_NEED_SPACEを返します。JmsStringの適切なフィールド(stringまたはdata)には、allocatedSizeバイトを限度として格納できるだけのデータが格納されます。この場合、返されるC文字列データの最後に、NULL文字が書き込まれる場合と書き込まれない場合があります。次に例を示します。

テキスト・メッセージからの文字列出力に100バイトを割り当てるため、データ・ポインタを設定し、allocatedSizeフィールドを100に設定したとします。JmsMessageGetTextMessage APIは、allocatedSizeが200に設定されたJMS_NEED_SPACEを返します。元の文字列でreallocを呼び出してデータ・ポインタをリセットし、関数をもう一度呼び出します。今回は呼出しが成功し、メッセージ・ハンドルから文字列を抽出できます。かわりに、元のバッファを開放して、正しいサイズの新しいバッファを割り当てることも可能です。

メモリー割当てとガベージ・コレクション

割り当てるすべてのリソースも、適切に破棄する必要があります。Javaでは、参照されなくなったすべてのオブジェクトは、ガベージ・コレクションによってクリーンアップされます。しかし、Cではすべてのオブジェクトを明示的にクリーンアップする必要があります。ユーザーに提供されたすべてのWebLogic JMS C APIハンドルは、明示的に破棄しなければなりません。ハンドルの動詞が、Closeで終わる場合とDestroyで終わる場合があることに注意してください。この規約に基づいて、closeメソッドを含むJavaオブジェクトと含まないJavaオブジェクトを区別できます。次に例を示します。

- javax.jms.Sessionオブジェクトにはcloseメソッドが含まれているので、WebLogic JMS C APIにはJmsSessionClose関数があります。

- javax.jms.ConnectionFactoryオブジェクトにはcloseメソッドが含まれていないので、WebLogic JMS C APIにはJmsConnectionFactoryDestroy関数があります。

注意:
クローズまたは破棄したハンドルは、再び参照しないようにしてください。

接続のクローズ

Java JMSでは、接続を暗黙的にクローズすると、従属するすべてのセッション、プロデューサ、およびコンシューマがクローズされます。WebLogic JMS C APIでは、接続をクローズしても、従属するセッション、プロデューサ、およびコンシューマはクローズされません。接続をクローズしたら、従属するすべてのハンドルは使用できなくなり、明示的にクローズする必要があります。

ヘルパー関数

WebLogic JMS C APIに用意されているヘルパー関数の中には、WebLogic JMSに存在しないものもあります。これらのヘルパーの詳細は、『Oracle WebLogic Server JMS C APIリファレンス』を参照してください。例:

JmsMessageGetSubclassはJmsMessageハンドルで動作し、メッセージのサブクラスに対応する整数を返します。JMSでは、instanceofを使用してこの機能を実現できます。

セキュリティの考慮事項

WebLogic JMS C APIでは、usernameとpasswordに基づくWebLogic互換性レルム・セキュリティ・モードがサポートされています。usernameとpasswordは、InitialContextオブジェクトの作成に使用するハッシュ表のSECURITY_PRINCIPALおよびSECURITY_CREDENTIALSフィールドの初期コンテキストに渡す必要があります。

実装のガイドライン

WebLogic JMS C APIを実装する際は、以下の点に注意してください。

- WebLogic Server JMS拡張(XMLメッセージを含む)はサポートされません。

- JMSオブジェクト・メッセージはサポートされません。

- クライアントでエラーが検知されるとエラー・ログが作成されます。このエラー・ログの名前はULOG.mmddyy (月/日/年)になります。このログ・ファイルは、クライアントのNLSPATH、LOCALE、およびLANG環境変数を使用して完全に国際化されます。

- メッセージ・カタログを翻訳する場合は、Windowsのgencatユーティリティまたはホスト・プラットフォームのgencatユーティリティを使用できます。生成されたカタログ・ファイルがNLSPATH、LOCALE、およびLANG変数に従って配置されていれば、ログ・ファイルにメッセージを書き込む際に翻訳済みのカタログが使用されます。

- クライアント環境では、以下の環境変数を設定できます。

- JMSDEBUG - クライアントからの出力の冗長デバッグを提供します。

- JMSJVMOPTS - クライアントによってロードされたJVMに追加の引数を提供します。

- ULOGPFX - エラー・ログ・ファイルを配置する場所のパス名とファイル接頭辞を構成します。

クライアントのクラッシュにおけるスレッドのデタッチ問題の回避策

JMS Cクライアント・ライブラリを使用するCプログラムは、JVMの障害によりクラッシュする可能性があります。この問題は、特定のJVM製品でのみ起きることが知られている断続的な競合状況に関連している可能性があります。失敗の可能性はJVMのバージョンとパッチ・レベル、オペレーティング・システム、およびハードウェアによって変わります。特に、JMS Cクライアント・ライブラリは暗黙的にCスレッドをJVMにアタッチしますが、実行後にそのスレッドをデタッチすることができません。推奨される回避策は、以下のとおりです。

- 新しいJVMにアップグレードします。Sun JVMのバージョン1.5以降、およびJRockit JVMのR27.6にはこの問題はありませんが、更新されたJVMでもデタッチを呼び出すことをお薦めします。Sun JVMでのこの問題の詳細は、http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6219874を参照してください。

- 以前にJMS C-APIを呼び出した既存のCスレッドからJVMをデタッチするコードをクライアントに追加します。

- 以前にJMS C-APIを呼び出したCスレッドがある場合、プロセス全体が終了する前にそのスレッドを終了しないようにします。

例15-1のJava JNIのサンプル・コードでは、JVMからスレッドをデタッチする方法を示しています。

例15-1 Java JNIのサンプル・コード

#include <jni.h>

...

JavaVM *jvmList[JVM_LIST_SIZE];
jsize retSize = -1;
jint retVal = JNI_GetCreatedJavaVMs(jvmList, JVM_LIST_SIZE, &retSize);
if ((retVal != 0) || (retSize < 1) ) {
printf('ERROR: got %d/%d on JNI_getCreatedJavaVMs\n', retVal, retSize);
return;
}
printf('INFO: got %d/%d on JNI_getCreatedJavaVMs\n', retVal, retSize);
/* The following line assumes that there's exactly one JVM: */
(*(jvmList[0]))->DetachCurrentThread(jvmList[0]);

プログラムが直接JNI呼出しを実行しない場合は、Java JNIライブラリにアクセスするためにコンパイラおよびリンカーのパラメータを追加しなければならない場合があります。たとえば、MicroSoft Visual C++の場合は、次のパラメータを追加します。

- -I$(JAVA_HOME)/includeおよび-I$(JAVA_HOME)/include/win32 (コンパイル)

- $(JAVA_HOME)/lib/jvm.lib (リンク)

A 非推奨となったWebLogic JMS機能

この章では、サーバー・セッションのサーバー管理プールを定義するための非推奨のJMS機能であるサーバー・セッション・プールを構成して使用する方法について説明します。この機能を使用すると、アプリケーションで複数のメッセージを並行して処理できます。WebLogic Serverの非推奨のリリース

- サーバー・セッション・プールの定義

サーバー・セッション・プールの定義

注意:
セッション・プールは現在ほとんど使用されていません。理由は、Java EE仕様の必須の部分ではないこと、JTAユーザー・トランザクションをサポートしていないこと、そして大部分がメッセージドリブンBean (MDB)に取って代わられたことです。MDBの方が簡単で管理しやすく、高機能です。MDBの設計の詳細は、『Oracle WebLogic Server Enterprise JavaBeansのプログラミング』の「メッセージドリブンEJB」を参照してください。

WebLogic JMSには、サーバー・セッションのサーバー管理プールを定義するためのオプションのJMS機能が実装されています。この機能を使用すると、アプリケーションで複数のメッセージを並行して処理できます。

サーバー・セッション・プールの機能は次のとおりです。

- 宛先からメッセージを受信し、そのメッセージを、メッセージ処理用に用意したサーバー側のメッセージ・リスナーに渡します。メッセージ・リスナー・クラスには、メッセージを処理するonMessage()メソッドがあります。

- JMSセッションのプールを管理することで、メッセージを並行して処理します。各セッションでは、シングル・スレッドのonMessage()メソッドが実行されます。

次の図に、サーバー・セッション・プール機能、およびアプリケーションとアプリケーション・サーバーのコンポーネントの関係を示します。

図A-1 サーバー・セッション・プール機能

「図A-1 サーバー・セッション・プール機能」の説明

図に示されているように、アプリケーションにはシングル・スレッドのメッセージ・リスナーが用意されています。JMSによって実装された、アプリケーション・サーバー上の接続コンシューマによって、以下のタスクが実行され、1つまたは複数のメッセージが処理されます。

1. サーバー・セッション・プールからサーバー・セッションを取得します。

2. サーバー・セッションのセッションを取得します。

3. セッションに1つまたは複数のメッセージをロードします。

4. サーバー・セッションを開始して、メッセージを受信します。

5. メッセージの処理が終了したら、サーバー・セッションを解放してプールに戻します。

次の図に、メッセージの並行処理を行うための準備に必要な手順を示します。

図A-2 メッセージの並行処理を行うための準備

「図A-2 メッセージの並行処理を行うための準備」の説明

この手順では、アプリケーションで、他のアプリケーション・サーバー・プロバイダのセッション・プール実装を使用できます。サーバー・セッション・プールはメッセージドリブンBeanを使用して実装することもできます。メッセージドリブンBeanによるサーバー・セッション・プールの実装の詳細は、『Oracle WebLogic Server Enterprise JavaBeansのプログラミング』の「メッセージドリブンEJB」を参照してください。

構成時にセッション・プールと接続コンシューマが定義された場合は、この手順を省略することができます。サーバー・セッション・プールおよび接続コンシューマの構成については、『Oracle WebLogic Server JMSの構成と管理』の「基本JMSシステム・リソースの構成」を参照してください。

WebLogic JMSは現在、オプションのTopicConnection.createDurableConnectionConsumer()処理をサポートしていません。このJMSの高度な処理の詳細については、JMS仕様(http://www.oracle.com/technetwork/java/jms/index.html)を参照してください。

ステップ1: JNDIでサーバー・セッション・プール・ファクトリをルックアップする

サーバー・セッション・プール・ファクトリを使用して、サーバー・セッション・プールを作成します。

WebLogic JMSでは、デフォルトで次のようなServerSessionPoolFactoryオブジェクトが定義されています。weblogic.jms.extensions.ServerSessionPoolFactory:<name>。ここで<name>には、セッション・プールの作成先になるJMSサーバーの名前を指定します。

サーバー・セッション・プール・ファクトリを定義したら、そのファクトリをルックアップするために、まずNamingManager.InitialContext()メソッド(http://download.oracle.com/javase/1.4.2/docs/api/javax/naming/InitialContext.html#InitialContext())を使用してJNDIコンテキスト(context)を確立します。サーブレット・アプリケーション以外のアプリケーションの場合は、初期コンテキストの作成に使用する環境を渡す必要があります。詳細は、NamingManager.InitialContext()のJavadoc (http://download.oracle.com/javase/1.4.2/docs/api/javax/naming/InitialContext.html#InitialContext())を参照してください。

コンテキストが定義されたら、次のコードを使用して、JNDIでサーバー・セッション・プール・ファクトリをルックアップします。

factory = (ServerSessionPoolFactory) context.lookup(<ssp_name>);

<ssp_name>には、サーバー・セッション・プール・ファクトリの修飾名または非修飾名を指定します。

サーバー・セッション・プール・ファクトリの詳細は、「ServerSessionPoolFactory」またはweblogic.jms.extensions.ServerSessionPoolFactoryのJavadocを参照してください。

ステップ2: サーバー・セッション・プール・ファクトリを使用してサーバー・セッション・プールを作成する

以降の節で説明するServerSessionPoolFactoryメソッドを使用して、キュー(PTP)またはトピック(Pub/Sub)の接続コンシューマで使用するサーバー・セッション・プールを作成できます。

サーバー・セッション・プールの詳細は、「ServerSessionPool」またはjavax.jms.ServerSessionPoolのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ServerSessionPool.html)を参照してください。

キュー接続コンシューマで使用するサーバー・セッション・プールを作成する

ServerSessionPoolFactoryには、キュー接続コンシューマ用のサーバー・セッション・プールを作成する、次のメソッドが用意されています。

public ServerSessionPool getServerSessionPool(
QueueConnection connection,
int maxSessions,
boolean transacted,
int ackMode,
String listenerClassName
) throws JMSException

サーバー・セッション・プールに関連付けられるキュー接続、接続コンシューマ(ステップ3で作成予定)で取得できる並行セッションの最大数、セッションをトランザクション処理するかどうか、確認応答モード(トランザクション処理されないセッションの場合にのみ適用可能)、およびインスタンス化されメッセージの受信および並行処理に使用されるメッセージ・リスナー・クラスを指定する必要があります。

ServerSessionPoolFactoryクラスのメソッドの詳細は、weblogic.jms.extensions.ServerSessionPoolFactoryのJavadocを参照してください。ConnectionConsumerクラスの詳細は、javax.jms.ConnectionConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionConsumer.html)を参照してください。

トピック接続コンシューマで使用するサーバー・セッション・プールを作成する

ServerSessionPoolFactoryには、トピック接続コンシューマ用のサーバー・セッション・プールを作成する、次のメソッドが用意されています。

public ServerSessionPool getServerSessionPool(
TopicConnection connection,
int maxSessions,
boolean transacted,
int ackMode,
String listenerClassName
) throws JMSException

サーバー・セッション・プールに関連付けられるトピック接続、接続コンシューマ(ステップ3で作成予定)で取得できる並行セッションの最大数、セッションをトランザクション処理するかどうか、確認応答モード(トランザクション処理されないセッションの場合にのみ適用可能)、およびインスタンス化され、メッセージの受信および並行処理に使用されるメッセージ・リスナー・クラスを指定する必要があります。

ServerSessionPoolFactoryクラスのメソッドの詳細は、weblogic.jms.extensions.ServerSessionPoolFactoryのJavadocを参照してください。ConnectionConsumerクラスの詳細は、javax.jms.ConnectionConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionConsumer.html)を参照してください。

ステップ3: 接続コンシューマを作成する

以下の方法のいずれかを使用して、サーバー・セッションを取得し、メッセージを並行処理するための接続コンシューマを作成できます。

- 『Oracle WebLogic Server JMSの構成と管理』の「基本JMSシステム・リソースの構成」の説明に従って、構成時にサーバー・セッション・プールと接続コンシューマを構成します。

- 以降の節で説明されているConnectionメソッドをアプリケーションに含めます。

ConnectionConsumerクラスの詳細は、「ConnectionConsumer」またはjavax.jms.ConnectionConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionConsumer.html)を参照してください。

キュー用の接続コンシューマを作成する

QueueConnectionには、キュー用の接続コンシューマを作成する、次のメソッドが用意されています。

public ConnectionConsumer createConnectionConsumer(
Queue queue,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException

関連付けられるキューの名前、メッセージをフィルタ処理するためのメッセージ・セレクタ、サーバー・セッションにアクセスするためのサーバー・セッション・プール、およびサーバー・セッションに同時に割り当てることができるメッセージの最大数を指定する必要があります。メッセージ・セレクタの詳細は、「メッセージのフィルタ処理」を参照してください。

QueueConnectionクラスのメソッドの詳細は、javax.jms.QueueConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/QueueConnection.html)を参照してください。ConnectionConsumerクラスの詳細は、javax.jms.ConnectionConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionConsumer.html)を参照してください。

トピック用の接続コンシューマを作成する

TopicConnectionには、トピック用のConnectionConsumersを作成する、以下の2種類のメソッドが用意されています。

public ConnectionConsumer createConnectionConsumer(
Topic topic,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException

public ConnectionConsumer createDurableConnectionConsumer(
Topic topic,
String messageSelector,
ServerSessionPool sessionPool,
int maxMessages
) throws JMSException

各メソッドには、関連付けられるトピックの名前、メッセージをフィルタ処理するためのメッセージ・セレクタ、サーバー・セッションにアクセスするためのサーバー・セッション・プール、およびサーバー・セッションに同時に割り当てることができるメッセージの最大数を指定する必要があります。メッセージ・セレクタの詳細は、「メッセージのフィルタ処理」を参照してください。

いずれのメソッドも接続コンシューマを作成しますが、後者のメソッドは、恒久サブスクライバで使用する恒久接続コンシューマも作成します。恒久サブスクライバの詳細は、「恒久サブスクリプションの設定」を参照してください。

TopicConnectionクラスのメソッドの詳細は、javax.jms.TopicConnectionのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/TopicConnection.html)を参照してください。ConnectionConsumerクラスの詳細は、javax.jms.ConnectionConsumerのJavadoc (http://download.oracle.com/javaee/5/api/javax/jms/ConnectionConsumer.html)を参照してください。

例: PTPクライアントのサーバー・セッション・プールの設定

次の例では、JMSクライアント用のサーバー・セッション・プールを設定する方法を示します。startup()メソッドは、「例: PTPアプリケーションの設定」で説明されているexamples.jms.queue.QueueSendサンプルのinit()メソッドとほぼ同じです。このメソッドでもサーバー・セッション・プールを設定できます。

次の例にstartup()メソッドを示し、あわせて各設定の手順も説明します。

サーバー・セッション・プール・アプリケーションを実装するには、次のパッケージをインポート・リストに追加します。

セッション・プールの作成に必要なセッション・プール・ファクトリの静的変数を定義します。

private final static String SESSION_POOL_FACTORY=
"weblogic.jms.extensions.ServerSessionPoolFactory:examplesJMSServer";

private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private ServerSessionPoolFactory sessionPoolFactory;
private ServerSessionPool sessionPool;
private ConnectionConsumer consumer;

必要なJMSオブジェクトを作成します。

public String startup(
String name,
Hashtable args
) throws Exception

{
String connectionFactory = (String)args.get("connectionFactory");
String queueName = (String)args.get("queue");
if (connectionFactory == null || queueName == null) {
throw new  IllegalArgumentException("connectionFactory="+connectionFactory+
", queueName="+queueName);
}
Context ctx = new InitialContext();
qconFactory = (QueueConnectionFactory)
ctx.lookup(connectionFactory);
qcon =qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qcon.start();

ステップ1

JNDIでサーバー・セッション・プール・ファクトリをルックアップします。

sessionPoolFactory = (ServerSessionPoolFactory)
ctx.lookup(SESSION_POOL_FACTORY);

ステップ2

次のように、サーバー・セッション・プール・ファクトリを使用してサーバー・セッション・プールを作成します。

sessionPool = sessionPoolFactory.getServerSessionPool(qcon, 5,
false, Session.AUTO_ACKNOWLEDGE,
examples.jms.startup.MsgListener);

このコードでは、以下のように定義されています。

- qconは、サーバー・セッション・プールに関連付けられるキュー接続を示します。

- 5は、接続コンシューマ(ステップ3で作成予定)で取得できる並行セッションの最大数を示します。

- falseは、セッションをトランザクション処理しないことを示します。

- AUTO_ACKNOWLEDGEは、確認応答モードを示します。

- examples.jms.startup.MsgListenerは、インスタンス化され、メッセージの受信および並行処理に使用されるメッセージ・リスナーを示します。

ステップ3

接続コンシューマを次のように作成します:

このコードでは、次が定義されています:

consumer = qcon.createConnectionConsumer(queue, "TRUE",
sessionPool, 10);

- queueは、関連付けられるキューを示します。

- TRUEは、メッセージをフィルタ処理するためのメッセージ・セレクタを示します。

- sessionPoolは、サーバー・セッションにアクセスするためのサーバー・セッション・プールを示します。

- 10は、サーバー・セッションに同時に割り当てることができるメッセージの最大数を示します。

この例で使用されているJMSクラスの詳細は、「JMS APIについて」またはjavax.jmsのJavadoc (http://www.oracle.com/technetwork/java/jms/index.html)を参照してください。

例: Pub/Subクライアントのサーバー・セッション・プールの設定

次の例では、JMSクライアント用のサーバー・セッション・プールを設定する方法を示します。startup()メソッドは、「例: Pub/Subアプリケーションの設定」で説明されているexamples.jms.topic.TopicSendサンプルのinit()メソッドとほぼ同じです。このメソッドでもサーバー・セッション・プールを設定できます。

次の例にstartup()メソッドを示し、あわせて各設定手順も述べます。

サーバー・セッション・プール・アプリケーションを実装するには、次のパッケージをインポート・リストに追加します。

import weblogic.jms.extensions.ServerSessionPoolFactory

セッション・プールの作成に必要なセッション・プール・ファクトリの静的変数を定義します。

private final static String SESSION_POOL_FACTORY=
"weblogic.jms.extensions.ServerSessionPoolFactory:examplesJMSServer";

private TopicConnectionFactory tconFactory;
private TopicConnection tcon;
private TopicSession tsession;
private TopicSender tsender;
private Topic topic;
private ServerSessionPoolFactory sessionPoolFactory;
private ServerSessionPool sessionPool;
private ConnectionConsumer consumer;

必要なJMSオブジェクトを作成します。

public String startup(
String name,
Hashtable args
) throws Exception

{
String connectionFactory = (String)args.get("connectionFactory");
String topicName = (String)args.get("topic");
if (connectionFactory == null || topicName == null) {
throw new  IllegalArgumentException("connectionFactory="+connectionFactory+
", topicName="+topicName);
}
Context ctx = new InitialContext();
tconFactory = (TopicConnectionFactory)
ctx.lookup(connectionFactory);
tcon = tconFactory.createTopicConnection();
tsession = tcon.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
topic = (Topic) ctx.lookup(topicName);
tcon.start();

ステップ1

JNDIでサーバー・セッション・プール・ファクトリをルックアップします。

sessionPoolFactory = (ServerSessionPoolFactory)
ctx.lookup(SESSION_POOL_FACTORY);

ステップ2

次のように、サーバー・セッション・プール・ファクトリを使用してサーバー・セッション・プールを作成します。

sessionPool = sessionPoolFactory.getServerSessionPool(tcon, 5,
false, Session.AUTO_ACKNOWLEDGE,
examples.jms.startup.MsgListener);

このコードでは、以下のように定義されています。

- tconは、サーバー・セッション・プールに関連付けられるトピック接続を示します。

- 5は、接続コンシューマ(ステップ3で作成予定)で取得できる並行セッションの最大数を示します。

- falseは、セッションをトランザクション処理しないことを示します。

- AUTO_ACKNOWLEDGEは、確認応答モードを示します。

- examples.jms.startup.MsgListenerは、インスタンス化され、メッセージの受信および並行処理に使用されるメッセージ・リスナーを示します。

ステップ3

次のように、接続コンシューマを作成します。

consumer = tcon.createConnectionConsumer(topic, "TRUE",
sessionPool, 10);

このコードでは、以下のように定義されています。

- topicは、関連付けられるトピックを示します。

- TRUEは、メッセージをフィルタ処理するためのメッセージ・セレクタを示します。

- sessionPoolは、サーバー・セッションにアクセスするためのサーバー・セッション・プールを示します。

- 10は、サーバー・セッションに同時に割り当てることができるメッセージの最大数を示します。

この例で使用されているJMSクラスの詳細は、「JMS APIについて」またはjavax.jmsのJavadoc (http://www.oracle.com/technetwork/java/jms/index.html)を参照してください。

B FAQ :リモートJMSプロバイダの統合

この章では、WebLogic ServerとリモートJMSプロバイダを統合する方法について説明します。JMS(メッセージング)、JTA(トランザクション)、およびJNDI(ネーミング)の各Java EE標準は、相互に連携することで、異なるホスト・マシン間(さらには異なるベンダー間)において信頼性の高いJava対Javaメッセージングを提供します。Oracle WebLogic Serverには、これらのAPIを利用してリモートJMSプロバイダをローカル・アプリケーションに統合するための各種ツールが用意されています。

- JMSおよびJNDIの用語

- トランザクションについて

- リモート・プロバイダと統合する方法

- リモート・プロバイダを統合する場合のベスト・プラクティス

- 外部JMSサーバー定義の使用

- EJB/サーブレットのJMSリソース参照の使用

- WebLogicストア・アンド・フォワードの使用

- WebLogic JMS SAFクライアントの使用

- メッセージング・ブリッジの使用

- メッセージングBeanの使用

- AQ JMSの使用

- JMSの相互運用性に関するドキュメント

JMSおよびJNDIの用語

Q.

A.リモートJMSプロバイダは、ローカルのスタンドアロンWebLogicサーバーの外部、またはWebLogicサーバー・クラスタの外部でホストされるJMSサーバーです。リモートJMSサーバーとしては、WebLogic JMSサーバーだけでなく、非WebLogic (外部) JMSサーバーも使用できます。

Q.JNDIとは何ですか。

A.JNDI (Java Naming and Directory Interface)は、サービスやリソースに名前をマップする、Java EEルックアップ・サービスです。JNDIは、特定の(クラスタリングされていない)スタンドアロンWebLogicサーバー内、またはWebLogicサーバー・クラスタ内に存在する公開リソースのディレクトリを提供します。これらのリソースとしては、JMS接続ファクトリ、JMS宛先、JDBC (データベース)データ・ソース、アプリケーションEJBなどがあります。

WebLogicクラスタ内のいずれかのWebLogicサーバーに接続しているクライアントは、クラスタ内のすべてのWebLogicサーバーでホストされているどのJNDI公開サービスおよびリソースでも透過的に参照できます。クライアントは、クラスタ内の特定のWebLogicサーバーについての明確な情報がなくても、そのサーバーでホストされているリソースにアクセスできます。

Q.JMS接続ファクトリとは何ですか。

A.JMS接続ファクトリは、JNDIに保持されている名前付きエンティティ・リソースです。アプリケーション、メッセージドリブンBean (MDB)、およびメッセージング・ブリッジは、JNDI内のJMS接続ファクトリをルックアップし、これを使用してJMS接続を作成します。最終的には、このJMS接続を使用して、メッセージを送信または受信するためのJMSセッション、プロデューサ、およびコンシューマを作成します。

Q.JMS接続IDとは何ですか。

A.JMS接続IDは、JMSクライアント接続の命名に使用します。恒久サブスクライバでは名前付きの接続が必要になります。それ以外の場面では、接続に名前を付けることはあまりありません。なお、クラスタリングされたサーバー群内(またはスタンドアロンのサーバー内)では、特定の名前付き接続を複数のJMSクライアントから同時に使用することはできません。また、既存の接続と同じ名前の接続を新たに作成しようとしても失敗します。

Q.JMSトピックとJMSキューの違いは何ですか。

A.JMSキューは、1つのコンシューマにメッセージを配信します。一方、JMSトピックは、複数のコンシューマにメッセージのコピーを配信します。

Q.トピック・サブスクリプションとは何ですか。

A.トピック・サブスクリプションは、特定のサブスクライバへの配信を待機しているメッセージの内部キュー、と捉えることができます。サブスクリプションを作成すると、トピックに対してパブリッシュされた各メッセージのコピーがこの内部キューに蓄積されます。ただし、サブスクリプションが作成される前に送信されたメッセージは蓄積されません。サブスクリプションは共有できないため、複数のサブスクライバが特定のサブスクリプションを同時にサブスクライブすることはできません。

Q.非恒久トピック・サブスクライバとは何ですか。

A.非恒久トピック・サブスクライバは、JMSクライアントの存続期間のみ存続する名前なしのサブスクリプションを作成します。非恒久サブスクリプション内のメッセージは永続化されることはありません。これは、メッセージのパブリッシャによって永続的なサービス品質(QOS)が指定されている場合でも同様です。JMSサーバーを停止すると、すべての非恒久サブスクリプションが終了します。

Q.恒久サブスクライバとは何ですか。

A.恒久サブスクライバは、サーバーの再起動後や恒久サブスクライバの終了後も存続する名前付きサブスクリプションを作成します。恒久サブスクライバは、トピック名、接続ID、およびサブスクライバIDを指定してそのサブスクリプションに接続します。クラスタ内にあるサブスクライバのサブスクリプションは、接続IDとサブスクライバIDの組合せによって一意に命名されます。トピックに対してパブリッシュされた各永続メッセージのコピーは、そのトピックの恒久サブスクリプションに永続化されます。サーバーのクラッシュや再起動が発生した場合は、恒久サブスクリプションおよびその未消費の永続メッセージが回復します。

トランザクションについて

Q.トランザクションとは何ですか。

A. トランザクションは、複数のアプリケーション操作をまとめたもので、最小単位として処理する必要のあるものです。一貫性を維持するため、トランザクション内のすべての操作は、すべてが成功するかすべてが失敗するかのどちらかでなければなりません。詳細は、『Oracle WebLogic Server JTAのプログラミング』の「トランザクションの紹介」を参照してください。

Q.統合においてトランザクションが重要なのはなぜですか。

A.アプリケーションの統合においては、トランザクションを使用してデータの一貫性を維持するのが一般的です。たとえば、メッセージが必ず1回のみ転送されるようにする場合には、単一のトランザクションを使用して、2つの操作(ソース宛先からのメッセージの受信、およびターゲット宛先への送信)を1つにまとめることができます。また、トランザクションを使用することで、データベースの更新やメッセージング操作の実行における原子性を維持することもできます。

Q.JTAトランザクション、XAトランザクション、グローバル・トランザクションとは何ですか。

A.Java EEでは、単一のグローバル・トランザクションのことを、明確に区別することなくJTAトランザクション、XAトランザクション、ユーザー・トランザクション、グローバル・トランザクションなどと呼びます。このようなトランザクションには、複数の異なるXA対応リソースに対する操作が含まれている場合や、タイプの異なるリソースに対する操作が含まれている場合さえあります。JTAトランザクションは、常に現在のスレッドに関連付けられており、1つのアプリケーション呼出しとしてサーバー間で受け渡すこともできます。XAトランザクションの典型的な例は、WebLogicのJMS操作およびJDBC (データベース)操作の両方が含まれているトランザクションです。

Q.ローカル・トランザクションとは何ですか。

A.JMSローカル・トランザクションとは、単一のリソースまたはサービスのみが参加するトランザクションです。JMSローカル・トランザクションは、単一のベンダーの宛先が参加する特定のJMSセッションに関連付けられます。XAトランザクションと異なり、データベース操作をJMSローカル・トランザクションに参加させることはできません。

Q.JMSでは、ローカル・トランザクションをどのような方法で提供しているのですか。

A.ローカル・トランザクションは、transacted sessionsと呼ばれるJMS固有のAPIによって提供されます。WebLogic JMS以外のベンダーの場合、トランザクション・セッションのスコープを単一のJMSサーバーに限定しているのが一般的です。WebLogic JMSでは、クラスタ内の複数の宛先での複数のJMS操作を、単一のトランザクション・セッションのトランザクションに参加させることができます。言い換えると、トランザクション・セッションのスコープはWebLogicクラスタであり、そのJMSセッションのクラスタの外部にあるリモートJMSプロバイダをトランザクションに参加させることはできません。

Q.JMSローカル・トランザクションは統合にも利用できますか。

A.ローカル・トランザクションは、スコープが単一のリソース(たとえばメッセージング・サーバーやデータベース・サーバー)に限定されるため、通常は統合には使用しません。

Q.動トランザクション登録とは何ですか。

A.自動トランザクション登録とは、以下に示す条件に基づいて、Java EE JTAトランザクションに参加するデータベース・サーバーやメッセージング・サーバーなどのリソースに対して実行する操作です。

- リソースがXAトランザクション対応です

- リソースが現在のトランザクションに登録されています

- リソースへのアクセスに使用されるクライアント・ライブラリがトランザクション対応(XA対応)です

技術的には、トランザクション内のXA対応リソースに対する操作を自動的に参加させることを自動登録と呼びます。

- XA対応WebLogic APIを使用するWebLogicクライアントには、現在のスレッドのJTAトランザクション内の操作が自動的に登録されます。XA対応のWebLogicクライアントとしては、WebLogic JMS XA対応(またはユーザー・トランザクション対応)接続ファクトリ、グローバル・トランザクション対応のJDBC接続プール・データ・ソースなどがあります。

- 外部(非WebLogic) JMSクライアントには、現在のJTAトランザクションは自動登録されません。このようなクライアントの場合は、現在のトランザクション内で別手順によってプログラム的に登録するか、WebLogicが提供する機能を使用して外部JMSクライアントをラップし、ラッパーAPI経由で外部JMSクライアントにアクセスしたときに自動登録されるようにする必要があります。

外部ベンダーに対して自動登録を提供するためのJMS機能は以下のとおりです。

- メッセージドリブンEJB

- JMS resource-referenceプール

- メッセージング・ブリッジ

WebLogic以外のベンダーのJMS接続ファクトリがXA対応かどうかは、そのベンダーのドキュメントで確認してください。なお、トランザクション・セッション(ローカル・トランザクション)のサポートには、グローバル/XAトランザクションのサポートは含まれていません。

リモート・プロバイダと統合する方法

Q.JMSクライアントは、どのような手順でリモートJMSプロバイダと通信するのですか。

A.JMSクライアントでは、どのJMSプロバイダと通信する場合でも、次の手順を実行する必要があります。

1. JNDIを使用して、JMS接続ファクトリ・オブジェクトとJMS宛先オブジェクトをルックアップする

2. 接続ファクトリ・オブジェクトを使用してJMS接続を作成する

3. JMS接続とJMS宛先オブジェクトを使用して、メッセージ・コンシューマまたはプロデューサを作成する

Q.リモートJMSプロバイダとの通信を設定するためにはどのような情報が必要ですか。

A.リモートJMSプロバイダとの通信を設定するためには、以下の情報を用意する必要があります。

- 宛先タイプ(リモートJMS宛先がキューであるかトピックであるか)。

- リモートJMS宛先のJNDI名。

- 恒久トピック・サブスクライバの場合は、それを一意に特定するための接続ID名とサブスクライバID名。メッセージドリブンEJBは、これらの値のデフォルト値をEJB名に基づいて提供します。

- 非WebLogicリモートJMSプロバイダの場合

- 初期コンテキスト・ファクトリ・クラス名(JMSプロバイダのJNDIルックアップ・サービスのJavaクラス名)

- JMSプロバイダのJMSクライアント・ライブラリおよびJNDIクライアント・ライブラリを保持するJava jarファイルの格納場所。これらのjarファイルが、ローカルJVMのクラスパスに指定されていることを確認してください。

- リモート・プロバイダのJNDIサービスのURL。WebLogicサーバーの場合、このURLは通常t3://hostaddress:portという形式になっています。HTTP上でトンネリングする場合は、URLの先頭をt3ではなくhttpにします。アプリケーションと同じWebLogicサーバー(またはWebLogicクラスタ)上に存在するWebLogic JMSサーバーにアクセスする場合は、サーバー・アプリケーション・コードにURLを記述する必要はありません。

- リモート・プロバイダのJMS接続ファクトリのJNDI名。この接続ファクトリは、ローカル・プロバイダではなくリモート・プロバイダ上に存在している必要があります。
JMSアプリケーションでトランザクションを使用する場合は、接続ファクトリをXA対応にする必要があります。WebLogicドキュメントでは、XA対応ファクトリをユーザー・トランザクション対応と表現しています。

WebLogicサーバーでは、以下に示す構成不可の接続ファクトリ3つがデフォルトで提供されます。

- weblogic.jms.ConnectionFactory (XA対応でないファクトリ)

- weblogic.jms.XAConnectionFactory (XA対応ファクトリ)

- weblogic.jms.MessageDrivenBeanConnectionFactory (メッセージドリブンEJB用のXA対応ファクトリ)

その他のWebLogic JMS接続ファクトリは、明示的に構成する必要があります。

Q.部JMSプロバイダのJNDIサービスの機能性に制限がある場合はどうしたらよいですか。

A.JMSプロバイダの接続ファクトリおよび宛先を特定する方法として好ましいのは、標準のJava EE JNDIルックアップを使用する方法です。しかし、非WebLogic JMSプロバイダのJNDIサービスは、使い勝手が悪い場合や信頼性に欠ける場合があります。この問題を解決するには、WebLogicサーバーで動作する起動クラスまたはload-on-startupサーブレットを作成して、以下の処理を実行します。

- 外部プロバイダ独自の(非JNDI) APIを使用して、接続ファクトリとJMS宛先を特定します

- JMS宛先とJMS接続ファクトリをWebLogic JNDI内に登録します

Q.JMSリソースをプールする方法について教えてください。

A.リモートおよびローカルのJMSリソース(たとえば、クライアント接続およびセッション)は、プールすることでパフォーマンスを向上させることができます。メッセージドリブンEJBでは、その内部JMSコンシューマが自動的にプールされます。また、リソース参照によってアクセスするJMSコンシューマおよびプロデューサも自動的にプールされます。

Q.WebLogicで提供されるバージョン相互運用性について教えてください。

A. 『Oracle WebLogic Serverインフォメーション・ロードマップ』の「WebLogic Serverの互換性」で説明するように、すべてのWebLogic Serverリリースは相互運用します。

Q.リモートJMSプロバイダを統合するためのツールは用意されていますか。

A.次の表に、リモートJMSプロバイダを統合するために使用できるツールをまとめます。

方法

自動登録

JMSリソース・プーリング

リモート・プロバイダのJMSクライアントの直接使用

WebLogicサーバー・プロバイダの場合は「はい」。その他のプロバイダの場合は、プログラム的に登録を実行する必要があります。

いいえ。ただし、プログラム的に実行できます。

メッセージング・ブリッジ

はい

なし

外部JMSサーバー定義

いいえ。自動登録を実現するには、JMSリソース参照またはMDBと組み合せて使用します。

いいえ。リソース・プーリングを実現するには、JMSリソース参照またはMDBと組み合せて使用します。

JMSリソース参照

はい

はい

メッセージドリブンEJB

はい

はい

SAFクライアント

なし

なし

SAF

はい

なし

リモート・プロバイダを統合する場合のベスト・プラクティス

Q.EJBまたはサーブレット内でリモートJMSプロバイダからメッセージを受信するにはどうしたらよいですか。

A.メッセージドリブンEJBを使用します。ただし、同期受信では、レシーバがメッセージの待機をブロックしている間、サーバー側スレッドがアイドル状態になるためお薦めできません。「メッセージングBeanの使用」を参照してください。

Q.EJBまたはサーブレット内からリモートJMSプロバイダにメッセージを送信するにはどうしたらよいですか。

A.リソース参照を使用します。プーリングと自動リスト登録が提供されます。「EJB/サーブレットのJMSリソース参照の使用」を参照してください。ラッパーが十分でない場合は、独自のプーリング・コードを記述できます。

ターゲット宛先がリモートである場合は、ローカル宛先とメッセージング・ブリッジを追加して、ストア・アンド・フォワードによる高可用性設計を実装することを検討してください。「メッセージング・ブリッジの使用」を参照してください。

もう1つのベスト・プラクティスは、外部JMSサーバー定義を使用する方法です。外部JMSサーバー定義を使用すると、アプリケーションのJMSリソースを管理的に変更できるため、アプリケーション・コードにURLをハード・コード化するのを避けることができます。また、リモートJMSプロバイダを参照するためのリソース参照を有効にする場合には、外部JMSサーバー定義が必要になります。「外部JMSサーバー定義の使用」を参照してください。

Q.クライアントからリモートJMSプロバイダと通信するにはどうしたらよいですか。

A.宛先がWebLogic Serverによって提供されたものでなく、グローバル・トランザクションないの宛先での操作を含める必要がある場合は、EJB内の外部ベンダーでのJMS操作をサーバー・プロキシを使用してカプセル化します。WebLogicサーバーで実行されているアプリケーションは、現在のトランザクションにおいてトランザクション(XA)対応の非WebLogic JMSプロバイダを登録するための機能を備えています。

ストア・アンド・フォワード機能が必要な場合は、メッセージをローカル宛先に送信し、メッセージング・ブリッジを使用して外部宛先に転送することを検討してください。以下を参照してください。

- メッセージング・ブリッジの使用

- WebLogicストア・アンド・フォワードの使用

- WebLogic JMS SAFクライアントの使用

別の選択肢としては、単純にリモート・ベンダーのJNDIおよびJMS APIを直接使用するか、外部JMSプロバイダを構成して、参照のハード・コード化を避ける方法もあります。その場合は、外部プロバイダのクラス・ライブラリをクライアントのクラスパスに追加する必要があります。

Q.WebLogic JMSの相互運用機能をチューニングするにはどうしたらよいですか。

A. 『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「WebLogic Server EJBのチューニング」、「WebLogicメッセージング・ブリッジのチューニング」、および「WebLogic JMSストア・アンド・フォワードのチューニング」を参照してください。

外部JMSサーバー定義の使用

Q.外部JMSサーバー定義とは何ですか。

A.外部JMSサーバー定義は、管理的に構成されたシンボリック・リンクです。スタンドアロンのWebLogicサーバーやWebLogicクラスタにおいては、この外部JMSサーバー定義によって、リモートJNDIディレクトリ内のJNDIオブジェクト(JMS接続ファクトリ、宛先オブジェクトなど)と、JNDIネームスペース内のJNDI名との間をリンクさせています。それらは、管理コンソールまたは標準のJMX MBean APIを使用して構成せきます。または、スクリプトを使用してプログラム的に構成できます。「外部JMSプロバイダへのアクセスの簡略化」を参照してください。

Q.外部JMSサーバー定義を使用するのが最適なのはどのような場合ですか。

A.このリリースでは、外部JMSサーバー定義を使用することで、JMS JNDIパラメータを1箇所にまとめることができます。1つの定義を、複数のEJB、サーブレット、およびメッセージング・ブリッジで共有できます。定義を変更する場合にも、デプロイメント記述子を再コンパイルしたり変更したりする必要はありません。それらは、以下の場合に特に便利です:

- メッセージドリブンEJB (MDB)の標準JMS通信プロパティを、アプリケーションのEJBデプロイメント記述子にハード・コード化するのではなく、構成によって管理することが望ましい場合。これは、MDBのソース宛先がリモートでない場合にも当てはまります。

- MDBにリモート宛先が含まれている場合。この場合は、デプロイメント記述子の構成が簡略化され、管理制御を強化できます。

- EJBまたはサーブレットにおいて、リモート宛先との送受信を行う場合。

- リソース参照を有効にして、リモートJMSプロバイダを参照する場合。「EJB/サーブレットのJMSリソース参照の使用」を参照してください。

EJB/サーブレットのJMSリソース参照の使用

Q. JMSリソース参照とは何ですか。

A.リソース参照は、サーブレットおよびEJBアプリケーションの開発者が指定し、アプリケーションにパッケージ化するものです。リソース参照を使用すると、一定レベルの間接性を簡単に実現できます。つまり、JNDI名をアプリケーションのソース・コードに直接ハード・コード化するかわりに、EJB記述子に定義したJNDI名をアプリケーションから参照することが可能になります。

JMSリソース参照は、以下の2つの機能を提供します。

- JMSリソースがアプリケーションによって閉じられた場合に、それらのリソースを自動的にプーリングする

- JMSリソースを現在のトランザクションに自動登録する(非WebLogic JMSプロバイダの場合も可能)

EJBまたはサーブレットのアプリケーション・コード内でJMSリソース参照を使用するには、デプロイメント記述子にresource-ref要素を追加し、JNDIコンテキストを使用してjava:comp/env/jms/<参照名>という構文で参照をルックアップします。

リソース参照の機能は、アプリケーション・コードの外部には提供されません。したがって、メッセージドリブンEJBのソース宛先の構成や、メッセージング・ブリッジのソース宛先またはターゲット宛先の構成には使用できません。

JMSリソース参照のプーリングの詳細は、第4章「WebLogic JMSをEJBやサーブレットと組み合せて使用するために拡張されたサポート」を参照してください。

Q. JMSリソース参照を使用する利点は何ですか。

A. JMSリソース参照には以下の利点があります。

- サーブレットおよびEJBアプリケーションの移植性を確保できます。JMSリソース参照を使用することで、アプリケーションのソース・コードを再コンパイルすることなく、アプリケーションのJMSリソースを変更できます。

- JMS Connection、Session、およびMessageProducerオブジェクトの自動プーリングが可能になります。

- 非WebLogic JMSプロバイダの自動トランザクション登録が可能になります。ただし、JMSプロバイダがXA対応である必要があります。リソース参照を使用しない場合、非WebLogic JMSプロバイダを現在のトランザクションに登録するには、プログラム手順を別途記述する必要があります。

Q. 外部JMSプロバイダでは、リソース参照をどのように使用したらよいですか。

A. リソース参照でリモートJMSプロバイダを参照できるようにするには、リソース参照と外部JMS定義を組み合せて使用する必要があります。これは、リソース参照には、URLや初期コンテキスト・ファクトリを指定する場所が用意されていないためです。「外部JMSサーバー定義の使用」を参照してください。

Q. 非トランザクション・メッセージングでは、リソース参照をどのように使用したらよいですか。

A.非トランザクションの場合は、グローバル・トランザクション(XA)対応の接続ファクトリは使用しないでください。これによって、メッセージングのパフォーマンスが影響を受けます。使用した場合は、リソース参照が各メッセージング処理の内部トランザクションを自動的に開始およびコミットし、メッセージングのパフォーマンスに影響を及ぼします。「トランザクションについて」を参照してください。

WebLogicストア・アンド・フォワードの使用

Q. WebLogicストア・アンド・フォワード・サービスとは何ですか。

A. WebLogic ServerでWebLogicストア・アンド・フォワード(SAF)サービスを使用すると、複数のWebLogic Serverインスタンスに分散されているアプリケーション間でメッセージを確実に配信することができます。たとえば、SAFサービスを利用すると、ローカルのWebLogic Serverインスタンス上で動作するアプリケーション、またはローカルのWebLogic Serverインスタンスに接続するアプリケーションは、リモート・サーバー上の宛先にメッセージを確実に配信できます。ネットワークの問題やシステム障害が原因で、メッセージの送信時に宛先が使用不能になっている場合、メッセージはローカルのサーバー・インスタンスに保存されて、リモートの宛先が使用可能になった時点で転送されます。『Oracle WebLogic Serverストア・アンド・フォワードの構成と管理』の「ストア・アンド・フォワード・サービスについて」を参照してください。

Q. WebLogicストア・アンド・フォワード・サービスはどのような場合に使用すべきですか。

A. WebLogicストア・アンド・フォワード(SAF)サービスは、WebLogic Server 9.0以降のドメインの間でJMSメッセージを転送する場合に使用します。SAFサービスによるメッセージの配信対象間の関係は、以下のとおりです。

- 2つのスタンドアロンのサーバー・インスタンス間

- クラスタ内のサーバー・インスタンス間

- ドメイン内の2つのクラスタ間

- 異なるドメイン間

Q. WebLogicストア・アンド・フォワード・サービスを使用できないのはどのような場合ですか。

A. WebLogicストア・アンド・フォワード・サービスは、以下の状況では使用できません。

- リモート宛先から受信する場合 - メッセージドリブンEJBを使用するか、クライアント・コンシューマを直接実装してください。

- ローカル宛先にメッセージを送信する場合 - ローカル宛先に直接送信してください。

- 以前のリリースのWebLogic Serverにメッセージを転送する場合。「メッセージング・ブリッジの使用」を参照してください。

- サード・パーティのJMS製品(MQSeriesなど)と相互運用する場合。「メッセージング・ブリッジの使用」を参照してください。

- リクエストにレスポンスを戻すためにJMSReplyToで一時的な宛先を使用する場合

- メッセージのレイテンシに対する許容度が低い環境。SAFによってレイテンシが増加し、スループットが低下する可能性があります。

WebLogic JMS SAFクライアントの使用

Q. WebLogic JMS SAFクライアントとは何ですか。

A.JMS SAFクライアント機能は、WebLogic Server 9.0で導入したJMSストア・アンド・フォワード・サービスをスタンドアロンJMSクライアントに拡張したものです。この機能を使用することで、(一時的なネットワーク接続の障害などが原因で) JMSクライアントが宛先にアクセスできない場合でも、JMSクライアントはサーバー側のJMS宛先にメッセージを確実に送信できるようになります。サーバーとの接続が切断されている間、JMS SAFクライアントによって送信されたメッセージはクライアントのファイル・システム上でローカルに格納され、クライアントが再接続するときに、サーバー側のJMS宛先に転送されます。「JMS SAFクライアントによる確実なメッセージ送信」を参照してください。

Q. WebLogic JMS SAFクライアントはどのような場合に使用すべきですか。

A. JMSメッセージをWebLogic Server 9.0以降のドメインに転送する場合に使用します。

Q. JMS SAFクライアントを使用する場合、何か制限はありますか。

A.「JMS SAFクライアントの使用に関する制限」を参照してください。

メッセージング・ブリッジの使用

Q. メッセージング・ブリッジとは何ですか。

A.メッセージング・ブリッジは、WebLogic Server上で動作する管理的に構成されたサービスです。構成されたソースJMS宛先から、構成されたターゲットJMS宛先に、メッセージを自動的に転送します。これらの宛先は、ブリッジとは別のサーバーに構成できます。また、外部(非WebLogic)宛先を構成することも可能です。ブリッジの各宛先は、リモート・プロバイダの以下の4つのプロパティを使用して構成します。

- 初期コンテキスト・ファクトリ

- 接続URL

- 接続ファクトリのJNDI名

- 宛先のJNDI名

メッセージング・ブリッジでトランザクションを使用するように構成して、すべてのXA対応(グローバル・トランザクション対応) JMSプロバイダから別のプロバイダに「必ず1回」転送されるようにすることも可能です。

Q. メッセージング・ブリッジはどのような場合に使用すべきですか。

A. 通常、メッセージング・ブリッジは、ストア・アンド・フォワードによる高可用性設計要件を満たすために使用します。メッセージング・ブリッジは、送信者のローカル宛先からのメッセージを消費し、これを送信者の実際のターゲットのリモート宛先に転送するように構成されます。つまり、ターゲットのリモート宛先にアクセスできない場合でも、送信者がそのローカル宛先にメッセージを送信できるようにすることで、高可用性を提供します。リモート宛先にアクセスできない場合は、ローカル宛先が自動的にメッセージのストアを開始し、ターゲット宛先がアクセス可能になり、ブリッジからメッセージを転送できるようになるまで継続します。

Q. メッセージング・ブリッジを使用すべきでないのはどのような場合ですか。

A. 以下のような状況では、他の方法を使用することをお薦めします。

- リモート宛先から受信する場合 - メッセージドリブンEJBを使用するか、クライアント・コンシューマを直接実装してください。

- ローカル宛先にメッセージを送信する場合 - ローカル宛先に直接送信してください。

- メッセージのレイテンシに対する許容度が低い環境。メッセージング・ブリッジを使用するとレイテンシが長くなり、スループットが低下することもあります。メッセージング・ブリッジでは、メッセージ・パス内の追加宛先が導入されるためメッセージのレイテンシが長くなり、シングル・スレッドでメッセージを転送するためスループットが低下する可能性があります。

- WebLogic 9.0のドメイン間でメッセージを転送する場合 - WebLogicストア・アンド・フォワード機能を使用してください。「WebLogicストア・アンド・フォワードの使用」を参照してください。

Q.一部のメッセージが転送されないのはなぜですか。

A.通常、メッセージング・ブリッジはすべてのメッセージを転送します。一部のメッセージが転送されない場合は次の理由が考えられます。

- 一部のメッセージに有効期限がある場合、ソース宛先またはターゲット宛先のJMSプロバイダによりメッセージが失効します。

- セレクタ・フィルタを指定するようにブリッジ・ソース宛先を構成した場合、フィルタ処理されたメッセージのみが転送されます。

- ブリッジでは、転送の制限回数を超えた場合、メッセージをエラー宛先に自動で移動したり、自動で削除したりするオプションは直接提供されません。JMSプロバイダには、ブリッジ・ソース宛先でメッセージに関する同様の機能をもたらすオプションがあります。ブリッジ・ソース宛先をホストするJMSプロバイダで再配信制限オプションが有効な場合、ブリッジの自動再試行メカニズムがメッセージの再配信制限を超えないようにプロバイダを再構成する必要があります。

メッセージングBeanの使用

Q. メッセージドリブンEJB (MDB)とは何ですか。

A.メッセージドリブンEJBは、標準のJMS APIを内部的に使用するEJBコンテナです。ローカル、リモート、または外部JMS宛先から非同期でメッセージを受信し、そのメッセージを処理するアプリケーション・コードを呼び出します。MDBには以下のような特性があります。

- ソース宛先に自動的に接続し、リモート宛先にアクセスできない場合は自動的に接続を再試行します。

- JMSプロバイダがWebLogicでない場合でも、コンテナ管理のトランザクションでの受信メッセージの自動登録をサポートします。

- JMS接続、セッション、およびコンシューマを自動的にプールします。

- MDBのソース宛先、URL、および接続ファクトリは、アプリケーションの一部としてパッケージ化されるEJBおよびWebLogic記述子に構成されます。

- メッセージング処理のアプリケーション・ロジックは、単一のメソッド・コールバックonMessage()に含まれています。

- トランザクション、セキュリティ、JDBCなどの典型的なEJBアクションをサポートする完全なEJBです。

詳細は、『Oracle WebLogic Server Enterprise JavaBeansのプログラミング』の「メッセージドリブンEJB」を参照してください。

Q. MDBはどのような場合に使用すべきですか。

A. MDBは、JMSメッセージを受信および処理するWebLogic Serverアプリケーションに適したメカニズムです。

Q. MDBと一緒にメッセージング・ブリッジを使用する必要はありますか。

A. MDB間にメッセージング・ブリッジを配置するのではなく、MDBがソース宛先から直接消費するように構成してください。MDBは、ソース宛先にアクセスできない場合には自動的に接続を再試行するため、メッセージ・パス内にメッセージング・ブリッジを配置してさらに高可用性を提供する必要はありません。メッセージング・ブリッジを配置すると、パフォーマンスに影響が及ぶ可能性があります。「メッセージング・ブリッジの使用」を参照してください。

Q.MDBにはどのような構成が最適ですか。

A.以下に、MDBを構成する際のヒントを示します。

- MDBの同時実行性とスレッド・プールを構成するには、max-beans-in-free-poolおよびdispatch-policy記述子フィールドを使用します。MDBのスレッド・プール内の使用可能なサーバー・スレッドの数によっては、同時に作成されるインスタンスの数がmax-beans-in-free-poolの値よりも少なくなることがあります。

- リモートJMSプロバイダから消費するようにMDBを構成する場合は、外部JMSサーバー定義を使用します。WebLogic MDB記述子から直接リモート宛先を参照するように構成することも可能ですが、この情報はアプリケーションにパッケージ化されてしまうため、動的に変更することができません。外部JMSサーバー定義を構成し、MDBが外部定義を参照するように構成することをお薦めします。なお、一部のドキュメントでは、外部JMSサーバー定義を「ラッパー」と呼んでいます。「外部JMSサーバー定義の使用」を参照してください。

- コンテナ管理のトランザクション用にMDBを構成する場合は注意が必要です。MDBでコンテナ管理のXAトランザクションをサポートするには、MDBの記述子ファイルでtransaction-typeをContainer、trans-attributeをRequiredに設定し、XA対応のJMS接続ファクトリを使用する必要があります。このように設定しないと、MDBはトランザクション非対応になります。WebLogicのデフォルト設定では、MDBの接続ファクトリはXA対応になっています。MDBは、トランザクションを自動的に開始し、トランザクション内で受信したメッセージを自動的に登録します。

AQ JMSの使用

Q.AQ JMSと相互運用できますか。

A.Oracle WebLogic Serverアプリケーションでは、WebLogic Serverリソース(Webアプリケーション、EJB、MDB)またはスタンドアロン・クライアントを使用し、JMS APIを介してOracle Streamsアドバンスト・キューイング(AQ)と相互運用します。AQ JMSでは、WebLogic Serverクラスタ全体にアクセス可能なデータベースに格納されたJMSメッセージと、データベース接続を使用して、データベース機能やデータ操作およびバックアップのツールを利用できるようにします。

WebLogic Serverリソース(Webアプリケーション、EJB、MDB)またはスタンドアロン・クライアントを使用し、JMS APIを介してOracle Streamsアドバンスト・キューイング(AQ)と相互運用するにはJMS外部サーバー構成を使用します。『Oracle WebLogic Server JMSの構成と管理』のOracle AQ JMSとの相互運用に関する項を参照してください。

Q.作成したOC4JアプリケーションをWebLogic Serverに移行するにはどうすればよいですか。

A.Oracle OC4JアプリケーションをOracle WebLogic Serverアプリケーションに移行する方法については、『Oracle Fusion Middleware Java EEアップグレード・ガイド』を参照してください。

JMSの相互運用性に関するドキュメント

Q.JMSの相互運用性に関するドキュメントは他にもありますか。

A.WebLogic JMSの一般的な情報については、メッセージングを参照してください。

C 宛先のルックアップ方法

この章では、JNDIおよび宛先識別子の作成を使用してメッセージの宛先をルックアップする方法について説明します。

- JNDI名の使用

- 宛先識別子の作成の使用

- 宛先のルックアップに使用する構文の例

注意:
JMSリソースの構成方法については、『Oracle WebLogic Server JMSの構成と管理』のJMSリソース構成の理解に関する項を参照してください。

JNDI名の使用

宛先のタイプをルックアップするには、JNDIを使用することをお薦めします。宛先は、JNDIコンテキスト(context)を確立して、PTPまたはpub/subメッセージングでそれぞれ次のようなコマンドを実行することでルックアップできます。

Queue queue = (Queue) context.lookup(Dest_name);

Topic topic = (Topic) context.lookup(Dest_name);

Dest_name引数は、構成時に定義された宛先のJNDI名を指定します。「JNDI名の使用」と「宛先のルックアップに使用する構文の例」を参照してください。

宛先識別子の作成の使用

宛先識別子の作成(CDI)は、あまり一般的ではありませんが、JNDIを使用しない方法として、宛先または分散宛先のメンバーをルックアップします。CDIは、次のようなQueueSessionまたはTopicSessionのいずれかのメソッドを使用して、それぞれキューまたはトピックを参照します。

public Queue createQueue(
String queueName
) throws JMSException

public Topic createTopic(
String topicName
) throws JMSException

queueNameおよびtopicName文字列の構文は、JMS仕様で定義されません。WebLogic JMSの構文については、次の項で説明します。

- デフォルトのWebLogic CDI構文

- カスタムWebLogic CDI構文

注意:
createQueue()メソッドとcreateTopic()メソッドでは宛先が動的には作成されず、既存の宛先への参照のみが作成されます。宛先の動的な作成については、第7章「JMSモジュール・ヘルパーを使用したアプリケーションの管理」を参照してください。

デフォルトのWebLogic CDI構文

JMSサーバー名、モジュール、および宛先構成名を含む文字列。「宛先のルックアップに使用する構文の例」を参照してください。

カスタムWebLogic CDI構文

デフォルトのCDI構文の他に、WebLogic JMSでは、宛先または共通分散宛先の追加の構成パラメータとしてJMSCreateDestinationIdentifierが提供されます。このパラメータでは、デフォルトのCDI構文と同じ値のキューまたはトピックが(1つ以上のモジュールで)複数定義されている場合、一意の参照名を構成できます。つまり、2つの異なるモジュール内に2つの異なる宛先があり、そのデフォルトのCDI名が同じ場合にこれらの宛先を区別する際に役立ちます。「宛先のルックアップに使用する構文の例」を参照してください。

この名前は、この宛先のターゲットとなるJMSサーバーのスコープ内で一意である必要があります。ただし、JMSモジュール全体のスコープ内で一意である必要はありません。たとえば、2つのキューは、それぞれ異なるJMSサーバーをターゲットにする限り、同じCDI名を持つことができます。

注意:
この名前はJMSサーバーのスコープ内で一意でなければならないため、この名前と競合する宛先名が他のJMSモジュールに含まれている可能性があるかどうかを確認します。JMSサーバーをターゲットとする宛先名を解決するのは、デプロイヤの役目です。

宛先ルックアップ時のサーバー・アフィニティ

createTopic()およびcreateQueue()メソッドでは、「./Destination_Name」構文を使用して、宛先をルックアップする場合のサーバー・アフィニティを示すこともできます。これにより、JMS接続の接続ファクトリ・ホストと同じJVMにローカルにデプロイされた宛先の位置が指定されます。名前がローカルJVMにない場合は、同じ名前が別のJVMにデプロイされていても例外がスローされます。

アプリケーションでこの規約を利用すると、createTopic()メソッドおよびcreateQueue()メソッドを使用する場合にサーバー名をハード・コード化せずに済むので、コードを変更しなくても別のJMSサーバー上でコードを再利用できます。

宛先のルックアップに使用する構文の例

次の項では、宛先または分散宛先のメンバーの参照に使用する構文の例を示します。

- 非分散宛先

- 共通分散宛先

- 重み設定された分散宛先

非分散宛先

次の項では、通常の宛先(分散されない宛先)の参照に使用される構文の例を示します。

- 非分散宛先のJNDI構文

- 非分散宛先のCDI構文

非分散宛先のJNDI構文

ほとんどのアプリケーションでは、CDIではなくJNDIを使用して宛先をルックアップします。次の項では、JNDIによる非分散宛先の参照に使用される構文の例を示します。

- JNDI名を構成する場合は、以下のように定義されます。
Dest_JNDI_Name

- ローカルJNDI名を構成する場合、以下のように定義されます。
Dest_Local_JNDI_Name

注意:
ローカルJNDI名は、JNDIコンテキスト・ホストが非分散宛先と同じサーバー上に存在する場合にのみ機能します。JNDIコンテキスト・ホストは、JMS接続ホストと同じであるとは限りません。

非分散宛先のCDI構文

この項では、CDIを使用したcreateQueueまたはcreateTopicで非分散宛先の参照に使用される構文の例を示します。

- デフォルトのCDIを使用する場合、文字列は次のように定義されます。
JMS_Server_Name/JMS_Module_Name!Destination_Name

- 相互運用モジュールでデフォルトのCDIを使用する場合、文字列は次のように定義されます。
JMS_Server_Name/interop-jms!Destination_Name

- カスタムCDIを構成する場合、文字列は次のように定義されます。
JMS_Server_Name/CDI_Name

注意:
(JMS_Server_Nameを「.」に置き換えて)サーバー・アフィニティを使用する場合は、検索がクラスタ全体ではなくJMS接続ホストに制限されます。
WebLogic Server 9.0より前のリリースで宛先を参照する場合は、JMS_Server_Name!Destination_Name(例: myjmsserver!mydestination)で定義される文字列を使用してください。

共通分散宛先

次の項では、共通分散宛先(UDD)の参照に使用される構文の例を示します。

- JNDI構文(UDDの場合)

- UDDのCDI構文

JNDI構文(UDDの場合)

ほとんどのアプリケーションでは、CDIではなくJNDIを使用して宛先をルックアップします。次の項では、JNDIを使用して各メンバーまたは論理UDDを参照する方法の例を示します。

- 論理UDDの場合、文字列は次のように定義されます。
udd-jndi-name

- 個々のメンバーの論理UDDについては、文字列は次のように定義されます。
jms-server-name@udd-jndi-name

UDDのCDI構文

注意:
ヘルパー・メソッドweblogic.jms.extensions.JMSModuleHelperクラスのuddMemberNameとuddMemberJNDIName APIを使用すると、正しい構文でUDD CDI名を作成する際に役立ちます。

この項では、CDIを使用したcreateQueueまたはcreateTopicでUDDメンバーを参照する方法の例を示します。

- CDIを構成しない場合の個々のメンバーについては、以下のように定義されます。
jms-server-name/module-name!jms-server-name@udd-name

- CDIを構成する場合の個々のメンバーについては、以下のように定義されます。
jms-server-name/cdi-name

- 論理UDDを参照する場合、module-name!udd-nameで定義される文字列を使用します。

注意:
jms-server-nameを「.」で置き換える場合、APIは、最初に論理上使用可能な/開始されるUDQのメンバーを返します。メンバーを現在ホストしている同じWebLogicサーバーでJMSクライアント接続がホストされる場合、メンバーはローカルで使用可能と見なされます。

重み設定された分散宛先

注意:
重み設定された分散宛先は、WebLogic Server 10.3.4.0では非推奨です。共通分散宛先を使用することをお薦めします。

重み設定された分散宛先は、個々に構成された通常の宛先のセットであり、それぞれに独自のJNDI名とCDI名があります。WDDの論理名は、セット全体を表し、JNDI名として構成されます。CDIを使用してWDDの論理にアクセスする方法はありません。

- WDDのJNDI構文

- WDDのCDI構文

WDDのJNDI構文

次の項では、JNDIを使用して個々のメンバーまたは論理WDDを参照する方法の例を示します。

- 論理WDDの場合、文字列は次のように定義されます。
wdd-jndi-name

- 個々のメンバーの論理WDDについては、「非分散宛先のJNDI構文」を参照してください。

WDDのCDI構文

この項では、CDIを使用する場合と使用しない場合のcreateQueueまたはcreateTopicによるWDDメンバーの参照方法の例を示します。

- createQueue()またはcreateTopic()を使用してWDD論理名にアクセスする方法はありません。論理WDDは、メンバーのJNDI名で定義される文字列を使用して常に参照される必要があります。非分散宛先の場合、かわりにサーバー・アフィニティ構文「.」を使用して各論理メンバーをルックアップする方法が便利な場合があります。

- CDIをメンバーで構成する場合の個々のメンバーについては、「非分散宛先のCDI構文」を参照してください。

D JMS宛先の可用性ヘルパーAPIを使用した分散宛先に関する拡張プログラミング

この章では、クラスタ環境でJMS分散宛先の使用時に、高可用性(HA)、スケーラビリティ、および柔軟性を提供する分散アプリケーションまたはコンテナを設計する方法について説明します。

重要:
このガイドには、経験豊富なJMS開発者向けの高度な情報が記載されています。分散宛先と相互運用する際はメッセージドリブンBeanを使用することをお薦めします。MDBコンテナは、分散宛先のすべてのメンバー間で内部コンシューマを必要に応じて自動的に作成して閉じます。また、セキュリティ、スレッド化、プーリング、アプリケーション・ライフサイクル、自動再接続、トランザクションのリスト化も処理します。MDBを使用できない場合、より簡単な回避策(分散宛先でコンシューマをリバランスするようにコンシューマを定期的に再起動したり、メッセージの順序付けやパフォーマンスを気にしない場合は、分散キューの転送オプションを有効にしたりするなど)も検討できます。

- はじめに

- DDプロデューサ・ロード・バランシングの制御

- JMS宛先可用性ヘルパーAPIの使用

- 共通分散キュー・コンシューマ用の方針

- 共通分散トピックに関するサブスクライバ用の方針

はじめに

分散宛先(DD)は、単一の論理宛先(キューまたはトピックのグループ)としてアクセスされるJMS物理宛先のグループです。メッセージはメンバー間でロード・バランシングされ、クライアントはメンバー宛先間でフェイルオーバーできます。

MDBを利用しない分散宛先ユーザーの場合、コンシューマ・アプリケーションに関する問題が生じることがあります。たとえば、次のような問題があります。

- すべてのDDメンバーをコンシューマで確実に処理できません。

- コンシューマのないDDメンバーに未処理のメッセージが蓄積されます。

- JMSサーバーの移行時、WebLogic Serverの再起動時、あるいはDDメンバーに変更が生じるイベントの際にDDコンシューマが自動的にリバランスしません。

このような事例を解決するため、WebLogic Serverは、「拡張パブリッシュ/サブスクライブ・アプリクーションの開発」で示されるように、JMS宛先高可用性ヘルパーAPIおよび拡張トピック機能を提供します。

DDプロデューサ・ロード・バランシングの制御

コンシューマ・ロード・バランシングについて説明する前に、プロデューサ・ロード・バランシングの基本事項とベスト・プラクティスを最初に確認しておくと便利です。

- 基本のJMS

- 分散キュー(DQ)およびパーティション化された分散トピック(PDT)へのセンダー

- レプリケートされた分散トピック(RDT)へのセンダー

基本のJMS

JMSプログラムは、次の3つの段階でメッセージ送信を設定します。

1. クライアントは、JMS接続ファクトリを使用してWebLogicへのJMS接続を作成します。

2. クライアントはこの接続を使用して、JMSのセッションとセンダーを作成します。

3. クライアントは、このセンダーを使用してメッセージを送信します。

WebLogic JMSでは、クライアントが接続するWebLogicサーバーはクライアントの接続ホストと呼ばれ、メッセージは常にセンダーからその接続ホストを介して、接続ホストと同じクラスタ内の宛先にルーティングします。接続は、その有効期間中は接続ホストに固定されます。

WebLogic接続ファクトリは、1つ以上のWebLogicサーバーでターゲット指定できます。接続ファクトリがターゲット指定される同じWebLogicサーバーでクライアントが実行している場合、ファクトリは常に、クライアントと同じサーバーの接続ホスト(接続はローカル)で接続を返します。一方で、接続ファクトリのターゲットに含まれるWebLogicサーバーでクライアントが実行していない場合、ファクトリはターゲット間で自動的にロード・バランシングして、そのいずれかに接続を返します。

センダーが分散宛先で機能する場合、各メンバーのJNDI名に送信するのではなく、DQまたはPDTのJNDI名(その論理名)に常に送信します。これにより、ロード・バランシング動作の自動化が可能になります。

分散キュー(DQ)およびパーティション化された分散トピック(PDT)へのセンダー

DQまたはPDTに対するセンダーのデフォルト動作では、メンバーがセンダーの接続ホストで実行する場合、すべての送信メッセージはいずれかのローカル・メンバーに送信されます。それ以外の場合、メッセージはすべてのメンバー間でラウンドロビンします。

ローカル・メンバーがセンダーの接続ホストに存在する場合でも、同じDQまたはPDTセンダーのメッセージをすべてのアクティブなメンバー間でラウンドロビンするようにするには、Server Affinityをfalseに、Load Balanceをtrueに設定してカスタム接続ファクトリを使用します。

レプリケートされた分散トピック(RDT)へのセンダー

RDTへのセンダーは、常にロード・バランシングを1回実行し、次にすべてのメッセージの特定のメンバーに固定します。このメンバーが「センダー・ホスト」になります。メッセージがセンダー・ホストに着信すると、メッセージはすべてのRDTメンバー上にあるすべてのサブスクリプションに自動的に複製されます。

センダー・ホストに対する初期ロード・バランシング判定が、接続ホストへの判定と同じ扱いにならないように制御する場合、false (デフォルトはtrue)に構成された「サーバー・アフィニティ」およびtrue (デフォルト)に構成された「ロード・バランシング」と共に接続ファクトリを使用します。

JMS宛先可用性ヘルパーAPIの使用

次の項では、JMSDestinationAvailabilityHelper APIの使用方法について説明します。

- 概要

- 一般的なフロー

- weblogic.jms.extension.DestinationDetailの処理

- コンシューマ・コンテナのベスト・プラクティス

- 相互運用性ガイドライン

- セキュリティの考慮事項

- トランザクションについて

概要

クライアントのjavax.jms APIを使用してコンシューマを作成し、DD論理JNDI名を指定した場合、コンシューマはアクティブなDDメンバーにロード・バランシングされ、その存続期間中は該当メンバーに固定されます。すべてのコンシューマの作成後に新しいメンバーがアクティブになる場合、新しいメンバーにコンシューマはありません。

JMSDestinationAvailabilityHelper APIにより、宛先が使用可能または使用不可になる場合に通知を取得する手段が提供されます。これらの通知は、アプリケーションを初期化したときに使用不可のメンバーが存在する場合でもすべてのDDメンバーでアプリケーションがコンシューマを作成する際に役立ちます。同じメカニズムを使用して、他のタイプの宛先(WebLogic分散宛先のみではなく、通常の宛先や外部ベンダーの宛先)の可用性を検出することもできます。

アプリケーションは、JNDIコンテキスト・パラメータと宛先のJNDI名を指定して、ヘルパーに通知リスナーを登録します。DDについては、メンバーが使用可能および使用不可になる場合、アンデプロイされる場合、新しいメンバーとして追加される場合、移行、停止、再起動する場合に、ヘルパーによってリスナーに通知されます。

WebLogic ServerのMDBは、両方のローカルMDB (DDと同じクラスタにデプロイされたMDB)とリモートMDB (DDをホストするクラスタとは別のクラスタにデプロイされたMDB)に同じメカニズムを内部で使用することに注意してください。MDBには、JMSDestinationAvailabilityHelper APIが提供する同じ動的適応性をDDトポロジ変更に対して実現する即時利用可能なソリューションがあります。

一般的なフロー

JMSDestinationAvailabilityHelper APIを使用するアプリケーションは、次の一般的なステップに従います。

1. 下記のステップ3の動作を実現するため、weblogic.jms.extensions.DestinationAvailableListenerインタフェースを実装します。

2. JNDIコンテキスト・プロパティ(通常はURLとコンテキスト・ファクトリのみ)、宛先のJNDI名、リスナー・インスタンスを指定して、ヘルパーに関連事項を登録します。クライアントがDDと同じクラスタで実行している場合はURLを指定しないでください。

import java.util.Hashtable;
import javax.naming.Context;
import weblogic.jms.extensions.JMSDestinationAvailabilityHelper;

Hashtable contextProps = new Hashtable();
contextProps.put(javax.naming.Context.PROVIDER_URL, myURL);
contextProps.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
JMSDestinationAvailabilityHelper dah = JMSDestinationAvailabilityHelper.getInstance();

RegistrationHandler rh = dah.register(
contextProperties,
destinationJNDIName,
myDestinationAvailableListener
)

3. リスナー・コールバックを処理します。各リスナー・インスタンスに対するコールバックは単一のスレッドがあり、これにより、2つのコールバックが同時に発生することはあります。

1. onDestinationsAvailable() - 通常は最初の通知。このコールバックの実装は、指定の各宛先でゼロ以上のコンシューマを作成すると反応するのが一般的です。これが失敗した場合、定期的に再試行します。

2. onDestinationsUnavailable() - このコールバックは、通常、宛先で既存のコンシューマを破棄する場合に使用されます。

3. onFailure() - このコールバックは、通常、生じた失敗のログを記録する場合に使用されます。ヘルパーは引き続き内部で再試行し、以降のコールバックを行いますが、管理者は失敗を確認する必要があります。ヘルパーは、最善を尽くして、繰り返される同じ失敗に対してonFailure()を一度呼び出します。

4. 完了したら、rh.unregister()を呼び出して宛先の関連事項の登録を解除します。

weblogic.jms.extension.DestinationDetailの処理

前述のように、onDestinationsAvailable()通知は、スタンドアロンの宛先、外部宛先、分散宛先のメンバーが使用可能になることを示します。通知はDestinationDetailインスタンスのリストで構成され、キー情報は各DetailでgetDestinationType()、getJNDIName()、isLocalWLSServer()、isLocalCluster()を呼び出すことで取得されます。

宛先の詳細は、呼出し元が行うアクションの決定に役立ちます。宛先のタイプがDD_QUEUE、REPLICATED_DTまたはPARTITIONED_DTの場合、詳細のgetJNDIName()メソッドにより、特定のDDメンバーのJNDI名が返されます。呼出し元はアプリケーション・コンシューマのインスタンスをメンバーにデプロイする場合としない場合があります。宛先のタイプがPHYSICALまたはFOREIGNの場合、アプリケーションは宛先を通常の宛先として扱います。

特にDDで使用する場合、DestinationDetailのコロケーション・フラグを利用することを強くお薦めします。宛先のコロケーションの性質を判断するには、isLocalWLSServer()とisLocalCluster()を呼び出します。「ローカル・サーバー・コンシューマのベスト・プラクティス」を参照してください。

APIとそのメソッドの詳細は、Oracle WebLogic Server APIリファレンスのDestinationDetailに関する項を参照してください。

コンシューマ・コンテナのベスト・プラクティス

次の項では、コンシューマ・コンテナのベスト・プラクティスのガイドラインを示します。

- 登録と登録解除のタイミング

- URLの処理

- 失敗の処理

- JNDIコンテキストの処理

- JMS接続の処理

登録と登録解除のタイミング

1. アプリケーションのデプロイメント時にJMSDestinationAvailabilityHelperに登録します。ヘルパーがリスナーでonFailure()コールバックを呼び出す場合、デプロイメントを失敗しないでください(断続的な失敗になると想定されます)。

2. アプリケーションのアンデプロイメント時にJMSDestinationAvailabilityHelperへの登録を解除します。

URLの処理

1. クライアントが宛先と同じサーバーまたは同じクラスタで実行している場合、ヘルパーへの登録やJNDIコンテキストの作成時にURLを指定しないでください。これにより、ヘルパーは確実にローカル・コンテキストを作成します。

2. isLocalCluster()またはisLocalServer()がtrueを返しても、URLを指定した場合(この場合URLは不要)、1つの警告ログと見なします。

失敗の処理

1. onFailure()通知で報告されるエラーのログを記録するため、アプリケーションの開発者は、構成/アプリケーションのエラーを修正することができます。同じ例外のログを繰り返し記録することは避けてください。ヘルパーは引き続き内部で再試行し、成功または異なるタイプの失敗に対して以降のコールバックを行いますが、管理者は失敗を確認する必要があります。エラーは、不正なURL、無効なセキュリティ情報、存在しない宛先などのアプリケーションまたは管理上のエラーが原因で発生します。また、JNDIコンテキストのホストまたは宛先が一時的に使用不可になる場合にも発生します。

2. JMS呼出しが例外をスローするか、JMS接続例外リスナーが接続の失敗を報告した場合、接続を閉じます。すべてのリソースの誤りが修正されたら、すべてのリソースを定期的に再初期化します。再初期化には、通常、コンテキストの作成、JNDIルックアップの実行、接続、セッション、コンシューマの作成が必要です。

3. 失敗後すぐに再試行することは避けてください。かわりに数秒ごとに定期的に再試行して、サーバーがオーバーロードしないようにします。

JNDIコンテキストの処理

1. 通常、同一のサーバーまたはクラスタに対して複数のJNDI初期コンテキスト・インスタンスを作成しないようにします。

注意:
特にドメイン間シナリオなどの一部のセキュリティ問題を解決するには、追加のコンテキスト・インスタンスを使用する必要があります。

2. アンデプロイ時にコンテキストでclose()を呼び出して、メモリー・リークを防止します。

3. コンテキストでclose()を呼び出して、失敗時(ルックアップの失敗を含む)に再作成します。

JMS接続の処理

1. JMS接続の場合、標準のJMS接続「例外リスナー」を必ず登録します。

2. onException()で接続を閉じてJNDIルックアップを定期的に再試行し、JMS接続を再作成して別のスレッドでコンシューマを設定します。

3. アンデプロイ時に接続を閉じて、メモリー・リークを防止します。

4. 複数のセッション間でWebLogic Server接続を共有するのではなく、セッションにつき1つの接続を作成することを検討します。WebLogic Serverでは、複数の接続によりロード・バランシング機能が向上します。WebLogic Serverを使用する場合、パフォーマンス・ペナルティはありませんが、一部の外部ベンダーは接続ごとにTCP/IPソケットや同様の高価なリソースを作成するため、外部ベンダーによる予想外のオーバーヘッドが生じる場合があります。

相互運用性ガイドライン

Oracle WebLogic Server APIリファレンスのJMSDestinationAvailabilityHelperには、使用可能な各種メソッドの使用法や動作に関する詳細があります(次の項で説明する相互運用性ガイドラインに関する詳細を含む)。

- APIの可用性

- 外部コンテキスト

- 宛先タイプのサポート

- 使用不可の通知

- WebLogic Server 9.0以前の分散キューとの相互運用

- WebLogic Server 10.3.4.0以前の分散トピックとの相互運用

- DestinationDetailのフィールド

APIの可用性

パブリックJMS宛先可用性ヘルパーAPIは、AS11gR1PS2(WebLogic Serverバージョン10.3.3)以降のクライアントとサーバーで利用できます。

外部コンテキスト

DAヘルパーに通知リスナーを登録する際に指定するコンテキスト・プロパティは、外部ベンダーや旧バージョンのWebLogic Serverのコンテキストを含む有効なJNDIコンテキストに解決できます。

外部(WebLogic以外の)コンテキストの場合、外部JNDIベンダーのクラスは現在のクラスパス内に存在する必要があります。また、Context.INITIAL_CONTEXT_FACTORYプロパティは、外部ベンダーのJNDIコンテキスト・ファクトリのクラス名を参照する必要があります。

宛先タイプのサポート

JMSDestinationAvailabilityHelper APIは、JNDIコンテキストに登録できるどのタイプの宛先(非分散宛先、外部ベンダーの宛先など)でも機能します。ただし、使用不可の通知は、DDメンバーに対してのみ生成され、DestinationDetailの特定のフィールドはDDメンバーにのみ適用されます。使用不可の通知は、外部宛先には適用されません。

使用不可の通知

使用不可の通知は、DDタイプの宛先にのみ適用されます(DQ_QUEUE、PARTITIONED_DT、REPLICATED_DT)。

WebLogic Server 9.0以前の分散キューとの相互運用

DAヘルパーがWebLogic Server 9.0以降のDDと相互運用する場合、DDのメンバーごとに通知が生成されますが、9.0以前のバージョンと使用する場合、DD宛先の論理JNDI名を含む単一のDestinationDetail通知のみが生成され、getDestinationType()はPHYSICALを返します。

WebLogic Server 9.0以前のDDは、通常の宛先として扱われることが多いため、「レプリケートされた分散トピック使用時のアプリケーション設計制限」で説明した概略と同様の制限を持つことになります。

WebLogic Server 10.3.4.0以前の分散トピックとの相互運用

WebLogic Server 10.3.4以前のリリースでは、無制限(非排他的)client-idまたは共有サブスクリプションを有効化する機能がありません。

注意:
無制限client-idおよび共有サブスクリプションを有効化する方法の詳細は、『Oracle WebLogic Server JMSの構成と管理』の無制限ClientIDの構成および共有サブスクリプションの構成に関する項を参照してください。

宛先がWebLogic 10.3.4.0以降のトピックかどうかを判定するには、宛先タイプがPHYSICAL_TOPIC, REPLICATED_DTまたはPARTITIONED_DTで、FOREIGN_TOPICになっていないことを確認し、isAdvancedTopicSupported()がtrueを戻すことを確認します。WebLogic Server 10.3.4.0以前のトピックは次のとおりです。

- PARTITIONED_DTにはなりません。

- PHYSICAL_TOPICは通常トピックとして扱われることが多く、サブスクリプションごとに1つのコンシューマに制限されます。

論理DT名が指定されているとき、WebLogic 10.3.4.0以前のDTメンバーそれぞれに対して恒久的なサブスクライバを自動的に試行しようとすることはお薦めできません。ご使用のアプリケーションがこのオプションをサポートしないようにすることをお薦めすると共に、WebLogic 10.3.4.0以前のDT上の恒久サブスクリプションが、論理DT名を指定するかわりにメンバーのJNDI名を直接指定する必要があることをユーザーに通知するエラー・ログを記録することをお薦めします。

WebLogic Server 10.3.4.0以前の分散トピックを非恒久的にサブスクライブする場合、任意の単一のメンバーJNDI名上または論理DR名上でコンシューマを作成し、他のすべての通知を無視することをお薦めします(あるサブスクライバがDTに送信されるすべてのメッセージを取得するため、サブスクリプション上にはコンシューマ・スレッドが1つのみ存在できます)。

DestinationDetailのフィールド

一部の宛先詳細フィールドの動作は、宛先のタイプ、JMSベンダー、WebLogic JMS動作時のWebLogic Serverバージョンに基づいて変わります。Oracle WebLogic Server APIリファレンスのJMSDestinationAvailabilityHelperに関する項を参照してください。

セキュリティの考慮事項

次の項では、Java EEおよびWebLogic Serverセキュリティ・モデルを使用したセキュリティの実装について説明します。

- WebLogic Serverセキュリティ・モデル

- スレッド間の資格証明の受渡し

- クロス・ドメイン・セキュリティの使用タイミング

- ユーザーの認証

- 宛先の保護

- ワイヤー・データの保護

WebLogic Serverセキュリティ・モデル

WebLogic資格証明の伝播は、多くの場合、スレッドを基準に実行されます。現在のスレッド資格証明は、JNDIコンテキストまたはアプリケーション記述子の作成時に指定することによって確立されます。このような資格証明は、WebLogic JMS呼出しを含むJVM間のRMIベースの呼出しと共に自動的に伝播されます。

スレッド間の資格証明の受渡し

コンテキスト・インスタンスが異なるスレッドに渡されてそこで使用される場合、JNDIコンテキストに関連付けられる件名は失われます。これによって、一部のマルチ・ドメイン・アプリケーション・シナリオでセキュリティ問題が起こる可能性があります。次の項では、資格証明の受渡しに関するメソッドを説明します。

- 同一スレッドの使用

- 匿名ユーザーとしての受渡し

- 初期コンテキストからの件名のキャッシュと再利用

同一スレッドの使用

可能な場合、コンテキスト作成のために同一スレッドを使用して問題の発生を避け、すべてのJMSおよびJNDI操作を実行してコンテキストを閉じます。

匿名ユーザーとしての受渡し

JMS宛先とJNDIリソースが保護されていない場合、匿名の件名を使用します。特に、複数のWebLogicドメイン間で相互運用するとき、JMS宛先とJNDIリソースが保護されていない場合には、通常、すべての呼出しが匿名の件名を使用するように強制することが最も簡単な方法となります。非匿名資格証明情報は通常、特定のドメインに対してのみ有効で、異なるドメインを使用するように試行を実行する場合、セキュリティの例外が発生することに繋がります。

匿名ユーザーとしての受渡し

JMS宛先とJNDIリソースが保護されていない場合、匿名の件名を使用します。特に、複数のWebLogicドメイン間で相互運用するとき、JMS宛先とJNDIリソースが保護されていない場合には、通常、すべての呼出しが匿名の件名を使用するように強制することが最も簡単な方法となります。非匿名資格証明情報は通常、特定のドメインに対してのみ有効で、異なるドメインを使用するように試行を実行する場合、セキュリティの例外が発生することに繋がります。

次のコードでは、件名をキャッシュし、匿名ユーザーを使用して別のスレッドに関連付ける方法の例を示します。

import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;

import weblogic.security.subject.AbstractSubject;
import weblogic.security.SubjectUtils;
import weblogic.security.Security;

class MyClass {

void doSomethingAsAnonymous() {

// get the anonymous user
AbstractSubject anon = SubjectUtils.getAnonymousSubject();

// run some operation as the anonymous user
try {
Security.runAs(anon.getSubject(),
new java.security.PrivilegedExceptionAction() {
public Object run()  throws Exception {
//  do something;
return null; // or return some Object
}});
} catch (PrivilegedActionException e) {
//  handle exception
}
}
}

初期コンテキストからの件名のキャッシュと再利用

次のコードでは、件名をキャッシュし、匿名ユーザーを使用して別のスレッドに関連付ける方法の例を示します。

import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;

import javax.security.auth.Subject;
import weblogic.security.Security;

class MyClass {

// don't make the cached subject public
private Subject subject;

MyClass() {
subject = Security.getCurrentSubject();
}

void doSomething() {

// run some operation as the subject on the original thread
try {
Security.runAs(subject,new PrivilegedExceptionAction() {
public Object run()  throws Exception {
//  do something;
return null; // or return some Object
}});
} catch (PrivilegedActionException e) {
// handle exception
}
}
}

クロス・ドメイン・セキュリティの使用タイミング

クロス・ドメイン・セキュリティは、2つ以上のWebLogic Serverドメイン全体のセキュリティを確立するためにWebLogic Server 10.0で導入された機能です。WebLogic Serverは、クロス・ドメイン・ユーザーのセキュリティ・ロールを確立し、各ドメインでWebLogic資格証明マッピング・セキュリティ・プロバイダを使用してクロス・ドメイン・ユーザーに使用される資格証明を保存します。クロス・ドメイン・セキュリティ機能は、ドメイン・ベースごとに有効化できます。クロス・ドメイン資格証明マッピングは、内部通信の保護が必要な各リモート・ドメインに構成される必要があります。JTA、MDB、およびJMSは、この機能に依存する3つのサブシステムです。クロス・ドメイン・セキュリティを構成する方法の詳細は、次を参照してください。

- 『Oracle WebLogic Serverの保護』のWebLogic Serverドメイン間の信頼関係の有効化に関する項

- 『Oracle WebLogic Server JMSのプログラミング』の「クロス・ドメイン・セキュリティの使用」

- 『Oracle WebLogic Serverストア・アンド・フォワードの構成と管理』のSAFおよびクロス・ドメイン・セキュリティに関する項

- 『Oracle WebLogic Server JTAのプログラミング』のクロス・ドメイン・セキュリティの構成に関する項

- 『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』のMDBとクロス・ドメイン・セキュリティの併用に関する項

ユーザーの認証

次の項では、アプリケーションを認証し、JNDIやJMS操作のアプリケーションも認可するJMSアクセス時のユーザー名とパスワードを説明します。

- JNDIコンテキストへの資格証明の指定

- JMS接続への資格証明の指定

- 外部JMSサーバーJNDIコンテキストの資格証明の使用

- 外部JMSサーバー接続の資格証明の使用

JNDIコンテキストへの資格証明の指定

JMSリソースにアクセスするためには、アプリケーションがJNDIプロバイダへのアクセス権を持つ必要があります。資格証明は、アプリケーション・コードがJNDIプロバイダへの初期コンテキストを作成するときに提供されます。初期コンテキストを確立するスレッドが件名を送信するため、すべてのサブシーケンス操作に使用されます。初期コンテキストの作成中にアプリケーションがWebLogic Server上で実行されていて、サーバーURLおよびセキュリティ資格証明が提供されない場合、スレッドは書きコンテキスト作成前にスレッド上にあった同一の資格証明を引き続き所持します。初期コンテキストを作成するスレッドがコンテキストを閉じるとき、スレッドは最初にコンテキスト作成前のスレッド上にある元のセキュリティ資格証明を再開します。

JMS接続への資格証明の指定

ConnectionFactory.createConnection()呼出しは、任意でユーザー名とパスワードをサポートします。接続作成時に提供される資格証明は、作成される接続上の任意のJMS操作のセキュリティに関する影響がありません(これは、WebLogic JMS Javaクライアント用のWebLogic JMS固有の動作で、.NETクライアントの例外があります)。資格証明は、接続が作成されるドメインでユーザーが有効なユーザーかどうかを確認するためにのみ使用されます。

外部JMSサーバーJNDIコンテキストの資格証明の使用

JNDIプロパティを持つ外部JMSサーバー・インスタンスを構成してJNDIプロバイダへのアクセス権を取得します。JNDIプロパティには、セキュリティ・プリンシパルと資格証明設定用のオプションが含まれます。

外部JMSサーバー接続の資格証明の使用

ユーザー名およびパスワードは、JMS接続ファクトリを参照するためにEJBまたはサーブレット・リソース・リファレンスを使用しない場合に、外部接続ファクトリ・マッピングの構成が無視されるときに指定できます。「プーリングを使用したパフォーマンスの向上」を参照してください。

宛先の保護

WebLogic JMSは、ACLを宛先に指定するための機能を提供します。この機能を使用すると宛先を保護でき、認可されたユーザーのみが宛先上で操作を実行できるようになります。『Oracle WebLogic Serverロールおよびポリシーを使用したリソースの保護』のJava Messaging Service (JMS)リソースに関する項を参照してください。

ワイヤー・データの保護

アプリケーションがワイヤー上に受け渡されるJMSデータを保護する必要があるとき、ネットワークがSSLを使用するように構成します。『Oracle WebLogic Serverの保護』のSSLの構成に関する項を参照してください。

トランザクションについて

WebLogic Server JTAトランザクションの伝播は、スレッド・ベースで実行されます。トランザクションを起動するスレッドは、トランザクションをコミットまたはロールバックするスレッドにする必要があります。WebLogic JMS宛先上でsendまたはreceive操作を実行するとき、WebLogic JTAトランザクションが現在のスレッド上に存在する場合、JMSリソースはWebLogicトランザクション・マネージャに自動的に登録されるため、独自に登録を実行する必要はありません。

WebLogic JMSリソースが外部またはサードパーティのトランザクションに関与する必要があるとき、またはWebLogic以外の宛先がトランザクションに関与する必要があるとき、明示的に「手動」登録を実行するだけで済みます。外部トランザクション・マネージャ(TM)への登録は、WebLogic JMSスタンドアロン・クライアントでは直接サポートされていません。EJBおよびサーブレットのリソース参照を使用すると、WebLogic以外のJMSベンダーをWebLogic TMに自動的に登録できます。

アプリケーションは、JMS操作がグローバルXAトランザクションに参加する必要がある場合、処理対象セッションを使用しない必要があります。グローバル・トランザクションではXAベースの接続ファクトリを使用する必要があり、一方のローカル・トランザクションでは、XAベースでないJMS接続ファクトリが使用されます。

共通分散キュー・コンシューマ用の方針

コンシューマ・アプリケーションは、WebLogic Serverの同じJVMで実行する場合とそうではない場合があります。これらは、それぞれサーバー側コンシューマおよびスタンドアロン・コンシューマと呼ばれます。

JMS UDQコンシューマがWebLogic Serverまたはクラスタにデプロイされる場合、アプリケーションはUDQと同じクラスタ/サーバー、または別のクラスタで実行できます。これら2つの異なるアプリケーション構成を、それぞれローカル・ケースおよびリモート・ケースと言います。

注意:
レプリケートされた分散トピックおよびパーティション化された分散トピックを使用する拡張メッセージ分散モードを実装するためにMDBを使用することをお薦めします。MDBを使用する拡張パブリッシュ/サブスクライブ・アプリケーション設計の詳細は、『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』の拡張パブリッシュ/サブスクライブ・アプリケーションの開発および分散トピックを使用したMDBの構成とデプロイに関する項を参照してください。

なんらかの理由によりアプリケーション・アーキテクチャでMDBを使用できないアプリケーションの場合、次のガイドラインに従ってください。

- 一般的な戦略

- ローカル・サーバー・コンシューマのベスト・プラクティス

一般的な戦略

UDQに送信されるすべてのメッセージをアプリケーションで受信するには、アプリケーションがメンバーJNDI名を使用してUDQのメンバーごとに1つのコンシューマを作成する必要があります。このためには、アプリケーションがドメインのトポロジとUDQ構成を把握する必要があります。この場合、JMSDestinationAvailabilityHelperが役立ちます。

一般的な戦略では、特定のアプリケーションの各デプロイメント・インスタンスはJMSDestinationAvailabilityHelperに登録する必要があります。リスナーはメンバーの可用性に関する通知を受け取ります。

- onDestinationsAvailable()通知を受け取ると、アプリケーションは使用可能なすべてのメンバーのDestinationDetailインスタンスのリストを取得します。その後、リストのメンバーごとにメンバーのJNDI名を使用して1つ以上のコンシューマ・インスタンスを作成する必要があります。リモート・コンシューマの場合、アプリケーションの各インスタンスは、UDQのメンバーごとにコンシューマを作成する必要があります。ローカル・コンシューマの場合、ローカルUDQメンバーでのみコンシューマを作成します。詳細は、「ローカル・サーバー・コンシューマのベスト・プラクティス」を参照してください。

- onDestinationsUnavailable()通知を受け取ると、アプリケーションは、最後の通知以降に使用不可になるすべての宛先のDestinationDetailインスタンスのリストを取得します。その後、リストのメンバー宛先ごとに、メンバー宛先に対して以前に作成されたコンシューマを探し、そのコンシューマを閉じます。

ローカル・サーバー・コンシューマのベスト・プラクティス

アプリケーションがJMS分散宛先と同じクラスタにデプロイされる場合、可能なかぎり、UDQをホストする同じセットのサーバーにアプリケーションをデプロイする必要があります。この構成のベスト・プラクティスとして、アプリケーションはローカル・メンバーからのメッセージのみを受け取り、DestinationDetail isLocalWLSCluster()呼出しとisLocalWLSServer()呼出しを使用してローカル・メンバーを決定できます。この方法では、すべてのメッセージがローカルになり(ネットワーク呼出しでメッセージが転送されない)、すべてのメンバーがコンシューマで処理されるため、パフォーマンスが向上します。

一部の使用事例では、バランスの取れていないキューの負荷に関して、ローカル・サーバーの最適化ネットワークを節約するよりも、クラスタのすべてのJVM間でメッセージ処理を分散するメリットの方が上回ります。これは特に、メッセージのバックログがクラスタ全体で不規則に生じ、メッセージ処理に費用がかかる場合に関連します。このような使用事例では、リモート・コンシューマに対して一般的な戦略モデルを支持して最適化を回避してください。

共通分散トピックに関するサブスクライバ用の方針

注意:
レプリケートされた分散トピックおよびパーティション化された分散トピックを使用する拡張メッセージ分散モードを実装するためにMDBを使用することをお薦めします。MDBを使用する拡張パブリッシュ/サブスクライブ・アプリケーション設計の詳細は、『Oracle WebLogic ServerメッセージドリブンBeanのプログラミング』の拡張パブリッシュ/サブスクライブ・アプリケーションの開発および分散トピックを使用したMDBの構成とデプロイに関する項を参照してください。

UDTからメッセージを処理するすべてのクラスタ・アプリケーションおよび分散アプリケーションの場合、次の設定と組み合せて10.3.4以降のトピックを使用することをお薦めします。

- クライアントIDポリシーをUnrestrictedに設定します。『Oracle WebLogic Server JMSの構成と管理』の無制限ClientIDの構成に関する項を参照してください。

- サブスクリプション共有ポリシーをSHARABLEに設定します。『Oracle WebLogic Server JMSの構成と管理』の共有サブスクリプションの構成に関する項を参照してください。

- JMSDestinationAvailabilityHelper APIを使用して、メンバー可用性通知を取得します

- 常にメンバー宛先上でサブスクライバを作成します。

WebLogic JMSには2種類の共通分散トピックがあります。

- レプリケートされた分散トピック(RDT)には、メンバー間の転送機能があります。その結果、RDTの各メンバーはRDTに送信されるすべてのメッセージのコピーを持ちます。

- パーティション化された分散トピック(PDT)には、メンバー間の転送機能がありません。その結果、PDTの各メンバーは特定のメンバーに送信されたすべてのメッセージの独自のコピーを持ちます。これは、WebLogic Server 10.3.4.0で導入された新しいタイプのDTです。『Oracle WebLogic Server JMSの構成と管理』のパーティション化された分散トピックの構成に関する項を参照してください。

次の項では、RDTおよびPDT使用時の構成要件とプログラミング・パターンを説明します。

- インスタンスごとに1つのコピー

- アプリケーションごとに1つのコピー

インスタンスごとに1つのコピー

「インスタンスごとに1つのコピー」のパターンは、各インスタンスがトピックにパブリッシュされる各メッセージのコピーを取得することを保証します。たとえば、各インスタンスがJVMの場合、このパターンは各JVMがソース・トピックに送信された各メッセージのコピーを取得することを保証します。次の項では、「インスタンスごとに1つのコピー」に基づいた設計パターンの開発について説明します。

- 「インスタンスごとに1つのコピー」の一般的パターン設計方針

- 「インスタンスごとに1つのコピー」を使用したローカル・サーバー・コンシューマ向けベスト・プラクティス

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

分散アプリケーション/コンテナのインスタンスが、「インスタンスごとに1つのコピー」方式でDTに送信されるメッセージを受信するためには、各インスタンスが次を実行する必要があります。

1. すべての接続によって共有される基本のClientIDと、すべての恒久サブスクライバによって共有される恒久サブスクリプション名を選択します。サブスクリプション名は、使用するアプリケーション・インスタンスを一意に識別します。たとえば、各インスタンスが異なる名前のWebLogic Server JVM上で実行される場合、各インスタンスのサブスクリプション名はWebLogic Server名に基づく可能性があります。

2. JMS接続およびセッションを標準JMS仕様に従って作成します。接続のClientIDは、当該インスタンスに対して一意の識別子によって付加される基本のClientIDに設定する必要があります。たとえば、アプリケーションまたはコンテナが実行中のWebLogic Server名またはサード・パーティのアプリケーション・サーバーを使用します。ClientIDPolicyをUnrestrictedに設定する必要があります。

3. SubscriptionSharingPolicyをSharableに設定します。

4. JNDI名またはDTを指定し、メンバーシップ可用性通知のJMSDestinationAvailabilityHelperに登録します。

5. 例外リスナーを設定します。

6. onDestinationsAvailable()通知の受信時に、リスト中の新しく利用可能になった各宛先上でサブスクライバを作成します。DTがレプリケートされたDTの場合、サブスクライバはNOT JMS_WL_DDForwardedセレクタまたは(NOT JMS_WL_DDForwarded) AND接頭辞を既存アプリケーションが指定したセレクタに使用する必要があります。

7. onDestinationsUnavailable()通知の受信時に、対応するconsumer()を終了します。

「インスタンスごとに1つのコピー」を使用したローカル・サーバー・コンシューマ向けベスト・プラクティス

アプリケーションがUDTと同じクラスタにデプロイされる場合、可能なかぎり、UDTをホストする同じセットのサーバーにアプリケーションをデプロイする必要があります。この構成に従い、すべてのローカル・メンバー上でのみコンシューマを作成する点を除き、アプリケーションはインスタンスごとに1つのコピー用の一般パターン・デザイン戦略に関する項で説明されている手順と同じ手順に従う必要があります。JMSDestinationAvailabilityHelper.DestinationDetail.isLocalWLSServer()呼出しを使用して、メンバーがローカルかどうかを判定できます。

アプリケーションごとに1つのコピー

「アプリケーションごとに1つのコピー」のパターンは、アプリケーションが複数のJVM全体でクラスタ化されている場合でも、アプリケーションがトピックに送信される各メッセージのコピーを1つ受信することを保証します。たとえば、メッセージ「A」、「B」、および「C」がトピックに送信される場合、アプリケーション・インスタンスごとに1つのコピーを取得するかわりに、メッセージはアプリケーションによって1回処理されます。

次の項では、「アプリケーションごとに1つのコピー」に基づいた設計パターンの開発について説明します。

- 「アプリケーションごとに1つのコピー」の一般的パターン設計方針

- 「アプリケーションごとに1つのコピー」を使用したローカル・サーバー・コンシューマ向けベスト・プラクティス

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

分散アプリケーション/コンテナのインスタンスが、「アプリケーションごとに1つのコピー」方式でDTに送信されるメッセージを受信するためには、各インスタンスが次を実行する必要があります。

1. すべての接続の基本のClientIDと、すべての恒久サブスクライバの恒久サブスクリプション名を選択します。サブスクリプション名は、使用するアプリケーション・インスタンスを一意に識別します。たとえば、各インスタンスが異なる名前のWebLogic Server JVM上で実行される場合、各インスタンスのサブスクリプション名はWebLogic Server名に基づく可能性があります。

2. JMS接続およびセッションを標準JMS仕様に従って作成します。接続のClientIDを基本のClientIDに設定する必要があります。ClientIDPolicyをUnrestrictedに設定する必要があります。

3. SubscriptionSharingPolicyをSharableに設定します。

4. JNDI名またはDTを指定し、メンバーシップ可用性通知のJMSDestinationAvailabilityHelperに登録します。

5. 例外リスナーを設定します。

6. onDestinationsAvailable()通知の受信時に、リスト中の新しく利用可能になった各宛先上でサブスクライバを作成します。DTがレプリケートされたDTの場合、サブスクライバはNOT JMS_WL_DDForwardedセレクタまたは(NOT JMS_WL_DDForwarded) AND接頭辞を既存アプリケーションが指定したセレクタに使用する必要があります。

「アプリケーションごとに1つのコピー」を使用したローカル・サーバー・コンシューマ向けベスト・プラクティス

アプリケーションがUDTと同じクラスタにデプロイされる場合、可能なかぎり、UDTをホストする同じセットのサーバーにアプリケーションをデプロイする必要があります。この構成に従い、すべてのローカル・メンバー上でのみコンシューマを作成する点を除き、アプリケーションはアプリケーションごとに1つのコピー用の一般パターン・デザイン戦略に関する項で説明されている手順と同じ手順に従う必要があります。JMSDestinationAvailabilityHelper.DestinationDetail.isLocalWLSServer()呼出しを使用して、メンバーがローカルかどうかを判定できます。

Copyright © 2007, 2011, Oracle and/or its affiliates. All rights reserved.