はじめに
こんにちは!さいけです。
今回は、「負荷ツールを利用して「socket: Too many open files」のエラーが出た場合の解決方法」について紹介します。
備忘録的な記事になります。
負荷ツールを利用して「socket: Too many open files」のエラーが出た場合の解決方法
結論から言うと、ファイルディスクリプタの上限を変更すると「socket: Too many open files」のエラーを解決することができます。
ファイルディスクリプタ?という方のためにわかりやすい解説記事があるので貼っておきます。mm
このエラーは、負荷(同時リクエスト)をかけたことによって、プロセスが開けるファイルディスクリプタが上限に達してしまったために発生するエラーです。
なので、このエラーは負荷ツール(abコマンド、vegata等)で同時リクエスト数を増加させた場合によく発生するようです。
では、次に解決方法であるファイルディスクリプタの上限変更方法をについて解説していきます。
ファイルディスクリプタの上限変更方法
今回は2つの方法を紹介します。
- 暫定的にファイルディスクリプタを変更する
- 恒久的にファイルディスクリプタを変更する
暫定的にファイルディスクリプタを変更する
以下のコマンドで暫定的にファイルディスクリプタ数を変更することができます。
$ ulimit -n <設定値>
実際にファイルディスクリプタの設定値を変更してみます。
$ ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-v: address space (kbytes) unlimited
-l: locked-in-memory size (kbytes) unlimited
-u: processes 2784
-n: file descriptors 256
$ ulimit -n 1024
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-v: address space (kbytes) unlimited
-l: locked-in-memory size (kbytes) unlimited
-u: processes 2784
-n: file descriptors 1024
ファイルディスクリプタが256から1024に変更されました!
恒久的にファイルディスクリプタを変更する
恒久的にファイルディスクリプタを変更するには、設定ファイルを作成します。
touchコマンドで/Library/LaunchDaemons/ に limit.maxfiles.plistを作成します。
$ touch /Library/LaunchDaemons/limit.maxfiles.plist
limit.maxfiles.plistファイルに、以下のようなxmlを追加します。
1024となっている箇所がファイルディスクリプタの設定値です。
<?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>
ファイルを作成すれば、恒久的に設定されるようになります。
Macを再起動してみて反映されているか確認してみてください。
再起動後、以下のコマンドを実行して、ファイルディスクリプタが変更されていればOKです!
$ ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-v: address space (kbytes) unlimited
-l: locked-in-memory size (kbytes) unlimited
-u: processes 2784
-n: file descriptors 1024
検証
ここでは、実際にファイルディスクリプタの上限を変更したら、「socket: Too many open files」のエラーが解決されるのか検証します。
検証方法はローカルのアプリケーションに同時リクエスト300のabコマンドを発行して検証します。
まず、ファイルディスクリプタは256に設定してエラーが再現するか検証します。
$ ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-v: address space (kbytes) unlimited
-l: locked-in-memory size (kbytes) unlimited
-u: processes 2784
-n: file descriptors 256
以下のabコマンドで同時リクエスト300を発行してみます。
$ ab -c 300 -n 300 http://localhost:8080/person This is ApacheBench, Version 2.3 <$Revision: 1843412 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) socket: Too many open files (24)
socket: Too many open files (24)が出ました。
では、以下の通り、ファイルディスクリプタの設定値を512に変更します。
$ ulimit -n 512
$ ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-v: address space (kbytes) unlimited
-l: locked-in-memory size (kbytes) unlimited
-u: processes 2784
-n: file descriptors 512
再度、同時リクエスト300のabコマンドを発行します。
$ ab -c 300 -n 300 http://localhost:8080/person This is ApacheBench, Version 2.3 <$Revision: 1843412 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Finished 300 requests Server Software: Server Hostname: localhost Server Port: 8080 Document Path: /person1 Document Length: 47 bytes Concurrency Level: 300 Time taken for tests: 0.032 seconds Complete requests: 300 Failed requests: 0 Total transferred: 49800 bytes HTML transferred: 14100 bytes Requests per second: 9439.31 [#/sec] (mean) Time per request: 31.782 [ms] (mean) Time per request: 0.106 [ms] (mean, across all concurrent requests) Transfer rate: 1530.20 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 9 1.4 9 11 Processing: 5 10 2.8 10 17 Waiting: 1 10 2.9 10 17 Total: 12 19 2.5 19 27 Percentage of the requests served within a certain time (ms) 50% 19 66% 20 75% 21 80% 21 90% 22 95% 23 98% 24 99% 25 100% 27 (longest request)
変更したところ、エラーが解決されabコマンドが正常に実行できました!
👍🎉
おわりに
今回は、「負荷ツールを利用して「socket: Too many open files」のエラーが出た場合の解決方法」について紹介しました。
負荷ツールを利用して負荷テストを実施する際は、ファイルディスクリプタの上限に引っかかってしまう罠が結構あると思うので、本記事が参考になれば幸いです。
ファイルディスクリプタには気をつけて\(^o^)/
コメント