数か月前の事になりますが、「RACでCPU負荷が1ノードに偏る」と同じ環境で再びCPU負荷の偏りが発生しました。
但し今回は事象がかなり違います。
前回はサーバプロセス数に顕著な偏りは見られませんでしたが、今回は明らかに異なっています。
v$sessionを確認した結果、各ノードのセッション数は下記の通りでした。
DB#1:1057
DB#2:1726
ノード2の方が明らかにセッション数が多いのですが、CPU負荷は低く、ノード1のCPU使用率が高くなっています。
詳細に見てみると、以下のようなセッションが大量にいます。
INST_ID LOGON_TIME LAST_CALL_ET
2 2020/01/24 02:36:10 996496
2 2020/01/24 02:36:10 996496
2 2020/01/24 02:36:10 996496
2 2020/01/24 02:36:11 996495
2 2020/01/24 02:36:11 996495
2 2020/01/24 02:36:11 996495
2 2020/01/24 02:36:12 996494
2 2020/01/24 02:36:13 996494
2 2020/01/24 02:36:13 996494
LAST_CALL_ETのマニュアルの説明は以下の通りです。
セッションSTATUSが現在ACTIVEである場合は、セッションがアクティブになってからの経過時間(秒)を表す。
セッションSTATUSが現在INACTIVEである場合は、セッションが非アクティブになってからの経過時間(秒)を表す。
v$sessionを確認したのは2/4でLAST_CALL_ETは約11日なので、これらのセッションはログイン後、使用されないままになっている事になります。使用されていないから、セッション数が多くてもCPU使用率は低い訳です。
この環境ではデフォルトのサービスを使用してロードバランスさせているので、本来ならセッション数は概ね均等になる筈です。
これだけセッション数に偏りが出るのもおかしいですが、それ以上に使われないセッションが多数いるのが怪しいです。
DB側でのロードバランス設定より、APサーバのWeblogicのデータソースの設定に問題があるのでは・・・?
そこでMOS(MyOracleSupport)を検索した所、以下のドキュメントを見つけました。
JDBC Driver 12c から論理接続のクローズ時にコネクションイベントが発行されない (ドキュメントID 2403324.1)
概略は以下の通りです。
Oracle JDBC Driver 12.1.0.1 またはそれ以降のバージョンでは、論理接続のクローズ時に connectionClosed / connectionErrorOccurred イベントが発行されません。
この結果、 javax.sql.ConnectionEventListener によってコネクションイベントを実装している接続プールマネージャーでは、コネクションリークが発生する可能性があります。Universal Connection Pool (UCP) の場合、接続管理にコネクションイベントを使用していないため、接続リークは発生しません。
コネクションリークとは何ぞやというのをWeblogicのドキュメントで調べてみました。
・アプリケーションがデータソースを利用して接続を要求した時、データソースの接続プールに未使用のConnectionオブジェクトがあれば、それを「予約」してアプリケーションが利用します。
• アプリケーションは利用後coloseメソッドを実行すると、接続プールにConnectionオブジェクトが戻されます。
• アプリケーションがリリースを行わないと、接続プールにConnectionオブジェクトが戻らず、他のアプリから使用できない状態になります。これをConnectionリークといい、接続プールにおいては発生させてはならない事象の一つです。
Weblogic側でコネクションリーク が発生しているなら、使用されないセッションが大量にノード2にいるのは納得できます。
更にWeblogicのマニュアルを調べたところ、RACの場合はDB側のロードバランス機能を使用するのは非推奨で、マルチデータソースまたはActive GridLink (AGL)データ・ソースを使用してWeblogic側でロードバランスおよびフェイルオーバーするのが推奨だそうです。
Weblogicは担当外なので、上記内容を担当チームに連携してこの件は終わりました。