2016年2月8日

[JavaScript, Database] Node-oracledb: Avoiding "ORA-01000: maximum open cursors exceeded"

原文はこちら。
https://blogs.oracle.com/opal/entry/node_oracledb_avoiding_ora_01000

Nodeを始めた開発者は、もっとも予期しないタイミングでメソッドが呼び出されるように見えるという、異なるJavaScriptのプログラミングスタイルに直面する羽目になるでしょう。最初のnode-oracledbでハックするフェーズにいる間に、
ORA-01000(maximum open cursors exceeded / 最大オープン・カーソル数を超えました
というエラーに出くわすことがあるでしょう。カーソルとは「解析済みSQL分とその他の処理情報を保持するセッション固有のプライベートSQL領域へのハンドル」です。

ORA-01000に出くわしたときに実施すべきことをまとめました。
  • 一度に大量の不完全に処理されたステートメントをオープンしない
    • 接続をリリースする前にResultSetをクローズする
    • PL/SQLブロック内でdbms_sql.open_cursor()を使ってカーソルをオープンする場合、REF CURSORSをnode-oracledbへ返す場合以外は、PL/SQLブロックから返る前にクローズする。(将来のnode-oracledbバージョンでOracle Database 12cのImplicit Result Setをサポートする場合、これらのカーソルもまたPL/SQLブロック内で閉じてはいけない)
    • アプリケーションが想定通りの順番で接続とステートメントを処理していることを確認する
  • 適切なステートメントキャッシュサイズ(Statement Cache size)を選択する。node-oracledbには接続ごとのステートメントキャッシュがある。node-oracledbが内部でステートメントをリリースすると、当該接続のステートメントキャッシュに入れられるが、ステートメントの再実行を非常に効率的にするため、カーソルは引き続きオープンしたままである。
    キャッシュサイズはstmtCacheSizeという属性で設定することができる。
    stmtCacheSize
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#propdbstmtcachesize
    適切なステートメントキャッシュサイズはステートメントの局所性に関する知識とアプリケーションで利用可能なリソースに依存する。ステートメントを再実行する場合、実行されていればキャッシュにステートメントが残っている。何個のステートメントをキャッシュに保持したいか、ステートメントを再実行しないとか、キャッシュにないというまれなケースでは、キャッシュを無効にして管理のオーバヘッドを排除することができる。
    誤ったステートメントキャッシュサイズを設定すると、アプリケーションの効率が低下する。幸いにしてOracle 12.1では、oraaccess.xmlファイルを使い、キャッシュを自動的にチューニングすることができる。
    External Configuration
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#oraaccess
    node-oracledbのステートメントキャッシュに関する詳細情報は以下のリンクに記載がある。
    Statement Caching
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#stmtcache
  • バインド変数を利用することを忘れないこと。使わない場合、ステートメントの各バリアントが独自のステートメントキャッシュエントリとカーソルを持つ。適切なバインディングを使えば、一個のエントリとカーソルだけですむ。
  • 適切にデータベースのopen_cursorsパラメータを設定する。このパラメータは各セッション(つまり、node-oracleの各接続)が利用可能なカーソルの最大個数を指定するもので、接続数がこの値を上回ると、ORA-01000がスローされる。以下のドキュメントにopen_cursorsの記載がある。
    Oracle® Databaseリファレンス 12cリリース1 (12.1)
    http://docs.oracle.com/cd/E57425_01/121/REFRN/GUID-FAFD1247-06E5-4E64-917F-AEBD4703CF40.htm
    Oracle® Database Reference 12c Release 1 (12.1)
    http://docs.oracle.com/database/121/REFRN/GUID-FAFD1247-06E5-4E64-917F-AEBD4703CF40.htm
    接続のステートメント・キャッシュ内のエントリごとのカーソルと一緒に、接続が現在実行している新しいステートメント、もしくはリリースされていないResultSetもまたカーソルを消費する(どちらの状況では、まだキャッシュされていない)。任意の接続が持つオープンされたカーソルの個数の最大値を収容できるよう、OPEN_CURSORSは十分に大きな数値になっていることを確認すること。必要な上限値は、stmtCacheSize + 接続中のステートメントの最大実行回数である。
    これは、すべての接続単位であることを忘れてはいけない。ステートメントが内部的にリリースされた場合も、キャッシュ管理が行われる。接続の大部分がOPEN_CURSORSで定義した個数よりも少ないカーソルを使用できるが、一つの接続でリミットに達して、新規のステートメントを実行しようとすると、その接続でORA-01000を取得することになる。

[WLS, Java] ZDT Rollouts and Singletons

原文はこちら。
https://blogs.oracle.com/WebLogicServer/entry/zdt_rollouts_and_singletons

WebLogic Serverは、エンタープライズグレードのアプリケーションを容易に構築するため、メッセージング、トランザクション、その他のシステムサービスを提供しています。通常、サービスは、クラスタ化またはシングルトンのいずれかです。クラスタ化されたサービスは、クラスタ内の各サーバーにデプロイされ、拡張されたスケーラビリティと信頼性を提供します。あるクラスタのメンバー・サーバのセッション状態は、クラスタ内の別のサーバーに複製されます。対照的に、シングルトンサービスは、任意の時点でクラスタ内の1台のサーバだけで実行され、特定のサービス品質(QoS)を提供しますが、最も重要なのは、データの一貫性を維持するためです。シングルトンサービスは、JMS関連のサービスや、JTA関連のサービスの場合があります(もちろん、ユーザー定義サービスの場合もあります)。高可用性構成(HA)環境では、すべてのサービスが起動し、パッチのアップグレード中にあっても実行されていることが重要です。

WebLogic Serverのこの新しいZero Downtime Patching (ZDT patchingとしても知られています)機能は、完全に自動化されたローリングアップグレードソリューションで。デプロイされたアプリケーションをアップグレードしながらも当該アプリケーションが機能し続け、エンドユーザーにとってはアップグレードプロセスの間も利用できるようにします。
Zero Downtime Patching Released!
https://blogs.oracle.com/WebLogicServer/entry/zero_downtime_patching_released
http://orablogs-jp.blogspot.jp/2015/11/zero-downtime-patching-released.html 
ZDT patchingはOracle_Home、Java_Homeのロールアウトやアプリケーションのアップデートもサポートします。ZDTに関する詳細は、以下のエントリをご覧になるか、ドキュメントをご覧ください。
ZDT Technical Topic: How are Those Sessions Kept Alive Anyway?
https://blogs.oracle.com/WebLogicServer/tags/zdt
http://orablogs-jp.blogspot.jp/2016/01/zdt-technical-topic-how-are-those.html 
Oracle® Fusion Middleware Administering Zero Downtime Patching Workflows 12c (12.2.1)
Using OPatchAuto to Initiate, Revert, and Resume Rollouts
http://docs.oracle.com/middleware/1221/wls/WLZDT/configuring_patching.htm#WLZDT166
ZDTロールアウト時は、サーバーはローリング方式で再起動されます。サーバを落とすとシングルトンサービスも落とすことになるので、結果としてサービスの中断に至り、サーバが再起動されるまでサービスが利用できなくなるでしょう。実際のダウンタイムはサーバの立ち上げ時間とデプロイされているアプリケーションの種類によって変わります。このため、シングルトンサービスがクラスタにある依存アプリケーションに対する単一障害点とならないようにするため、ZDTロールアウトプロセスが自動的に移行を実行します。

ZDTロールアウトがシングルトンを取り扱う方法にはいくつかハイライトがあります。
  • すべての種類のロールアウトに適用できる(rolloutOracleHome、rolloutJavaHome、rollingRestart、rolloutUpdateなど)
  • ロールアウト中にきめ細かくサービス移行を制御するためにJSONファイルベースの移行オプションを使うことができる(WLSTまたはコンソールで指定可能)
  • サービス移行(JMSやJTA)だけでなく、サーバ移行(WSM)もサポート
  • 必要に応じて自動フェイルバック

Terms, Acronyms and Abbreviations

用語 意味
シングルトン(Singletons) クラスタの1個のサーバでのみホストされるサービス
移行可能なターゲット (MT) まとめて移行すべきサービスをグループ化する方法を提供する特別なターゲット。これには当該タイミングでアクティブなただ1個のサーバと移行対象候補のサーバのリストが含まれる。
ソース(移行元)サーバ サービス移行元のサーバインスタンス
移行先サーバ サービス移行先のサーバインスタンス
自動サービス移行 (ASM) 影響を受けたサブシステムのサービスをあるサーバインスタンスから別の実行中のサーバインスタンスへ移動するプロセス
サーバ移行 (WSM) ある物理マシンから別の物理マシンへサーバインスタンス全体を移動するプロセス
フェールバック(切り戻し) フェールバックは、サービスを元のホストサーバもしくは「ホーム」サーバへ移転するという意味。

Assumptions

ZDTロールアウトの間、サーバを正規の手順でシャットダウンしてから立ち上げ直します。ZDTロールアウトを開始するにあたり、管理者は管理対象サーバの再起動による影響を十分に認識する必要があります。任意のアプリケーションはサービス移行が構成されている、いないに関わらず、再起動に対して寛容であったりなかったりする可能性があります。
  • 非永続状態を持っている可能性がある
  • ランタイムクライアントの例外に対して寛容であったりなかったりする可能性がある
  • 再起動に要する時間が影響を及ぼすことがある
サーバが正常にシャットダウンされた場合、クライアント接続は、クライアントは閉じられるため、結果的にクライアントは例外を取得します。JMSサーバは、ロードバランシングとJMSメッセージのルーティングの決定のための候補リストから削除されます。ほとんどの場合、このようなクライアントの例外は一時的なもので、再試行すると異なるJMSサーバ、もしくは移行後の元のJMSサーバへリダイレクトされます。しかし、例外の中には一時的ではないものがあり、特定のJMSサーバインスタンスが復旧するまで、各クライアントの再試行に対し例外をスローし続けることがあります。サーバーがシャットダウン中にいくつかのレベルの静止を行いますが、これでJMSクライアントまたは他の場所でのすべてのエラーを防ぐことはできません。

JTAに関しては、サーバが正常にシャットダウンされた場合、アプリケーションは、その特定のサーバーの任意の新しいトランザクションリクエストを生成しません。 EJB/ RMIパスでは、クラスタに対応するスタブがサーバー接続障害を検出し、セカンダリサーバにリクエストをリダイレクトします。アプリケーションはトランザクション中の例外を処理するように設計されている前提です。

サーバ移行(WSM)を環境で構成している場合、サーバインスタンス全体を新しいハードウェア上で起動する必要があるため、通常はサービスが利用可能になるまで(サービス移行と比較して)より長い時間を必要とすることに注意する必要があります。

注意:一般に、サーバ全体の移行は、その相対的にシンプルであるが故に基本的な用途では好ましいのですが、フェイルオーバーに要する時間がより短く、かつサービス移行での高度な制御を所望されている場合、自動サービス移行は魅力的でしょう。

JMS

WebLogic JMSサブシステムは堅牢で高パフォーマンスであり、エンタープライズアプリケーションを構築するための他のAPIと接続して使われることが多々あります。アプリケーションがスムーズに機能するためにはアプリケーションの設計(フォールトトレランス、特定のパターンや機能の利用)が大いに関わっており、管理サーバでのJMSサブシステムの調整方法にも関わっています。

WebLogic JMSでは、メッセージは、宛先のホストJMSサーバが実行されている場合にのみ使用可能です。メッセージが中央の永続ストアにある場合、メッセージにアクセスできる唯一のJMSサーバは、元々メッセージが保存されているサーバです。HA(高可用性構成)は通常、次のいずれかまたは全てのいずれかを使用して実現しています。
  • 分散送り先:分散送り先のキューおよびトピックメンバーは、通常クラスター内の複数のサーバに分散されており、各メンバーは別々のJMSサーバに属しています。分散送り先を使うアプリケーションは、単純な送り先を使用するアプリケーションよりも可用性が増していますが、それはWebLogic JMSが、クラスタ内の分散送り先に含まれる宛先のためのロードバランシングとフェイルオーバーを提供するためです。
  • ストアアンドフォワード:JMSモジュールは、SAFサービスを利用して、確実にリモート・キューまたはトピックにメッセージを送信するためにローカルJMSメッセージプロデューサを有効にします。メッセージ送信のタイミングで(ネットワークの問題やシステムの障害で)宛先が利用できない場合、メッセージはローカルサーバインスタンスに保存され、宛先が利用可能になったら、リモートの宛先に転送されます。
  • HAサーバ/サービス:JMSサーバを自動的に再起動したり、サーバー全体の移行やサービスの自動移行のいずれかを使用して移行したりすることができます。

JTA

高可用性のために設計された本番環境はほとんどの場合JTAサービス(だけでなく他のサービスも)が単一障害点(Single Point of Failure)にならないようになっています。WebLogic虎ザクションマネージャは最小限の人手による介入でシステム障害から回復するように設計されています。トランザクションマネージャは、複数のクラッシュや回復中のクラッシュがあった後でも、リソースマネージャがコミットやロールバックでPrepareしたトランザクションブランチを解決するためにあらゆる努力をします。また、不完全なトランザクションに関するすべてのトランザクション・ログの記録を解析し、それらを完了することによって、システムの起動時にトランザクションを回復しようとします。しかし、ZDTロールアウトなどのメンテナンスの類いの操作の準備のために、JTAサービスを移行するように構成することができます。実行中のトランザクションが基礎となるリソースのロックを保持することができるので、JTAの移行を必要とします。トランザクションマネージャがこれらのトランザクションを回復するために使用できない場合は、保留中のトランザクションがコミット/ロールバックを使用して解決されず、新しいトランザクションにエラーが発生し、アプリケーションが正しく機能することが難しい場合に限り、リソースがこれらのロックを保持することができます。

More on Service Migrations

WebLogic Serverにおけるサービスレベルの移行は、あるサーバインスタンスから固定サービスをクラスタ内で利用可能な別のサーバーインスタンスに移動するプロセスです。
サービス移行は、クラスタ内の1個の物理サーバ上でのみホストされているサービスのグループとして機能する、論理的に移行可能なターゲットが制御します。特定の固定サービスをターゲットとする場合は、サーバーまたはクラスタの代わりに移行可能な対象を選択することができます。移行フレームワークは、ターゲットの設定および移行のためのツールとインフラストラクチャを提供します。自動サービス移行の場合には、移行可能なターゲットがホストするサービスの状態を監視するためのWebLogic Serverの状態監視サブシステムを活用します。
次表は、さまざまな移行オプションをまとめたものです。
ポリシータイプ 説明
Manual Only (default) このターゲットへの自動サービス移行は無効
Failure Recovery このターゲットにデプロイされた固定サービスは
  • まず優先サーバ上で起動
  • クラスタマスタが優先サーバに障害が発生したと判断した場合にのみ移行
Exactly Once このターゲットにデプロイされた固定サービスは
  • まず優先サーバが利用できない場合に候補サーバで起動
  • ホストサーバに障害が発生したり、正常にシャットダウンされた場合に移行

ZDT Migration Strategy and Options

移行サブシステムは“exactly-once”タイプのサービスを自動的に取り扱うため、ZDTロールアウトでは考慮する必要はありません。主として考慮しなければならないのは、failure-recoveryタイプのサービスです。これらのサービスはサーバが正常終了すれば移行されません。再起動の時間間隔はまちまちなので、これらのサービスを移行して、エンドユーザーに影響が及ばないようにする必要があります。

同様に、ユーザーがサービスを手動で移行するよう設定した場合、そのようなサービスはロールアウト時に、管理者に成り代わって自動的に移行されます。 ZDTロールアウトは、JMSおよびJTAサービスの移行の両方を扱うことができます。

警告
  1. トランザクションマネージャは他の固定サービスのように移行ターゲットに割り当てられません。JTA ASM(自動サービス移行)はサーバ毎の設定です。これはJMSのようなサービスと対比すると、トランザクションマネージャが直接別の固定リソースに依存しないためです。
  2. ユーザー定義のシングルトンサービスの場合、自動的に”exactly-once”に構成されるため、ZDTロールアウトは特定のアクションを実行する必要はありません。

管理者は、ロールアウトコマンドにオプションとして移行プロパティ・ファイルを渡すことで、サーバ単位での正確な移行アクションを指定することができます。移行プロパティファイルで指定された移行オプションは、システムで構成されているものに対して検証されます。プロパティファイルに従ってダウンタイムを軽減するために必要とされる移行を呼び出します。最適化として、パッチ適用済みサーバと未適用のサーバ間での不要な移行を防ぐため、ワークフローがサーバ全体でロールアウトをする順番を生成します。
サーバをサーバ全体の移行(WSM)をするよう構成している場合、ZDTロールアウトはWSMもサポートします。

下表はすべての移行オプションのリストです。
移行タイプ 説明
jms 現在ホストしているサーバ上で実行中のすべてのJMS関連のサービスを宛先のサーバに移行する
jta JTAサービスを現在ホストしているサーバから宛先のサーバに移行する
all 現在ホストしているサーバのJMSサービスとJTAサービスの両方を宛先のサーバに移行する
server サーバインスタンス全体を宛先のマシンに移行する
none 現在のサーバで実行中のシングルトンサービスのための移行は実施しない

これらの移行オプションはWLSTのmigrateコマンドオプションと非常に似ていることがわかると思います。

Sample Migration Sequence

下図は、サービス移行の典型的なロールアウト・シーケンスです。ここで、JMSおよびJTAシングルトンサービスは、各サーバー用に構成済みの2種類の移行ターゲットとして表現されています。永続ストアおよびTLOGは、クラスタ内のすべてのサーバーからアクセスできる必要があります。管理者は、クラスタ内のサーバー間での移行方法を指定して管理します。次章では、ロールアウト時の移行をきめ細かく管理・制御するための設定を説明します。


ZDT Migration Properties

ロールアウトでの移行方法はロールアウトのコマンドにオプションを渡す移行プロパティファイルに指定します。移行プロパティ亜フィルはJSONファイルで、4個の主要なプロパティから構成されています。
移行プロパティ 説明
source 移行元サーバ(名)。つまり現在シングルトンをホストしているサーバ
destination シングルトンサービスの移行先サーバ(名)。サーバ移行の場合はマシン名を指定
migrationType 前章に記載の通り、"jms"、"jta"、"all"、"server"、"none"を指定
failback サービスを元々ホストしているサーバに自動フェールバックする必要があるか否かを指定
以下は移行プロパティファイルの例です。
{"migrations":[    
# Migrate all JMS migratable targets on server1 to server2. Perform a fail back
# if the operation fails.
    {
    "source":"server1",                
    "destination":"server2",
    "migrationType":"jms",
    "failback":"true"
    },

# Migrate only JTA services from server1 to server3. Note that JTA migration
# does not support the failback option, as it is not needed.
    {
    "source":"server1",
    "destination":"server3",
    "migrationType":"jta"
    },

# Disable all migrations from server2
    {
    "source":"server2",
    "migrationType":"none" 
    },
    {

# Migrate all services (for example, JTA and JMS) from server 3 to server1 with
# no failback
    "source":"server3",
    "destination":"server1",
    "migrationType":"all"
    },
 
# Use Whole Server Migration to migrate server4 to the node named machine 5 with
# no failback
    {
    "source":"server4",
    "destination":"machine5",
    "migrationType":"server"
    }
    ]}
  • migrationTypeが"None"の場合、このサーバで実行しているサービスは移行されません。フェールバックも不要であることを意味します。
  • シングルトンサービスが見つかり、管理者が移行プロパティファイルに記載しなかった場合、rollout コマンドは失敗します。移行が不要な場合、管理者は明示的にサーバの各々に対し、移行プロパティ(つまり、migrationType=”None”)と明示する必要があります。
  • migrationType が"server"の場合、宛先はノードマネージャのマシン名を指定する必要があります。そうすると、そのサーバインスタンスに対してWSM(サーバ全体移行)が呼び出されます。
  • failbackのデフォルト値はfalseです(オプションを指定しない場合、フェールバックしません)。
  • サーバに対し、ASMもしくはWSMを適用できますが、両方は適用できません。
  • JTAサブシステムはJTAインスタンスの自動フェールバックをサポートしていますので、failback はJTAサービスのオプションでは使えません。

    ロールアウト前に事前要件チェックの一環で 上記の検証チェックの各々が発生します。

ZDT Rollout Examples

以下は移行プロパティオプションの利用例です。
サンプルのmigrationProperties.json ファイルは以下のようです。
{"migrations":[ {
"source":"m1",
"destination":"m2",
"migrationType":"jms",
"failback":"true"
} ]}

Passing migration options to rolloutOracleHome

rolloutOracleHome('myDomain', '/pathto/patchedOracleHome.jar', '/pathto/unpatchedOracleHomeBackup/', options='migrationProperties=/pathto/migrationProperties.json')

Passing migration options to rolloutApplications

rolloutApplications('myDomain', applicationProperties='/pathto/applicationProperties.json', options='migrationProperties=/pathto/migrationProperties.json')

Passing migration options to rolloutJavaHome

rolloutJavaHome('myDomain', javaHome='/pathto/JavaHome1.8.0_60', options='migrationProperties=/pathto/migrationProperties.json')

Passing migration options to rolloutUpdate

rolloutUpdate('myDomain', '/pathto/patchedOracleHome.jar', '/pathto/unpatchedOracleHomeBackup/', false, options='migrationProperties=/pathto/migrationProperties.json')

Passing migration options to rollingRestart

rollingRestart('myDomain', options='migrationProperties=/pathto/migrationProperties.json')

References

2016年2月6日

[Mobile] MAF 2.2.2 release available now

原文はこちら。
https://blogs.oracle.com/mobile/entry/maf_2_2_2_release

MAF 2.2.1のリリースからおよそ6週間後、最新パッチであるMAF 2.2.2がダウンロードできるようになりました。このリリースにはいくつかの重要なバグ修正やiOSの64bitデバイス向けに最適化された新しいJVMが含まれています。この新しいJVMでほとんどのiOSデバイス上でみなさんのアプリケーションのパフォーマンスがすばらしく改善されることでしょう。そのため、皆様にこのパッチへアップグレードすることを強くお勧めします。このリリースにおける主要ポイントをまとめてみました。
  1. すでにMAF 2.2.1をお使いであれば、このパッチを当てるのは簡単です。2.2.1からアップデートするのであれば移行作業は必要ありませんので、新リリースのMAFで再ビルドすれば問題なく動作するでしょう。
  2. MAF 2.2.0およびそれ以前のリリースから移行する場合、以下のURLの移行手順に沿って移行してください。
    Oracle Mobile Application Framework 2.2.2 Migration Notes
    http://www.oracle.com/technetwork/developer-tools/maf/documentation/maf222migration-2881517.html
  3. このリリースでの不具合修正やその他の重要なリリースノートは以下のリンクからどうぞ。
    Oracle Mobile Application Framework 2.2.2 Release Notes
    http://www.oracle.com/technetwork/developer-tools/maf/documentation/maf222relnotes-2879088.html

2016年2月4日

[WLS, Java] Dynamic Debug Patches in WebLogic Server 12.2.1

原文はこちら。
https://blogs.oracle.com/WebLogicServer/entry/dynamic_debug_patches_in_weblogic

Introduction

好むと好まざるとに関わらず、完全なソフトウェアはありません。開発者の最善の努力にもかかわらずバグが発生しますし、さらに悪いことに、多くの状況で、予期しない形で現れます。また、あるケースでは再現することが難しく、断続的に発生することがあります。このような場合では、製品が十分に根本的な原因を明らかにするための機能が備わっていないと、問題の本質を理解するための情報が不足することが多々あります。お客様の本番環境への直接アクセスは通常は選択できず、根本的な原因をより理解するために、デバッグ用パッチを作成し、そのパッチを適用したアプリケーションを実行して、願わくばより多くの洞察が得られることを期待するわけですが、これはトライ&エラー方式で、本当の原因に到達するまでに何度かの繰り返し作業になる可能性があります。デバッグパッチを作成する人たち(通常はソフトウェアプロバイダのサポートや開発チームです)やアプリケーションを使うお客様はほぼ異なるグループで、別の会社に属していることが多々あります。そのため、デバッグパッチの作成、お客様へのパッチの提供、顧客環境へのパッチ適用、結果の取得・返送という繰り返し作業の各々でかなりの時間がかかる可能性があります。結果として、問題解決に時間がかかります。

加えて、このようなデバッグパッチをデプロイすることに伴う別の重要な問題が発生することがあります。Java EE環境でパッチを適用すると、サーバーおよびドメインの再起動もしくは少なくともアプリケーションの再デプロイが必要です。ミッションクリティカルな環境では、すぐにパッチ適用ができない可能性があります。サーバを再起動すると、状態が失われるため、メモリ内の重要な障害データが失われる可能性があります。また、サーバの再起動後、断続的な障害が長時間現れず、迅速な診断が困難になる場合があります。

Dynamic Debug Patches

WebLogic Server 12.2.1では、Dynamic Debug Patchesと呼ばれる新しい機能が導入されました。これは迅速な問題解決のため、診断データを取得するプロセスを簡素化することを目的としています。
Oracle® Fusion Middleware Configuring and Using the Diagnostics Framework for Oracle WebLogic Server 12c (12.2.1)
Using Debug Patches
http://docs.oracle.com/middleware/1221/wls/WLDFC/using_debug_patches.htm#WLDFC585
この機能を使用すると、デバッグパッチを動的にアクティベートできます。このときにサーバまたはクラスタの再起動や、WebLogicドメインへのアプリケーションの再デプロイは不要です。これは、JDKのインスツルメンテーション機能を利用し、ランタイムWLSTコマンドを使用して、指定されたデバッグパッチからクラスをホット・スワップします。
java.lang.instrument Interface Instrumentation
http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.htmlhttp://docs.oracle.com/javase/jp/7/api/java/lang/instrument/Instrumentation.html
WLSTコマンド(後述)を発行して、一つ以上のデバッグパッチを選択されたサーバ、クラスタ、パーティションおよびアプリケーションの範囲内でアクティベートできます。サーバの再起動やアプリケーションの再デプロイが不要なので、関連したロジスティックの障害は問題にはなりません。一例としては、アプリケーションやサービスは実行し続けるので、こうしたパッチを本番環境で有効にすることの障壁が低くなります。また、状態の損失もありません。したがって、新たにアクティベートされたデバッグパッチのインストルメントコードが新しくアクティブ化されたデバッグパッチでインストルメントコードがまずい過渡状態を明らかにし、意味のある診断情報を提供するチャンスが増えます。

Prerequisites

Dynamic Debug Patchは、デバッグログやステートメントの表示などといった追加のインストルメントコードを持つパッチ適用済みのクラスを含んだ通常のjarファイルです。通常は製品開発もしくはサポートチームがこれらのパッチjarファイルを作成し、システム運用チームが現場でのアクティベーションのために利用できるようにします。WebLogic ServerのDynamic Debug Patch機能を利用できるようにするには、システム管理者がドメイン内の特定のディレクトリにコピーする必要があります。デフォルトでは、このディレクトリは、ドメインルートの下のdebug_patchesというディレクトリですが、DebugPatchesMBeanのDebugPatchDirectory属性を再設定することで変更できます。

もう一つ、サーバの起動コマンド内で以下のオプションを使ってdebugpatch インストルメンテーション・エージェントとともにサーバを起動する必要がありますが、これはWebLogic Server 12.2.1ドメイン用に作成した起動スクリプトで自動的に追加されます。
-javaagent:${WL_HOME}/server/lib/debugpatch-agent.jar

Using Dynamic Debug Patches Feature

シンプルなアプリケーションでデバッグパッチを有効化・無効化しながら、この機能の使い方を説明します。

The Application

最小限のWebアプリケーションを使います。これは入力された整数の階乗値を計算してブラウザに表示するというものです。
FactorialServlet.java:
package example;

import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;

import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * A trivial servlet: Returns addition of two numbers.
 */
@WebServlet(value="/factorial", name="factorial-servlet")
public class FactorialServlet extends GenericServlet {

  public void service(ServletRequest request, ServletResponse response)
      throws ServletException, IOException {
    String n = request.getParameter("n");
    System.out.println("FactorialServlet called for input=" + n);
    int result = Factorial.getInstance().factorial(n);
    response.getWriter().print("factorial(" + n + ") = " + result);
  }
}
ServletはFactorialシングルトンに階乗値を計算させています。Factorialクラスは以前計算した値のMapを最適化のため保持しています。これはDynamic Debug Patchを有効化・無効化しながら、ステートフルな情報を保持していることの説明として役立つでしょう。
Factorial.java:
package example;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

class Factorial {
  private static final Factorial SINGLETON = new Factorial();
  private Map<String, Integer> map = new ConcurrentHashMap<String, Integer>();

  static Factorial getInstance() {
    return SINGLETON;
  }

  public int factorial(String n) {
    if (n == null) {
      throw new NumberFormatException("Invalid argument: " + n);
    }
    n = n.trim();
    Integer val = map.get(n);
    if (val == null) {
      int i = Integer.parseInt(n);
      if (i < 0)
        throw new NumberFormatException("Invalid argument: " + n);
      int fact = 1;
      while (i > 0) {
        fact *= i;
        i--;
      }
      val = new Integer(fact);
      map.put(n, val);
    }
    return val;
  }
}

Building and Deploying the Application

factorial.war Webアプリケーションをビルドするために、FactorialServlet.javaとFactorial.javaファイルを上述のように空のディレクトリに作成し、以下のコマンドを使ってアプリケーションwarファイルをビルドします。
mkdir -p WEB-INF/classes
javac -d WEB-INF/classes FactorialServlet.java Factorial.java
jar cvf factorial.war WEB-INF
WLSTもしくはWebLogic Server管理コンソールを使ってアプリケーションをデプロイします。
$MW_HOME/oracle_common/common/bin/wlst.sh
Initializing WebLogic Scripting Tool (WLST) ...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands
connect(username, password, adminUrl)  # e.g. connect('weblogic', 'weblogic', 't3://localhost:7001')
Connecting to t3://localhost:7001 with userid weblogic ...
Successfully connected to Admin Server "myserver" that belongs to domain "mydomain".
Warning: An insecure protocol was used to connect to the server.
To ensure on-the-wire security, the SSL port or Admin port should be used instead.
deploy('factorial', 'factorial.war', targets='myserver')
上の説明では、アプリケーションを管理サーバにデプロイしていることにご注意ください。実際の現場では別の管理対象サーバもしくはクラスタにデプロイされていることがあります。複数の管理対象サーバ全体に対してデバッグパッチを有効化・無効化する方法は後で説明します。

ビルドしたWebアプリケーションをブラウザから http://localhost:7001/factorial/factorial?n=4 のような感じで呼び出します。ブラウザに結果が表示され、サーバの標準出力ウィンドウには以下のような文字が現れるはずです。
FactorialServlet called for input=4

The Debug Patch

先ほど作成したアプリケーションはたくさんのログを出力しないので、機能がわかりづらくなっています。おそらく、そこに問題があり、このアプリケーションを実行した場合、より多くの情報が必要です。アプリケーションコードからデバッグパッチを作成し、システム管理者に提供して、実行中のサーバー/アプリケーション上でそれを有効化することができます。上記コードを変更し、追加情報を取得するため追加のprint文を入れましょう(以下のMYDEBUGが付いている行)。
Updated (version 1)  Factorial.java:
class Factorial {
  private static final Factorial SINGLETON = new Factorial();
  private Map<String, Integer> map = new ConcurrentHashMap<String, Integer>();
  static Factorial getInstance() {
    return SINGLETON;
  }
  public int factorial(String n) {
    if (n == null) {
      throw new NumberFormatException("Invalid argument: " + n);
    }
    n = n.trim();
    Integer val = map.get(n);
    if (val == null) {
      int i = Integer.parseInt(n);
      if (i < 0)
        throw new NumberFormatException("Invalid argument: " + n);
      int fact = 1;
      while (i > 0) {
        fact *= i;
        i--;
      }
      val = new Integer(fact);
      System.out.println("MYDEBUG> saving factorial(" + n + ") = " + val);
      map.put(n, val);
    } else {
      System.out.println("MYDEBUG> returning saved factorial(" + n + ") = " + val);
    }
    return val;
  }
}
デバッグパッチをビルドしますが、これはプレーンなjarファイルでありアプリケーションアーカイブとしてビルドしないことにご注意ください。また、(毀損することはないでしょうが)アプリケーション全体をコンパイルする必要はないことにご注意ください。デバッグパッチjarファイルには変更されたクラス(この場合、Factorialクラス)のみが含まれる必要があります。
mkdir patch_classes
javac -d patch_classes Factorial.java
jar cvf factorial_debug_01.jar -C patch_classes

Activating Debug Patches

現実のシナリオでは、作成者(開発者)とデバッグパッチのアクティベータ(システム管理者)が異なることがほとんどでしょう。説明のために、今回は同一人物が複数の役割を持つことにします。デバッグパッチディレクトリの場所としてデフォルト設定を利用する前提としますが、まだ存在しない場合は、<Domain_Home>の下にdebug_patchesディレクトリを作成してください。debug_patchesディレクトリにfactorial_debug_01.jarというデバッグパッチのjarファイルをコピーします。上記のようにWLSTを使用してサーバに接続します。

まず、デバッグパッチがドメインで利用可能かどうかを確認しましょう。これはlistDebugPatchesコマンドを使って実現できます。
Oracle® Fusion Middleware WLST Command Reference for WebLogic Server 12c (12.2.1)
listDebugPatches
http://docs.oracle.com/middleware/1221/wls/WLSTC/reference.htm#WLSTC3694
[ヒント]利用可能な診断コマンドを確認するには、 help('diagnostics') とコマンドを発行します。特定コマンドの情報を知るためには、help(コマンド名) を発行します。例えば、 help('activateDebugPatch') という感じです。
wls:/mydomain/serverConfig/> listDebugPatches()         
myserver:
Active Patches:
Available Patches:
    factorial_debug_01.jar
    app2.0_patch01.jar
    app2.0_patch02.jar 
factorial_debug_01.jar は新規作成されたデバッグパッチです。app2.0_patch01.jar と app2.0_patch02.jar は過去に別のアプリケーションでの問題を調査するために作成されたものでした。上記のリストはこれまでどれも有効化されなかったので「アクティブ」なパッチはありません。

では、activateDebugPatchコマンドを使ってデバッグパッチを有効化しましょう。
Oracle® Fusion Middleware WLST Command Reference for WebLogic Server 12c (12.2.1)
activateDebugPatch
http://docs.oracle.com/middleware/1221/wls/WLSTC/reference.htm#WLSTC3670
tasks=activateDebugPatch('factorial_debug_01.jar', app='factorial', target='myserver')
wls:/mydomain/serverConfig/> print tasks[0].status                                                                 
FINISHED
wls:/mydomain/serverConfig/> listDebugPatches()     
myserver:
Active Patches:
    factorial_debug_01.jar:app=factorial
Available Patches:
    factorial_debug_01.jar
    app2.0_patch01.jar
    app2.0_patch02.jar
コマンドは、起動コマンドの進行状況を監視するために使用できるタスクの配列を返します。該当する場合は、複数の管理対象サーバやクラスタをターゲットとして指定することができます。該当する各ターゲットサーバに対応して、返されたタスクの配列中にタスクがあります。コマンドを使ってサーバやミドルウェアレベルでデバッグパッチを有効化することもできます。このようなパッチを通常Oracle Supportが作成することもあるでしょう。上記の listDebugPatches() コマンドの出力結果では、factorial_debug_01.jar をアプリケーションfactorialが有効化されていることを示しています。

それではリクエストをアプリケーションに送信しましょう。
http://localhost:7001/factorial/factorial?n=4
http://localhost:7001/factorial/factorial?n=5
サーバー出力:
FactorialServlet called for input=4
MYDEBUG> returning saved factorial(4) = 24
FactorialServlet called for input=5
MYDEBUG> saving factorial(5) = 120
input=4の場合、値は以前のリクエストで計算、Mapに保存済みなので保存済みの結果を返していることに注意してください。したがって、デバッグパッチは、アプリケーション内の既存の状態を壊さずに有効化されました。input=5の場合、値は以前計算されておらず、保存されていないので、異なるデバッグメッセージが現れました。

Activating Multiple Debug Patches

必要であれば、潜在的にオーバーラップする複数のパッチを有効化することができます。オーバーラップする場合、後で有効化されるパッチが先に有効化されたパッチの効果をマスクします。具体的には、上記のケースでは、内部ループを実行しているときのfactorial()メソッドからの詳細情報が必要です。別のデバッグパッチを作成し、debug_patchesディレクトリにコピーして有効化しましょう。
Updated (version 2) Factorial.java:
class Factorial {
  private static final Factorial SINGLETON = new Factorial();
  private Map<String, Integer> map = new ConcurrentHashMap<String, Integer>();
  static Factorial getInstance() {
    return SINGLETON;
  }
  public int factorial(String n) {
    if (n == null) {
      throw new NumberFormatException("Invalid argument: " + n);
    }
    n = n.trim();
    Integer val = map.get(n);
    if (val == null) {
      int i = Integer.parseInt(n);
      if (i < 0)
        throw new NumberFormatException("Invalid argument: " + n);
      int fact = 1;
      while (i > 0) {
        System.out.println("MYDEBUG> multiplying by " + i);
        fact *= i;
        i--;
      }
      val = new Integer(fact);
      System.out.println("MYDEBUG> saving factorial(" + n + ") = " + val);
      map.put(n, val);
       } else {
      System.out.println("MYDEBUG> returning saved factorial(" + n + ") = " + val);
    }
    return val;
  }
}
factorial_debug_02.jarを作成します。
javac -d patch_classes Factorial.java
jar cvf factorial_debug_02.jar  -C patch_classes .
cp factorial_debug_02.jar $DOMAIN_DIR/debug_patches
factorial_debug_02.jarを有効化します。
wls:/mydomain/serverConfig/> listDebugPatches()     
myserver:
Active Patches:
    factorial_debug_01.jar:app=factorial
Available Patches:
    factorial_debug_01.jar
    factorial_debug_02.jar
    app2.0_patch01.jar
    app2.0_patch02.jar
wls:/mydomain/serverConfig/> tasks=activateDebugPatch('factorial_debug_01.jar', app='factorial', target='myserver')
wls:/mydomain/serverConfig/> listDebugPatches()                                                                    
myserver:
Active Patches:
    factorial_debug_01.jar:app=factorial
    factorial_debug_02.jar:app=factorial
Available Patches:
    factorial_debug_01.jar
    factorial_debug_02.jar
    servlet3.0_patch01.jar
    servlet3.0_patch02.jar
では、アプリケーションに http://localhost:7001/factorial/factorial?n=5 とか http://localhost:7001/factorial/factorial?n=6 といった具合で、いくつかリクエストを投げてみましょう。
FactorialServlet called for input=5
MYDEBUG> returning saved factorial(5) = 120
FactorialServlet called for input=6
MYDEBUG> multiplying by 6
MYDEBUG> multiplying by 5
MYDEBUG> multiplying by 4
MYDEBUG> multiplying by 3
MYDEBUG> multiplying by 2
MYDEBUG> multiplying by 1
MYDEBUG> saving factorial(6) = 720
factorial_debug_02.jarに入っているコードのおかげで追加情報が表示されていることがわかります。

Deactivating Debug Patches

もうデバッグパッチが不要であれば、deactivateDebugPatchesコマンドを使って無効化することができます。使い方はhelp('deactivateDebugPatches')でヘルプを呼び出してください。
Oracle® Fusion Middleware WLST Command Reference for WebLogic Server 12c (12.2.1)
deactivateDebugPatches
http://docs.oracle.com/middleware/1221/wls/WLSTC/reference.htm#WLSTC3678
wls:/mydomain/serverConfig/> tasks=deactivateDebugPatches('factorial_debug_02.jar', app='factorial', target='myserver')            
wls:/mydomain/serverConfig/> listDebugPatches()
myserver:
Active Patches:
    factorial_debug_01.jar:app=factorial
Available Patches:
    factorial_debug_01.jar
    factorial_debug_02.jar
    servlet3.0_patch01.jar
    servlet3.0_patch02.jar
では、 http://localhost:7001/factorial/factorial?n=2 でアプリケーションを呼び出してみましょう。以下の出力結果がサーバの標準出力画面に現れます。
FactorialServlet called for input=2
MYDEBUG> saving factorial(2) = 2
factorial_debug_01.jarとfactorial_debug_02.jarをこの順で有効化したとき、factorial_debug_02.jarのクラスがfactorial_debug_01.jarのものをマスクしていることに注意してください。factorial_debug_02.jarを無効化した後、factorial_debug_01.jarのクラスのマスクを外すと、再び有効になりました。デバッグパッチリストのカンマ区切りリストを、deactivateDebugPatchesコマンドで指定することができます。deactivateAllDebugPatches()コマンドを使用すると、該当するターゲットサーバ上のすべてのアクティブなデバッグパッチを無効にすることができます。
Oracle® Fusion Middleware WLST Command Reference for WebLogic Server 12c (12.2.1)
deactivateAllDebugPatches
http://docs.oracle.com/middleware/1221/wls/WLSTC/reference.htm#WLSTC3674

WLST Commands

Dynamic Debug Patch機能を操作するために、以下の診断WLSTコマンドが提供されています。
Oracle® Fusion Middleware WLST Command Reference for WebLogic Server 12c (12.2.1)
Diagnostics Commands
http://docs.oracle.com/middleware/1221/wls/WLSTC/reference.htm#WLSTC242
上述の通り、help(コマンド名)で当該コマンドのヘルプを表示します。

CommandDescription
activateDebugPatch特定ターゲットでデバッグパッチを有効化する
deactivateAllDebugPatches特定ターゲットからすべてのデバッグパッチを無効化する
deactivateDebugPatches特定ターゲットのデバッグパッチを無効化する
listDebugPatches特定ターゲットで有効化されているデバッグパッチ、無効化されているデバッグパッチを列挙する.
listDebugPatchTasks特定ターゲットからデバッグパッチタスクを列挙する
purgeDebugPatchTasksデバッグパッチタスクを特定ターゲットからパージする
showDebugPatchInfo特定ターゲットのデバッグパッチの詳細を表示する

Limitations

Dynamic Debug Patch機能はJDKのホットスワップ機能を使いますが、ホットスワップするクラスはオリジナルのクラスと異なる形を持つことができないという制限があります。つまり、スワップするクラスでは、コンストラクタ、メソッド、フィールド、スーパークラス、実装されたインターフェースなどを追加、削除、変更できず、メソッド本体での変更のみ許容されています。デバッグパッチは通常追加情報を収集するだけで、問題を修正しようとするものではない、ということにご注意ください。クラスの形を変更しないマイナーな変更を試すことができますが、それはこの機能の主要な目的ではありません。したがって、実際にはこれが大きな制限とは思っていません。

しかしながら、問題は、新しいデバッグコードが時として状態を維持する必要があるかもしれないということです。例えば、Mapのデータを収集し、ある閾値でダンプ出力したい、という場合があるとしましょう。形状変化に関するJDKの制限により、こうした場合に問題が発生します。Dynamic Debug Patch機能はDebugPatchHelperユーティリティクラスを提供しており、このクラスがそうした問題解決の手助けになります。後続の記事でこの内容を説明しますので、ご期待ください。

2016年2月1日

[Database, WLS] Monitoring FAN Events

原文はこちら。
https://blogs.oracle.com/WebLogicServer/entry/fanwatcher_sample_program

fanWatcherはOracle Notification Service(ONS)のFast Application Notification(FAN)イベント情報を表示するサンプルプログラムです。これらのイベントはロードバランシングとインスタンスの立ち上げ・立ち下げイベントに関する情報を提供します。この情報は自動的に中間層のWebLogic ServerのActive GridLinkやUCPが処理します。FANイベントに関する詳細は、以下のホワイトペーパーをどうぞ。
Fast Application Notification (FAN) Includes FANwatcher: A utility to subscribe to ONS and view FAN events
http://www.oracle.com/technetwork/database/options/clustering/overview/fastapplicationnotification12c-2538999.pdf
ここで説明するプログラムはこのホワイトペーパーで説明したプログラムを機能強化したもので、このプログラムを変更して、所望のイベントを監視したり、構成の問題を診断するためにつかったりすることができます。コードはこちらからダウンロードできます(拡張子を.txtから.javaへ変更してください)。

このJavaアプリケーションを実行するためには、JDKを構成し、ons.jarとojdbc.jarをクラスパスに通す必要があります。クラスパスはデータベースサーバ上で実行するか、WebLogic ServerやUCPのある中間層で実行するかで変わります。クラスパス指定時はご利用のプラットフォームにあわせた適切なパスセパレータを使うようにしてください(セミコロンはWindows、コロンはその他のプラットフォーム)

コマンドラインの一般的な形式は以下の通りです。
java fanWatcher config_type [eventtype … ]

Event Type Subscription

イベントタイプは制限されたイベントを返すためだけのサブスクライバをセットアップします。どのタイプのイベントを返すかを指定せずに実行することもできます。コマンドラインでイベント名を指定すると、プログラムはイベントに単純一致するサブスクライバを設定します。指定されたパターンが通知ヘッダのどこかにあれば、比較ステートメントはtrueと評価されます。最も基本的なパターンパッチは空文字列(nullではありません)で、この場合すべての通知に一致します。パターンをダブルクォート(必須)で括り、大文字小文字を区別しない場合、"%"を前に付けます。

イベント処理は、このサンプルに示されているよりも完全です。サブスクリプション文字列は一般に1個以上の比較ステートメントで構成されており、ORの関係を示すブール演算子 '|' もしくはANDの関係を表す '&" を使って別の比較ステートメントとそれぞれ論理的に関連しています。括弧は、グループにこれらの比較ステートメントをグループ化するために使用され、左括弧の前の '!' は括弧内の評価値を否定します。

各々の個別の比較ステートメントは二重引用符 ("") で囲む必要があり、"パターン" もしくは "名前=値" という2個の基本的な形のうち一つを取ることができます。"パターン" は通知ヘッダの単純文字列の一致であり、指定された "パターン" が通知ヘッダにあれば、比較ステートメントはtrueと評価されます。最も基本的なパターンパッチは空文字列(nullではありません)で、この場合すべての通知に一致します。

"名前 = 値" 形式は指定値に対する名前を使い、ONS通知ヘッダもしくはプロパティ名を比較し、値が一致する場合、比較ステートメントはtrueと評価されます。指定されたヘッダやプロパティ名が通知ヘッダに存在しない場合、比較ステートメントはfalseと評価されます。左ダブルクォートの前に%を付けると比較ステートメントは大文字小文字を区別せずに解釈されます。"名前 = 値" 比較ステートメントの場合、このオプションを使って値のみを大文字・小文字の区別せずに取り扱うことにご注意ください。名前のルックアップは常に大文字・小文字を区別して評価します。左ダブルクォートの前に$記号を配置すると比較ステートメントを正規表現で解釈します。標準のPOSIX正規表現をサポートしています。正規表現を使って大文字・小文字も区別しないように指定する場合$記号と%記号を左ダブルクォートの前に$%の順で配置します。

感嘆符 ('!') だけで構成される特殊なケースのサブスクリプション文字列は、サブスクリプションが任意の通知が一致しないことを意味します。

イベントを変更して特定のサービスを選択したい場合、次のようにします。
%"eventType=database/event/servicemetrics/<serviceName> "

Running with Database Server 10.2 or later

この方法はデータベース・サーバ上で実行し、Grid Infrastructureクラスタで利用可能なONSデーモンに直接接続します。FANwatcherユーティリティを実行する場合、$CRS_HOME/opmn/conf/ons.configファイルへアクセスできる権限を持つユーザーで実行する必要があります。このファイルはONSデーモンが開始するために利用され、このプログラムがアクセスします。コマンドラインの構成タイプは "crs" に設定します。
# CRS_HOME should be set for your Grid infrastructure
echo $CRS_HOME
CRS_HOME=/mypath/scratch/12.1.0/grid/
CLASSPATH="$CRS_HOME/jdbc/lib/ojdbc6.jar:$CRS_HOME/opmn/lib/ons.jar:."
export CLASSPATH
javac fanWatcher.java
java -Doracle.ons.oraclehome=$CRS_HOME fanWatcher crs

Running with WLS 10.3.6 or later using an explicit node list

クライアント環境で実行するには2つの方法があります。明示的なノードリストを使う方法と、自動ONSを使う方法です。これは、WebLogic Serverのために構成する場合、利用可能なojdbcN.jarとons.jarが必要です。直接UCPと共に実行するようセットアップする場合、これらのjarファイルがCLASSPATHに含まれる必要があります。

最初の方法では、Oracle JDBCドライバとDatabase 11g以後で動作します(SCANは、WLS10.3.6と同梱された11.2.0.3 jarファイルを含むOracle Databaseのバージョン以後でサポートされます)。
# Set the WLS environment using wlserver*/server/bin/setWLSEnv
CLASSPATH="$CLASSPATH:." # add local directory for sample program
export CLASSPATH
javac fanWatcher.java
java fanWatcher "nodes=rac1:6200,rac2:6200" database/event/service
ノードリストは改行文字で区切られた1個以上の名前 = 値 の形式の文字列です。ノードリストでは2個のフォーマットがサポートされています。
一つ目はONS全バージョンで利用可能です。以下の名前を指定することができます。

  • nodes(必須):host:portの組み合わせをコンマ区切りで表記します。
  • walletfile:ONSサーバとのSSL通信のためのOracle walletファイル
  • walletpassword:Oracle walletファイルを開くためのパスワード

二つ目の方法は、Database 12.1.0.2以後で利用可能なもので、複数のクラスタやノードリストを持つより複雑なトポロジーをサポートし、以下の名前を持ちます。

  • nodes.id—この値は、リモートONSサーバの一意のトポロジーを表すノードのリストです。IDはノードリストの一意の識別子を指定します。重複エントリは無視されます。任意のリストで構成済みのノードのリストには、同じクライアントのために、他のリストで構成済みのノードが含まれていてはいけません。もし含まれていると、重複通知が送信・配信されます。リストは、ONSデーモンのリスニングアドレスとポートのペアをコロンで区切ったものをカンマで区切ります。
  • maxconnections.id—この値はONSサーバで維持される最大同時接続数を指定します。idはこのパラメータが適用されるノードリストを指定します。デフォルト値は3です。
  • active.id—trueの場合、リストはアクティブでONSサーバの構成済み個数に対する接続を自動的に確立します。falseの場合、リストは非アクティブで、アクティブなリストに対する接続が確立できない場合におけるフェールオーバーリストとしてのみ利用されます。非アクティブなリストはある時点における、あるアクティブなリストに対するフェールオーバとしてのみ提供することができ、アクティブなリストで1個の接続が再度確立すれば、フェールオーバリストは非アクティブに戻ります。ただし、リストがフェールオーバした後にクライアントが発行する通知のみをフェールオーバリストに送信することにご注意ください。idは、このパラメータが適用されるノードリストを指定します。デフォルト値はtrueです。
  • remotetimeout —各リモートサーバへの接続タイムアウト時間(単位はミリ秒)。リモートサーバがこのタイムアウト時間内に応答しない場合、接続を閉じます。デフォルトタイムアウト時間は30秒です。

walletfileとwalletpasswordも指定できます(すべてのONSサーバに対して1個のwalletfileがあることに注意してください)。ノード属性をname.id属性と組み合わせることはできません。

Running with WLS using auto-ONS

Auto-ONSはOracle Database 12.1.0.1から利用できます。それまでは、何も情報を入手できませんでした。Database 12cR1のドライバを同梱した最初のWebLogic Server 12.1.3なので、このアプローチはデータベースのjarファイルをアップグレードしなければ動作しません。Auto-ONSはデータベースのの接続を取得してONSの情報をサーバに対してクエリすることで動作します。このプログラムが動作するためには、ユーザ、パスワード、URLが必要です。サンプルプログラムでは、(コマンドラインで入力しなくてすむよう)値が環境上にある前提です。必要であれば、プログラムを変更してプロンプトを表示して入力させたり、値をJavaコード中に埋め込んだりすることもできます。
# Set the WLS environment using wlserver*/server/bin/setWLSEnv
# Set the credentials in the environment. If you don't like doing this,
# hard-code them into the java program
password=mypassword
url='jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=\
(ADDRESS=(PROTOCOL=TCP)(HOST=rac1)(PORT=1521))\
(ADDRESS=(PROTOCOL=TCP)(HOST=rac2)(PORT=1521)))\
(CONNECT_DATA=(SERVICE_NAME=otrade)))'
user=myuser
export password url user
CLASSPATH="$CLASSPATH:."
export CLASSPATH
javac fanWatcher.java
java fanWatcher autoons

fanWatcher Output

出力結果は以下のようになります。プログラムを変更して出力結果を所望通りに変更することができます。この短い出力結果には、メトリックイベントとインスタンスの一つでのサービス停止に伴うイベントがあります。
** Event Header **
Notification Type: database/event/servicemetrics/otrade
Delivery Time: Fri Dec 04 20:08:10 EST 2015
Creation Time: Fri Dec 04 20:08:10 EST 2015
Generating Node: rac1
Event payload:
VERSION=1.0 database=dev service=otrade { {instance=inst2 percent=50 flag=U
NKNOWN aff=FALSE}{instance=inst1 percent=50 flag=UNKNOWN aff=FALSE} } timestam
p=2015-12-04 17:08:03


** Event Header **
Notification Type: database/event/service
Delivery Time: Fri Dec 04 20:08:20 EST 2015
Creation Time: Fri Dec 04 20:08:20 EST 2015
Generating Node: rac1
Event payload:
VERSION=1.0 event_type=SERVICEMEMBER service=otrade instance=inst2 database=dev db_domain= host=rac2 status=down reason=USER timestamp=2015-12-04 17:

2016年1月28日

[SOA] Patching SOA Composite Instances in Oracle 12.2.1

原文はこちら。
https://blogs.oracle.com/integration/entry/patching_soa_composite_instances_in

Introduction

Composite Instance Patching12.2.1で導入された新機能で、これを使うと互換性のある変更をSOAコンポジット定義に対して実施し、長時間実行中のアクティブなインスタンスに適用することができます。特徴は、コンポジットを実行中のインスタンスに対してパッチを適用し、ランタイムにパッチを適用した後、失敗したインスタンスを回復できる、という点で、これを使うことで、コンポジットに対する緊急の修正を提供し、長時間実行中のインスタンスを停止せずに互換性/許可された変更をコンポジットに対して適用できます。パッチが適用された実行中のインスタンスがパッチによって修正されたビジネスプロセス、例えばBPELのTransformationに遭遇すると、ビジネスプロセスに適用された修正を受け取ります。
12.2.1以前では、コンポジットに小さな変更を加えたり、実行中のインスタンス、具体的には長時間実行中のインスタンスや、エラーホスピタルのインスタンスがそうした変更を確認する方法がありませんでした。代替策としては、既存のコンポジットのリビジョンをデプロイするか、新たなコンポジットのリビジョンを作成することですが、前者の場合、実行中のインスタンスが処理を停止してしまうこと、後者の場合、既存の実行インスタンスはそのまま実行できるものの、新しいリビジョンで導入された変更はわからない、という問題があります。そこで、12.2.1での新しいComposite Instance Patching機能を使用すると、重要な修正をタイムリーに適用し即時有効化できる、という点が、Oracle SOA Suiteのユニークな差別化要素です。
このエントリでは、(1) コンポジットに加えることのできる互換性のある変更について紹介するとともに、(2) コンポジットパッチで無効な変更を加える心配なく、迅速かつ簡単にパッチを設計できる、JDeveloperへの機能強化を説明し、(3) SOA Suiteへコンポジットインスタンスへのパッチをビルド、検証、デプロイで使う手順を紹介します。

Compatible Composite Changes

前述の通り、コンポジットに対して加えることができ、実行中のインスタンスとの互換性があると見なされる変更は限られています。Composite Instance Patchingで扱える互換性のある変更をいくつかご紹介しましょう。
  • スキーマに関係しないXSLTの変更
  • フォルトポリシー、センサーデータ、アナリティクスデータへの変更
  • BPELへの互換性のある変更。例えば同期/非同期呼び出し、Transformationアクティビティ、Assignなど
  • JCA Adapterの構成プロパティ
  • コンポジット参照(Reference)のトークン値の変更
対して、Composite Instance Patchingで扱えない、互換性のない変更は以下のようなものがあります。
  • コンポジットあーティファクトの削除や名前変更
  • バインディングプロパティの更新
  • WSDLやスキーマ定義への変更
  • XQueryマッピングへの変更
  • BPELのReceive、構造化アクティビティ、Assignにおけるマッパー(ソース、ターゲット、スキップ条件)
どれが互換性のある変更で、どれが非互換なのかを正確に知っておく必要はありません。こうしたルールはJDeveloperのSOA Patch Developerモードで把握しており、自動的にパッチを作成できない変更を無効化します。

Composite Instance Patch Development in JDeveloper

コンポジットインスタンスへのパッチ作成を簡単にするため、数多くの機能強化がJDeveloperになされました。第1の変更点は、新たなSOA Patch Developerロールの導入です。JDeveloperを立ち上げたときに、最初に自身の要求に適うロールを選択する必要があります。


選択されたロールでは、メニュー、プリファレンス、新規ギャラリ、およびダイアログ上の個々のフィールドまでを含む、不要な項目をJDeveloperから除去するようにJDeveloper環境を仕立てます。選択したロールによって、利用可能な機能とオプションが決まります。SOA Patching Developerロールの場合、利用可能なアクション、エディタ、ウィザードによってユーザーが制限され、コンポジットインスタンスへのパッチ作成のため、互換性のある変更に関連するアクションのみ許可されます。
すでにJDeveloperでプロジェクトを開いている場合は、Oracle JDeveloperのメニューバーから、[ツール]> [ロールの切替え]>[SOA Patch Developer]とたどって、SOA Patch Developerモードに切り替える必要があります。 新たなロールを選択すると、変更を有効にするためにJDeveloperを再起動するように求められます。





新しいコンポジット・インスタンス・パッチを作成する場合、出発点は既存のデプロイ済みSOAコンポジットのリビジョンです。SOA Patch Developerロールである間、コンポジットへの後の変更は新たなpatch.xmlファイルでトラッキングされています。このファイルは変更されたアーティファクトファイルが最初に保存される際にプロジェクトディレクトリ内のSOA/SCA-INFディレクトリに自動的に生成されます。patch.xmlファイルは、SOA Patch Developerモードでコンポジットを変更、保存するたびに更新されます。patch.xmlファイルはメニューバーの[アプリケーション]>[概要の表示]を開き、XMLファイルの配下にあるpatch.xmlを選択すると表示できます。
プロジェクトにpatch.xmlがあるかないかで、コンポジット・パッチを作成しているのか、新規リビジョンを作成しているのかをJDeveloperに伝えます。SOA Patch Developerロールでない場合にpatch.xmlファイルを含むプロジェクトを開くと、以下の3個の方法のうち一つをとるよう求められます。
  1. SOA Patch Developerロールに切り替え、パッチ作成を継続する
  2. 現在のロールでプロジェクトを閉じる(つまり何もしない)
  3. project.xmlファイルを削除し、新しいコンポジット・リビジョンを作成する

なお、project.xmlファイルの削除を選択した場合、SOA Patch Developerロールで実施したコンポジットへの変更は消失しませんが、パッチ用にアーティファクトを修正したその記録はなくなることにご注意ください。

[訳注]
本来ならば、[Patch File Found]を意味する「パッチ・ファイルが見つかりました」となるべきところが、翻訳ミスで逆の意味になってしまっています。現在修正を依頼しています。


なお、英語の場合はこんな感じです。


patch.xmlファイルで参照されているアーティファクトのみコンポジットインスタンスパッチのデプロイメントアーカイブに取り込まれます。パッチアーカイブには通常のデプロイメント・アーカイブ(.sarファイル)にあるファイルの完全なセットは含まれていませんので、「少ない(sparse)」パッチ・アーカイブとも呼ばれます。パッチ・アーカイブを作成するためには、実行環境に変更をデプロイするためのデプロイメント・プロファイルを作成することから始めます。以下の手順を踏んでJDeveloperを使ってパッチのデプロイメント・プロファイルを作成します。
  1. [アプリケーション]内のプロジェクト名を右クリックし、[デプロイ]>[プロジェクト名]を選択します。新規デプロイメント・プロファイルを選択してもよいですし、以前に作成したパッチのデプロイメント・プロファイルを選択してもかまいません。[プロジェクト名]のデプロイウィザードが現れます。
  2. プロジェクトをデプロイするために、ウィザードの全手順を完了します。デプロイの構成(Deploy Configuration、なぜか日本語表示では構成のデプロイになっていますが...)画面では新たなバージョンの作成や既存バージョンの上書きはできないことに注意してください。これは別のバージョンを作成せず、実行中のインスタンスに影響を与えずに、パッチを実行環境にデプロイするためです。
  3. [終了]をクリックして、パッチのjarファイルを作成します。プロジェクト名/deployディレクトリにパッチのjarファイルがプロジェクトオリジナルのjarファイルに加えて格納されているはずです。デフォルトでは、パッチのjarファイルの名前はsca_{プロジェクト名}_patch.jarという表記ルールに則っています。
その他にも、AntやWLSTコマンドラインツールを使ってパッチ・アーカイブを作成することができます。パッチ・アーカイブをAntで作成する場合、以下のようにスクリプトを呼び出します。
ant -f  jdev_home/soa/bin/ant-sca-package.xml  -DcompositeDir=path_to_project_soa_folder -DcompositeName=composite_name  -Drevision=composite_revision
WLSTコマンドラインツールを使ってパッチ・アーカイブを作成する場合、sca_packagePatchコマンドを使います。sca_packagePatchコマンドの構文や引数に関する詳細情報は、ヘルプコマンド help(‘sca_packagePatch’) を使って確認できます。
例として、 sca_packagePatch('/home/HelloWorld/SOA','HelloWorld','1.0') とすると、/home/HelloWorld/SOA というディレクトリにコンポジット・アーティファクトのためのパッチ・アーカイブが作成されます。

Deploying the Composite Instance Patch

WLSTコマンドラインツールを使ってパッチのjarファイルを検証、デプロイすることができます。sca_validatePatchとsca_patchCompositeという2個のコマンドを使い、パッチを検証、デプロイします。以下の手順を踏んで、パッケージ済みjar(コンポジットのSARファイル)を検証し、実行環境にデプロイします。
  • sca_validatePatchコマンドを使用して、パッチのjarファイルを検証します。sca_validatePatchコマンドの構文および引数の詳細情報は、help('sca_validatePatch')で確認できます。例として、sca_validatePatch('http://my_soa_server:8001', 'weblogic',  'welcome', '/home/sca_HelloWorld_patch.jar') を実行した場合、sca_HelloWorld_patch.jar というパッチファイルが正常にmy_soa_serverのSOAサーバ実行環境にデプロイできるかどうかを確認します。コンポジット・パッチの検証で問題がないことが確認されると、「コンポジット・パッチは正常に検証されました("Composite patch has been validated successfully")」というメッセージが表示されるはずです。
  • sca_patchCompositeコマンドを使用して、パッチのjarファイルを実行環境にデプロイします。help(‘sca_patchComposite’)でsca_patchCompositeコマンドの構文および引数の詳細情報を取得することができます。例えば、sca_patchComposite('http://my_soa_server:8001', 'weblogic', 'welcome', '/home/sca_HelloWorld_patch.jar') とすると、sca_HelloWorld_patch.jarというパッチのjarファイルを使ってmy_soa_serverの実行環境上のHelloWorldコンポジットにパッチを適用します。パッチが正常に適用されると、「コンポジットは正常にパッチが適用されました(Composite has been patched successfully)」のメッセージが表示されるはずです。デプロイ前にパッチのjarファイルを検証するのを忘れたとしても、心配する必要はありません。デプロイメント・アクション中に、コンポジットのリビジョンをアップデートする前にサーバ側で検証チェックを実施するので、非互換の変更によって実行環境へ誤ってアップロードされることはありません。
Enterprise Manager Fusion Middleware Controlで以前に失敗したフローインスタンスを確認していて、このパッチを適用後リカバリが可能な場合、リカバリしてみてください。

JDeveloper-Based Patching Process

Composite Instance Patchingを、正式なビルドプロセスに組み込む方法には様々考えられますが、その一つをご紹介しましょう。
  1. 開発者は「SOAパッチ開発(SOA Patch Developer)」モードでJDeveloperを起動し、、ソースコントロールで見つかった既存のコンポジット用の互換性のある変更/修正のセットを作成します
  2. ソース管理の"patching"ブランチに変更を保存し戻します。
  3. 「互換性のある」コンポジットの修正のデプロイメント・アーカイブをソース管理からantスクリプトを使って作成し、後続のテスト作業のため、テスト/ステージング環境にWLSTコマンドを使ってデプロイします1
  4. もしくは、デプロイメント・アーカイブをJDeveloperで作成し、その後のテストのために、WLSTコマンドを使用して開発環境にデプロイします1
  5. このアーカイブを本番環境にデプロイし、実行インスタンスが新しいメタデータを使って処理を継続します1
1ランタイム検証・互換性のチェックは、変更されたアーティファクトに対してパッチデプロイ中に実行されます。
JDev Patching Process


Conclusions

新機能であるComposite Instance PatchingがSOA Suite 12.2.1で導入されました。これを使うとコンポジットに対する緊急の修正を展開し、長時間実行中のインスタンスが取り込むことができるようになります。この機能はOracle Integration Continuous Availabilityに含まれています。その他の情報は、以下のドキュメントをご覧ください。
Oracle® Fusion Middleware Developing SOA Applications with Oracle SOA Suite 12c (12.2.1)
Patching Running Instances of a SOA Composite
http://docs.oracle.com/middleware/1221/soasuite/develop/GUID-F2B6386E-0F68-4797-96D2-196800394FEF.htm#SOASE-GUID-4010E817-DF41-4CCC-B9CC-196EE6AB8905

[Java] Moving to a Plugin-Free Web

原文はこちら。
https://blogs.oracle.com/java-platform-group/entry/moving_to_a_plugin_free

2015年末までに、多くのブラウザベンダーが標準ベースのプラグインサポートをやめたり、廃止のタイムラインを発表しました。具体的には、Flash、Silverlight、Java、その他のプラグインベースのテクノロジーを埋め込む機能を取り除く、というものです。
NPAPI Plugin Perspectives and the Oracle JRE
https://blogs.oracle.com/java-platform-group/entry/npapi_plugin_perspectives_and_the
http://orablogs-jp.blogspot.jp/2015/10/npapi-plugin-perspectives-and-oracle-jre.html
モダンブラウザのベンダーは自身の製品でのプラグインサポートを制限、取りやめようとしているので、Javaブラウザプラグインに依存するアプリケーションの開発者は代替策を検討する必要があります。例えば(ブラウザプラグインに依拠している)Java Appletからプラグインが不要なJava Web Startテクノロジーに移行するといった具合です。
Java™ Web Start
http://docs.oracle.com/javase/8/docs/technotes/guides/javaws/
http://docs.oracle.com/javase/jp/8/docs/technotes/guides/javaws/
(訳注)
なぜかJava 8のドキュメントなのにJava 7という表記になっているのはご愛敬...。

OracleはJavaブラウザプラグインをJDK 9でdeprecate(非推奨)にする予定です。 将来のJava SEリリースでは、Oracle JDK およびJREからこのテクノロジーをなくす予定です。

JDK 9のEarly Accessリリースは以下のURLからダウンロードし、テストできます。
JDK 9 Project - Building the next generation of the JDK platform
http://jdk9.java.net 
背景や様々な移行の選択肢に関する情報は以下のリンクのホワイトペーパーをご覧ください。
Migrating from Java Applets to plugin-free Java technologie
http://www.oracle.com/technetwork/java/javase/migratingfromapplets-2872444.pdf