概要
AWS ELBの暖気申請(Pre-Warming)をしたかったのですが、サポートのプランがBusiness以上でなければ申請できないため、自前でPre-Warmingをする必要がありました。
AWS ELBは負荷が上がった場合に、AutoScaleするLBです。
通常、事前に大量のトラフィックが予想できる場合は、WebサーバーとDBはスケールアップ/アウトできるのですが、その前段のLBが捌き切れないことが多々有ります。
マネージドサービスの場合、スケールするまで、数分~数十分要する為、機会損失が多くなってしまいます。
そこで、ELBの特性を考えて、自前に意図的に暖気(AutoScaleさせる)ことにしました。 負荷テストなどでよく使われるApache Benchを使おうとしたのですが、やっている途中でエラーが発生してしまったので、その備忘録としてApache Bench(abコマンド)をmacOSで実行した場合に出るエラー「socket: Too many open files (24)」の回避方法について書きます。
遭遇したエラー
Apache Benchの使用方法は下記の通りです。
ab -n [総リクエスト数] -c [同時リクエスト数] [URL]
[同時リクエスト]で指定した数値で[URL]に対してリクエストを行います。 リクエスト数が[総リクエスト数]に達したら終了です。
負荷をかけたいので、同時リクエスト数を増やすことになると思いますが、この数値を大きくした場合にsocket: Too many open files (24)というエラーが発生します。
原因
socket: Too many open files (24)は、プロセスが開けるファイルディスクリプタの上限に達してしまうと発生するエラーです。 そのため、この上限を変更する必要があります。
上限の確認は下記コマンドで確認ができます。
$ ulimit -n 256
ulimit
は使用できるリソースを制限するコマンドです。ファイルの最大サイズ、使用可能メモリ、同時実行プロセス数などを確認&制限できます。
-n
オプションは、同時に開けるファイル数です。
回避方法
回避方法は2つあります。
一時的に設定を変更する
先述したulimit
コマンドで設定を変更します。
$ ulimit -n 256 $ ulimit -n 1024 $ ulimit -n 1024
この変更はターミナルを閉じてしまうと既定値に戻ります。
そのため、ulimit
を使用する場合は、変更した直後(ターミナルのプロセスを閉じないうち)にApache Benchを実行する必要があります。
恒久的に設定を変更する
恒久的に設定を変更したい場合はlaunchctl
コマンドを使用します。
このコマンドはmacOSで使用できるコマンドで、macOSのプロセスを管理するためのコマンドです。
現状を確認するには下記コマンドを実行します。
$ sudo launchctl limit cpu unlimited unlimited filesize unlimited unlimited data unlimited unlimited stack 8388608 67104768 core 0 unlimited rss unlimited unlimited memlock unlimited unlimited maxproc 2837 4256 maxfiles 256 256
この結果の「maxfiles」が今回のエラーの原因にあたります。
これを変更するために、設定ファイルを用意します。 最初は用意されていないはずなので、新規作成します。
$ touch /Library/LaunchDaemons/limit.maxfiles.plist
次に、作成したファイルに設定を書き込みます。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>limit.maxfiles</string> <key>ProgramArguments</key> <array> <string>launchctl</string> <string>limit</string> <string>maxfiles</string> <string>1024</string> <string>1024</string> </array> <key>RunAtLoad</key> <true/> <key>ServiceIPC</key> <false/> </dict> </plist>
最後に、設定を反映させるためのコマンドを実行します。
$ sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist $ sudo launchctl limit cpu unlimited unlimited filesize unlimited unlimited data unlimited unlimited stack 8388608 67104768 core 0 unlimited rss unlimited unlimited memlock unlimited unlimited maxproc 2837 4256 maxfiles 1024 1024
バッチリですね。
まとめ
やんごとなき理由で、AWS ELBの暖気申請ができない方は自前でPre-Warmingを行うこともできます。 その場合、負荷テスト用のコマンド(今回はApache Benchを紹介)を使用することになりますが、macOSでは同時に開くファイル数の上限に達してしまうエラーで阻まれてしまいます。 これを回避する方法は2通りあります。
ulimit
コマンドで一時的に上限設定するlaunchctl
コマンドで恒久的に上限設定する