[ADSI TroubleShooting] : 大量のユーザ登録処理とかを一気に行うとポート枯渇が起きる


みなさまごきげんよう。ういこです。


 


最近私の近辺が狂ったようにダイエットしています。ILM 一家のお父さんなんて、お弁当を買いに行くたびに「これはカロリーは…あっ、XXX kcal もある!!」なんて思春期の小娘のようなことをいちいち言うですよ。お父さん、食べて運動するのがシェイプアップの本筋ですよ!!


そして私はクリスマス、家族に宇宙戦艦ヤマトの万歩計をあげたのですが、まさかイスカンダルまでテクシー (※徒歩) で行くんじゃないだろなと思ってたら本当にそうでした。14 8000 光年を歩くらしいです。しかもタイムリミットがあるらしく、見ているとしょっちゅう沖田艦長に「このままでは地球が滅亡する…!」と脅されているようです。なんでも、メタボクリーナー (内臓脂肪除去装置) をゲットしに行くとか。なかなか歩けない生活の家族の人は、たまに手でシャカシャカ振ってますがいいんですかそれ。


 


そんなオトコ心はさておいて、今日の話題です♪


 









【今日のお題 】 あら大変!ADSI 大量にユーザの登録とか変更とかしてるとエラーが起きちゃうんですってよ!


 


世のIT 管理者様がいよいよ腕の見せ所を魅せる時期がやってまいりました!! そう、会計年度の切り替わりです。世は不景気ながら会社の統合、新人の入社などで激しく Directory Server にユーザ オブジェクトを追加したり変更したり削除したり…しまくりますよね?4 月ってそういう月って言うのが多いのではないでしょうか。


 


ところが、そんなあなたががんばって気張ってつくったスクリプトやプログラムが、何千件かぐるぐるどっか~んと追加してたら突然無常な「操作エラーです。」とか出やがられた!…そんなとき、どこから切り分けていきますか?


弊社にお問い合わせいただいても良いのですが、この不景気のご時勢貴重な Labor やインシデント、費用などを賢くセーブするためにまだまだ出来ることがあります。



現象


 


まず、以下の条件に当てはまる場合、ポート枯渇が原因である可能性がかなり高いです。


 


ADSI を使用し、大量にユーザ登録、変更などの処理を行っている。(何千件も)


・ループを使い、処理を激しくハムスターの車上等くらいの勢いでぶんまわしている。


 


どうですか?当てはまりますか?


当てはまるようならば、本当にポート枯渇かを確認していきましょう。手段は至極簡単。Netstat コマンドOS の一時ポートの空き状況を見ればよいです。


 


取得対象は、サーバ、クライアント(プログラム実行端末)双方がいいでしょう。


 


: CMD Shell 上で "netstat -a" コマンドを実行する。


実際に実行した際に得られる情報としては以下のようになります。以下は実際に問題が起きた環境で netstat –a を取得した例です。


 



























Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

C:\Users\uikou>netstat -a

アクティブな接続

 
プロトコル  ローカル アドレス          外部アドレス        状態


TCP    0.0.0.0:34572          0.0.0.0:0               LISTENING


TCP    0.0.0.0:34573          0.0.0.0:0               LISTENING


… (以下省略)


TCP    192.168.0.1:139        0.0.0.0:0               LISTENING


TCP   192.168.0.1:1025       192.168.0.2:389        ESTABLISHED
TCP
  192.168.0.1:1026       192.168.0.2:389        ESTABLISHED
TCP    192.168.0.1:1027       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1028       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1029       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1030       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1031       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1032       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1033       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1034       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1035       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:1036       192.168.0.2:389        TIME_WAIT


… (以下省略)


TCP    192.168.0.1:4996       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:4997       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:4998       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:4999       192.168.0.2:389        TIME_WAIT


TCP    192.168.0.1:5000       192.168.0.2:389        TIME_WAIT


さて、ここで見るべきポイントは、上の黄色い 1925 5000 のところです。これは、一時ポートです。OS は既定では一時ポートとして 1025 番から 5000 番を使用します。


↑をみてみると、なんと、389 番ポート (LDAP) に通信しているのが 1025 から 5000 までいますわよ奥様Oh、なんということでしょう、使い切っちゃってますね。枯渇してる典型的なパターンです。1025 5000 番を使い切った場合、5000 番以降は既定では割り当てられず、ポート枯渇が起こる可能性があります。( 後述 : 設定で変更可能)


 


TIME_WAIT 状態は、ただし、TCP 接続終了プロセスが完了した状態です。相手がずーっと無応答でも、「私このくらいの間までなら待ってもいいわフラグ」みたいな情報がレジストリにあって、このフラグに指定された時間までは待ってくれるのですが特にそれ以降なにもないようならばポートがリサイクルされ、再度割り当て可能になってくれるという仕組みです。


これが、規定では 240 = 4 分です。この間にループなどで大量処理を行うと、ポートのリサイクルが追いつかず、ADSI の処理はセッションが張れず、結果として問題が発生してしまうということになるのです。



原因


 


それでは、なぜこんなにびっくりするくらいセッションが張られてしまうのでしょうか。


ADSI は、ユーザ作成など処理を行う際、セッションを確立しますが、その際に少なくとも 1 セッション = 1 ポートが割り当てられるからです。


イメージとしてはこんな感じです。


 


 




対処方法


 


対処方法は


 


1.    プログラムのつくりを見直す


2.    ポートの再利用の間隔を短くする + 一時ポートの割り当て数を増やす


 


といったことがあげられます。1. については個々のプログラムのつくりを判断しなくてはいけませんので、ここでは 2. について取り上げます。


 


Ø  MaxUserPort


割り当て可能な一時ポートの限界を設定します。既定は 5000 です。


OS は既定では一時ポートとして 1025 番から 5000 番を使用します。


この値を変更しない状態で1025 5000 番を使い切った場合、ポート枯渇が起こる可能性があります。


 


Ø  TcpTimedWaitDelay


TCP 接続終了プロセスが完了した (TIME_WAIT 状態の) ポートが再度利用可能になるまでの時間です。既定では 240 = 4 分です。全てのポートが TIME_WAIT 状態になると接続が出来なくなりますので、短時間に大量に接続、切断が行われるような処理においてはTIME_WAIT の時間を短くすることでポートのリサイクルが迅速に行われるため、一時ポートを大量に使用する処理を行うことが事前にわかる場合はこちらの値を設定いただくことが有効です。


ただし、処理を自動化し、一気に一時ポートを使い切るようなことも考えられますので、上述の MaxUserPort 値を拡張し、割り当て可能な一時ポート数を増やすこともあわせて行うことが現実的な対処としては良いでしょう。



ポート変更に対するデメリットの評価


 


それでは、レジストリを変更することによるデメリットを気にされる方もいらっしゃるかと思います。結論からいえば、TcpTimedWaitDelay


よび MaxUserPort 値を拡張したデメリットについてはポートを使用する各アプリケーションごとの実装依存部分が多く、共通する定量的な情報としての評価はできません。


よって、評価を行う場合は、パフォーマンス モニタを使用し各環境ごとに状況を確認しつつ、どの程度の値に変更するべきかという判断を行う必要があるということになります。


 


しかし、あえて定性的なデメリットとしてあげるのであれば、


 


TcpTimedWaitDelay を使用し TIME_WAIT の時間を短くすることによりリサイクルまでの間隔が短くなるため、再使用を行う際に、再度ポートの割り当て処理を行う必要があり CPU などのリソースを変更前より多く必要となる可能性がある


 


MaxUserPort 値を増やすことにより、同時に接続できるポート数が増加することで瞬間的な CPU / メモリ / ネットワーク帯域 のリソースの使用率の上昇が発生する可能性がある


 


などでしょうか。


 


なお、パフォーマンス モニタの評価を行う場合、パフォーマンス モニタ自体の負荷も考慮するためレジストリ値の変更前後にての差分値による評価を行うことがよいでしょう。また、評価を行う場合には適用前後にて同等の負荷をかける必要もあります。


 


評価対象としては、タスクマネージャ のパフォーマンスとネットワーク タブで確認できる項目についてとなります。


代表的な項目については以下の 3 つの項目となります。


 


Processor\%Processor Time   CPUの利用率


Memory\Available Bytes   実行中のプロセスに利用可能な物理メモリーのサイズ


Network Interface\Bytes   Total/sec 1秒にあたりのNIC上で送受信されるバイト数


 


パフォーマンスチューニングを行う場合は、お客様のシステム要件に合わせた評価を行う必要があります。CPU / メモリ / ネットワークの負荷の上昇分についての評価を行うと言った場合、上昇分がシステム要件を考えた場合に許容できる範囲であるかを判断します。


 


: レスポンスタイムが 5 以内に収める必要があり、CPU の負荷状況については 平均値 70 %を超さないようにする等



参考情報


 


Netstat


http://technet2.microsoft.com/WindowsServer/ja/library/7b3ae3c0-4b95-4cb7-a290-57b22824194b1041.mspx?mfr=true


 


コマンド ライン ユーティリティ - "netstat を使って接続統計を表示する"


http://technet.microsoft.com/ja-jp/library/cc757819.aspx


 


5000 を超える番号の TCP ポートから接続しようとすると 'WSAENOBUFS (10055)' エラーが表示される


http://support.microsoft.com/default.aspx?scid=196271


 


ういこう@てちてちまーち


 


関連 : [ADSI] セッションの張り方に伴う一時ポートの使われ方 ~ 同じ関数の組み合わせでも順序などで使われ方が変わる ~


http://blogs.technet.com/jpilmblg/archive/2009/04/10/ADSI_2D00_Session_5F00_and_5F00_Dynamic_5F00_Port.aspx


(2009/04/11 Update)

Comments (0)

Skip to main content