開発システム(Ubuntu 21.10デスクトップ)の1つで実行されているカスタムアプリケーションがエラーでクラッシュしますsocket: Too many open files
。だからすぐに制限を確認してみました。出力は次のとおりです。
$ ulimit -n
65535
これが奇妙な理由は、アプリケーションがクラッシュしたときに1019ソケットのみを使用したためです。おそらく他のファイル記述子が開いていることを考えると、1024の制限に達したようです。
デスクトップにulimit -n
制限が65535であることが明確に示されていますが、1024の制限を課すのはなぜですか?
もっと奇妙にするためです。 2つのアプリケーションがあります。 1つはepoll
Webスクレーパーに基づいており、もう1つは接続を開始するために複数のWebサーバーにメッセージを送信するPACKET_MMAP
アプリケーションに基づいています。SYN
アプリケーションはepoll
クラッシュしませんが、1024よりもはるかに多くのソケットを使用します。そして、PACKET_MMAP
rawソケットを使用する基本的なアプリケーションがクラッシュしました。
さらに、サーバーでテストしたのと同じアプリケーション(Ubuntuも実行)は競合しません。
したがって、問題が何であれ、デスクトップと生のソケットアプリケーションにのみ当てはまります。
編集する:
cat /proc/pid/limits
必要に応じて出力:
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 31106 31106 processes
Max open files 1024 1048576 files
Max locked memory 1025802240 1025802240 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 31106 31106 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
出力は、最大オープンファイルのソフト制限が実際には1024であることを示しています。これはulimit -n
次のように一致します。
答え1
ユーザーとプロセスによってリソース制限を異なるように設定できます。特定のユーザーの特定の制限が表示されますulimit
が、systemd
独自の既定の制限があります。systemd
ファイル制限を設定するには、プログラムのユニットファイルを更新する必要があります。LimitNOFILE=1048576
バラより文書詳しくは
答え2
これが私がCコードでこの問題を解決した方法です。私のアプリケーションに次のコード行を追加しました。
#include <sys/resource.h>
...
struct rlimit lim;
getrlimit(RLIMIT_NOFILE, &lim);
printf("Soft: %d Hard: %d\n", (int)lim.rlim_cur, (int)lim.rlim_max);
lim.rlim_cur = lim.rlim_max;
if (setrlimit(RLIMIT_NOFILE, &lim) == -1) {
printf("rlimit failed\n");
return -1;
}
getrlimit(RLIMIT_NOFILE, &lim);
printf("New Soft: %d New Hard: %d\n", (int)lim.rlim_cur, (int)lim.rlim_max);
しかし、まだ私のシステムの設定ファイルを編集してこれを行う方法がわかりません。しかし、この答えは、Cコードの問題を解決するのに満足している人にとってはまだ便利です。
答え3
Ubuntu Linuxでsystemd管理サービスの制限を変更するには、override.confファイルでそれを構成する必要があります。私は例としてmariadbを使用していますが、これはすべてのサービスに一般化できます。
mkdir /etc/systemd/system/mariadb.service.d
vi /etc/systemd/system/mariadb.service.d/override.conf
このファイルには次の行を入力します。
[Service]
LimitNOFILE=65535
その後、ユニット宣言を再ロードする必要があります。
systemctl daemon-reload
そしてサービスを再起動してください
systemctl restart mariadb.service
今あなたはできます行政的管理プロセス制限。 Systemdはこの方法を使用して、次の制限を管理できます。
指示する | ulimit相当 | 単位 |
---|---|---|
CPU制限= | ulimit -t | 秒 |
制限FSIZE= | ulimit -f | バイト |
データ制限= | ulimit -d | バイト |
スタック制限 = | ulimit -s | バイト |
制限コア= | ulimit -c | バイト |
RSS制限= | ulimit-m | バイト |
制限NOFILE = | ulimit-n | ファイル記述子の数 |
制限AS = | ulimit -v | バイト |
NPROC=制限 | ulimit -u | プロセス数 |
制限MEMLOCK = | ulimit -l | バイト |
制限ロック = | ulimit-x | ロック数 |
署名制限= | ulimit -i | 待機中の信号数 |
制限 MSGQUEUE= | ulimit -q | バイト |
限度 NICE= | ulimit -e | 良いレベル |
制限RTPRIO = | ulimit -r | リアルタイム優先順位 |
制限RTTIME= | 対応するものはありません | マイクロ秒 |
システム文書からhttps://www.freedesktop.org/software/systemd/man/systemd.exec.html