Befehl zur Linux-Ressourcenbegrenzung – ulimit

Kurze Beschreibung der ulimit-Funktion

Angenommen, es gibt eine Situation, in der 10 Personen gleichzeitig bei einem Linux-Host angemeldet sind. Wenn die Systemressourcen unbegrenzt sind, öffnen diese 10 Benutzer gleichzeitig 500 Dokumente. Unter der Annahme, dass die Größe jedes Dokuments 10 MB beträgt, ist dies At Dieses Mal werden die Speicherressourcen des Systems stark beansprucht. Die tatsächliche Anwendungsumgebung ist viel komplexer als diese Annahme. Beispielsweise sind in einer eingebetteten Entwicklungsumgebung alle Aspekte der Ressourcen sehr knapp, wie z. B. die Anzahl der offenen Dateideskriptoren, die Größe des Zuordnungsstapels, die CPU-Zeit und der virtuelle Speicher Größe usw. unterliegen sehr strengen Anforderungen. Angemessene Begrenzung und Zuweisung von Ressourcen.

Dies ist nicht nur eine notwendige Voraussetzung zur Gewährleistung der Systemverfügbarkeit, sondern auch untrennbar mit der Leistung der auf dem System ausgeführten Software verbunden. Zu diesem Zeitpunkt kann ulimit eine große Rolle spielen, da es eine einfache und effektive Möglichkeit ist, Ressourcenbeschränkungen umzusetzen. ulimit wird verwendet, um die vom Shell-Startprozess belegten Ressourcen zu begrenzen und die folgenden Arten von Einschränkungen zu unterstützen: die Größe der erstellten Kerneldatei, die Größe des Prozessdatenblocks, die Größe der vom Shell-Prozess erstellten Datei, die Größe der Speichersperre und des residenten Speichers. Die Größe des Satzes, die Anzahl der offenen Dateideskriptoren, die maximale Größe des Zuordnungsstapels, die CPU-Zeit, die maximale Anzahl von Threads für einen einzelnen Benutzer, der maximal mögliche virtuelle Speicher Wird vom Shell-Prozess verwendet. Gleichzeitig unterstützt es sowohl harte als auch weiche Ressourcengrenzen.

Als temporäres Limit kann ulimit auf die mit seinem Befehl angemeldete Shell-Sitzung einwirken. Das Limit endet, wenn die Sitzung beendet wird, und hat keine Auswirkungen auf andere Shell-Sitzungen. Für langfristige feste Grenzwerte kann die Befehlsanweisung ulimit zu der von der Login-Shell gelesenen Datei hinzugefügt werden und wirkt sich auf einen bestimmten Shell-Benutzer aus.

So verwenden Sie ulimit

ulimit verwaltet verschiedene Arten von Systemressourcen über einige Parameteroptionen. In diesem Abschnitt erklären wir die Verwendung dieser Parameter.

Das Format des ulimit-Befehls ist:

$ ulimit [options] [limit]
[options]

-H: 设置硬资源限制,一旦设置不能增加。如,ulimit -Hs 64;限制硬资源,线程栈大小为64K。

-S: 设置软资源限制,设置后可以增加,但是不能超过硬资源设置。如,ulimit -Sn 32;限制软资源,32个文件描述符。

-a: 显示当前所有的limit信息。如,ulimit -a;显示当前所有的limit信息。

-c: 最大的core文件的大小, 以blocks为单位。如,ulimit -c unlimited;对生成的core文件的大小不进行限制。

-d: 进程最大的数据段的大小,以Kbytes为单位。如,ulimit -d unlimited;对进程的数据段大小不进行限制。

-f: 进程可以创建文件的最大值,以 blocks 为单位。如,ulimit -f 2048;限制进程可以创建的最大文件大小为2048 blocks。

-l: 最大可加锁内存大小,以Kbytes为单位。如,ulimit -l 32;限制最大可加锁内存大小为32Kbytes。

-m: 最大内存大小,以Kbytes为单位。如,ulimit -m unlimited;对最大内存不进行限制。

-n: 可以打开最大文件描述符的数量。如,ulimit -n 128;限制最大可以使用128个文件描述符。

-p: 管道缓冲区的大小,以Kbytes为单位。如,ulimit -p 512;限制管道缓冲区的大小为512Kbytes。

-s: 线程栈大小,以Kbytes为单位。如,如,ulimit -s 512;限制线程栈的大小为512Kbytes。

-t: 最大的CPU占用时间,以秒为单位。 如,ulimit -t unlimited;对最大的CPU占用时间不进行限制。

-u: 用户最大可用的进程数。如,ulimit -u 64;限制用户最多可以使用64个进程。

-v: 进程最大可用的虚拟内存,如,以Kbytes为单位。如,ulimit -v 200000;限制最大可用的虚拟内存为200000Kbytes。

Parametername Entsprechende Optionen Bedeutung
-A Zeigt alle limitierten Ressourceninformationen des aktuellen Systems an, ulimit -a
Kerndateigröße -C Die Größenbeschränkung der Kernel-Kerndatei in Blöcken
Dateigröße -F Die maximale Größe der Dateien, die ein Prozess erstellen kann, in Blöcken
Datensegmentgröße -D Die Größe des größten Datensegments des Prozesses in KB
maximale Speichergröße -M Die Speichergröße, die der Prozess nutzen kann, in KB
Dateien öffnen -N Die maximale Anzahl an Dateideskriptoren, die einem Benutzer zur Verfügung stehen
Stapelgrösse -S Maximale Stackgröße in KB
Rohrgröße -P Pipe-Puffergröße in KB
maximale Benutzerprozesse -u Die maximale Anzahl von Prozessen, die einem Benutzer zur Verfügung stehen
virtueller Speicher -v Der maximal verfügbare virtuelle Speicher des Prozesses in KB
CPU-Zeit -T Maximale CPU-Nutzungszeit in Sekunden
Maximal gesperrter Speicher -l Maximale Größe des gesperrten Speichers in KB

Beispiele für die Verwendung von Ulimit

Gültiger Bereich des Benutzerprozesses

Als eine Art Einschränkung der Ressourcennutzung hat ulimit seinen Geltungsbereich. Beschränkt es das Objekt also auf einen einzelnen Benutzer, einen einzelnen Prozess oder das gesamte System? Tatsächlich begrenzt ulimit den aktuellen Shell-Prozess und seine abgeleiteten untergeordneten Prozesse. Wenn der Benutzer beispielsweise zwei Shell-Terminalprozesse gleichzeitig ausführt und nur in einer der Umgebungen ulimit -s 100 ausführt, unterliegt die Größe der im Shell-Prozess erstellten Datei dem entsprechenden Limit, während die andere Shell Das Terminal enthält keine der darauf ausgeführten Unterroutinen.

$ ll -h newfile 
-rw-r--r--. 1 root root 223K 4月  23 09:16 newfile
$ ulimit -f 100
$ cat newfile > shell1
File size limit exceeded (core dumped)
$ ll -h shell1
-rw-r--r--. 1 root root 100K 4月 23 09:20 shell1
$ cat newfile > shell2
$ ll -d shell2 
-rw-r--r--. 1 root root 227690 4月  23 09:23 shell2
$ ll -h shell2 
-rw-r--r--. 1 root root 223K 4月  23 09:23 shell2

Gibt es also eine Möglichkeit, die Ressourcen eines bestimmten Benutzers zu begrenzen? Die Antwort lautet: Ja, es ist vorübergehend wirksam (keine Begrenzung der Größe geöffneter Dateien):

$ ulimit -f unlimited

Oder indem Sie die Konfigurationsdatei /etc/security/limits.conf des Systems ändern. Diese Datei kann nicht nur die Ressourcennutzung bestimmter Benutzer, sondern auch die Ressourcennutzung bestimmter Gruppen begrenzen. Jede Zeile der Datei enthält eine Beschreibung der Einschränkung im folgenden Format:

#格式:<domain> <type> <item> <value>
#domain:表示用户或组的名字,还可以使用*作为通配符,表示所有用户。
#type:表示限制类型,soft表示软资源限制,设置后可以超过软资源限制,但是不能超过硬资源限制;hard表示硬资源限制,一旦设置不能超过限制。
#item:表示需要限定的资源名称,常用的有nofile(用户可用文件描述符最大数量)、CPU(占用CPU时间)、statck(最大堆栈大小)、noproc(用户最大可用进程数)等。
#value:表示限制资源的具体值。
#举例:
 * soft noproc 65535
 * hard noproc 65535
 * soft nofile 65535
 * hard nofile 65535

Durch das Hinzufügen der entsprechenden einzeiligen Beschreibung können Sie entsprechende Einschränkungen generieren. Zum Beispiel:

 * hard noflle 100

Diese Zeile der Konfigurationsanweisung begrenzt die maximale Anzahl von Dateien, die ein Benutzer erstellen kann, auf 100. Jetzt ist es möglich, Ressourcenlimits für Prozesse bzw. Benutzer festzulegen. Dies scheint ausreichend zu sein, ist es aber nicht. Viele Anwendungen müssen eine allgemeine Grenze für die Ressourcennutzung des gesamten Systems festlegen. Zu diesem Zeitpunkt müssen wir die Konfigurationsdatei unter / proc ändern. Das Verzeichnis /proc enthält viele Parameter des aktuellen Status des Systems, z. B. /proc/sys/kernel/pid_max, /proc/sys/net/ipv4/ip_local_port_range usw. Sie können die Arten eingeschränkter Ressourcen anhand des Verzeichnisses grob erraten Name der Datei. Da in diesem Verzeichnis viele Dateien enthalten sind, werde ich sie hier nicht einzeln vorstellen. Interessierte Leser können die entsprechenden Dateien für Anweisungen öffnen.

Begrenzen Sie die Shell-Speichernutzung mit ulimit

In diesem Abschnitt wird dem Leser gezeigt, wie er die Optionen -d, -m und -v verwendet, um den von der Shell verwendeten Speicher zu begrenzen. Schauen wir uns zunächst die Situation an, in der der Befehl ls aufgerufen wird, ohne das ulimit-Limit festzulegen:

$ ll shell1 -l
-rw-r--r--. 1 root root 227690 4月  23 09:16 shell1

Sie können sehen, dass der Befehl ls zu diesem Zeitpunkt normal ausgeführt wird. Legen Sie ulimit unten fest:

$ ulimit -d 1000 -m 1000 -v 1000
这里再温习一下前面章节里介绍过的这三个选项的含义:

-d:设置数据段的最大值。单位:KB。

-m:设置可以使用的常驻内存的最大值。单位:KB。

-v:设置虚拟内存的最大值。单位:KB。

Durch die obige ulimit-Einstellung haben wir den maximalen Speicher, den die aktuelle Shell verwenden kann, auf weniger als 1000 KB begrenzt. Sehen wir uns als Nächstes an, welche Ergebnisse wir erhalten, wenn wir zu diesem Zeitpunkt den Befehl ls ausführen:

$ ll shell1 -l
Segmentation fault (core dumped)

Verwenden Sie ulimit, um die Anzahl der Sockets zu begrenzen, die ein Programm erstellen kann

Betrachten Sie einen praktischen Bedarf in der Realität. Für ein Serverprogramm im C/S-Modell werden mehrere Socket-Ports erstellt, um auf mehrere Client-Programmanforderungen zu reagieren. Wenn eine große Anzahl von Clients gleichzeitig Anfragen an den Server stellt, muss der Server eine große Anzahl von Socket-Verbindungen erstellen. Aber unter Linux sind alle Ressourcen Dateien. Gewöhnliche Dateien sind Dateien, Festplattendrucker sind Dateien und Sockets sind natürlich auch Dateien. Durch das Erstellen einer neuen Socket-Verbindung unter Linux wird tatsächlich ein neuer Dateideskriptor erstellt. Linux hat Einschränkungen hinsichtlich der Dateideskriptoren, die ein einzelner Prozess öffnen kann. Standardmäßig beträgt die maximale Anzahl von Dateien, die ein einzelner Prozess öffnen kann, 1024. In ulimit gibt es keine Option, mit der die Anzahl der Sockets direkt begrenzt werden kann. Wir haben jedoch die Option -n, die verwendet wird, um die maximale Anzahl von Dateideskriptoren zu begrenzen, die ein Prozess öffnen kann. Wie unten gezeigt (sehen Sie sich die Dateideskriptorinformationen an, die derzeit von einem Prozess geöffnet werden):

$ ll /proc/36766/fd
总用量 0
lr-x------. 1 root root 64 4月  23 09:31 0 -> /dev/null
l-wx------. 1 root root 64 4月  23 09:31 1 -> /mydata/localhost.localdomain.err
lrwx------. 1 root root 64 4月  23 09:31 10 -> /mydata/ib_logfile1
lrwx------. 1 root root 64 4月  23 09:31 11 -> socket:[115703]
lrwx------. 1 root root 64 4月  23 09:31 12 -> /tmp/ibLxLFBt (deleted)
l-wx------. 1 root root 64 4月  23 09:31 13 -> /mydata/mysql-bin.000001
lrwx------. 1 root root 64 4月  23 09:31 14 -> socket:[115704]
lrwx------. 1 root root 64 4月  23 09:31 15 -> /mydata/mysql/host.MYI
.......................

Daher können wir die maximale Anzahl von Dateideskriptoren, die ein Prozess öffnen kann, mithilfe von ulimit -n begrenzen. Die Standardanzahl der von einem einzelnen Prozess geöffneten Dateideskriptoren beträgt 1024, was bedeutet, dass ein einzelner Prozess nur maximal 1024 oder verwalten kann noch weniger gleichzeitig (weil andere Dateihandles geöffnet sind). Wenn 4 Prozesse geöffnet werden, um Benutzerverbindungen aufrechtzuerhalten, überschreitet die Anzahl der Verbindungen, die die gesamte Anwendung gleichzeitig aufrechterhalten kann, 4 * 1024 nicht, was bedeutet, dass maximal 4 * 1024 Benutzer online unterstützt werden können. Diese Einstellung kann erhöht werden, sodass der Dienst mehr TCP-Verbindungen aufrechterhalten kann, wodurch die Anzahl der Socket-Erstellung begrenzt wird.

Wenn die Anzahl der von einem einzelnen Prozess geöffneten Dateihandles den systemdefinierten Wert überschreitet, wird die Fehlermeldung „zu viele Dateien geöffnet“ ausgegeben. Woher wissen, wie viele Dateihandles vom aktuellen Prozess geöffnet werden? Der Befehl lsof kann Ihnen bei der Überprüfung helfen:

$ lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr| head -n 2
    126 7015
     93 1831

Wie oben erläutert, hat der 7015-Prozess 126 Dateideskriptoren geöffnet. Sie können den Befehl ps verwenden, um zu sehen, welche Dienste der 7015-Prozess bietet (hier sind meine Beispiele). Sie sollten während des Experiments anhand Ihres eigenen Prozesses überprüfen. Ich glaube, Sie haben das Bewusstsein).

Ändern Sie die maximale Anzahl von Dateien, die von einem einzelnen Prozess geöffnet werden können

1) Rückgang um 102400

Dies ist nur im aktuellen Terminal gültig. Nach dem Beenden werden geöffnete Dateien auf den Standardwert zurückgesetzt.

2) Schreiben Sie ulimit -n 102400 in /etc/profile, sodass /etc/profile bei jeder Anmeldung am Terminal automatisch ausgeführt wird.

3) Um die geänderten Werte der geöffneten Dateien dauerhaft zu machen, müssen Sie die Konfigurationsdatei ändern: /etc/security/limits.confNach dieser Datei Folgendes hinzufügen:

* soft nofile 1024000
* hard nofile 1024000
root soft nofile 1024000
root hard nofile 1024000

Was Sie bei der Verwendung von ulimit beachten sollten

Nachdem Sie die Konfigurationsdatei geändert haben, müssen Sie das SSH-Terminal verlassen und sich erneut anmelden, damit sie wirksam wird.

Zusätzlich zu limits.confeinem anderen /etc/security/limits.dVerzeichnis liest und verwendet das System standardmäßig zuerst die Konfigurationsdateien in diesem Verzeichnis und liest dann limits.confdie Konfiguration. Wenn doppelte Konfigurationen vorhanden sind, /etc/security/limits.dhaben die Konfigurationsdateien im Verzeichnis Vorrang.

Die laufende Anwendung liest das neu hinzugefügte ulimit-Ressourcenlimit nicht und das Ressourcenlimit wird erst wirksam, wenn die Anwendung neu gestartet wird.

Die ulimit-Änderung 可使用文件描述符最大数量darf 1048576 (1024 * 1024) nicht überschreiten. Wenn Sie die Gesamtzahl erhöhen möchten, müssen Sie die Kernel-Parameter ändern /etc/sys/fs/nr_open.

Fügen Sie hier eine Bildbeschreibung ein

/etc/security/limits.confDie Konfiguration in der Datei wirkt sich nicht auf Systemdienste aus, sondern nur auf Benutzer, die sich über PAM anmelden, was bedeutet, dass sie über systemd verwaltet werden.

Der Dienstprozess wird von dieser Konfigurationsdatei nicht beeinflusst.

Fügen Sie hier eine Bildbeschreibung ein

So ändern Sie den Systemd-Verwaltungsdienst

Unter der Annahme, dass der Nginx-Dienst von systemd verwaltet wird, gibt es zwei Methoden, wenn Sie seine Ressourcengrenzen ändern müssen:

  1. Verwenden Sie diese Option, um ps aux|grep nginxdie ID des Nginx-Prozesses abzurufen

    # ps aux |grep nginx
    root    2441  0.0  0.0  50176  5952 ?  Ss  18:30  0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
    
  2. Führen Sie diese Option aus cat /proc/nginx_id/limits, um die aktuell wirksamen Ressourcengrenzen anzuzeigen

    # cat /proc/2441/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             261206               261206               processes 
    Max open files            65536                65536                files     
    Max locked memory         65536                65536                bytes     
    Max address space         unlimited            unlimited            bytes     
    Max file locks            unlimited            unlimited            locks     
    Max pending signals       261206               261206               signals   
    Max msgqueue size         819200               819200               bytes     
    Max nice priority         0                    0                    
    Max realtime priority     0                    0                    
    Max realtime timeout      unlimited            unlimited            us   
    

Globale Modifikation

Für von systemd verwaltete Dienste können Sie die globale Konfiguration /etc/systemd/system.conf oder /etc/systemd/user.conf ändern (wirksam für alle Dienste).

Welche spezifische globale Konfigurationsdatei geändert werden muss, hängt davon ab, ob der Systemd-Dienst selbst auf der Systeminstanz oder der Benutzerinstanz (normalerweise auf der Systeminstanz ausgeführt) ausgeführt wird.

# ps aux |grep systemd
root     1  0.5  0.0 158336 10176 ?        Ss   Mar30   7:54 /lib/systemd/systemd --system --deserialize 20

Wie oben gezeigt, bedeutet dies die Ausführung im Systeminstanzstatus. Wenn Sie als Benutzerinstanz ausgeführt werden möchten, ersetzen Sie –system durch –user. Aber normalerweise ist es der Systeminstanzstatus.

 #在配置文件中添加如下内容
 DefaultLimitNOFILE=655360
 DefaultLimitNPROC=655360

Es gibt zwei Methoden, um die Konfiguration so zu ändern, dass sie wirksam wird:

  • Starten Sie das System neu
  • implementierensystemctl daemon-reexec
Gründe, warum die Verwendung von Daemon-Reload ungültig ist

Durch die Verwendung systemctl daemon-reloadwird die globale Konfiguration /etc/systemd/system.conf nicht aktualisiert, wobei die Beschreibung von systemd-system.conf durch serverfault.com zitiert wird:

Ohne Aktualisierung lädt daemon-reload alle Unit-Dateien neu und nicht die eigene Konfiguration von systemd. Systemd wird jedoch systemctl daemon-reexecerneut ausgeführt und darf dabei seine neue Konfiguration verarbeiten.

Von der systemctl-Manpage:

daemon-reexec
       Reexecute the systemd manager. This will serialize the manager
       state, reexecute the process and deserialize the state again. This
       command is of little use except for debugging and package upgrades.
       Sometimes, it might be helpful as a heavy-weight daemon-reload.
       While the daemon is being reexecuted, all sockets systemd listening
       on behalf of user configuration will stay accessible.

Wenn in der Manpage steht, dass „daemon-reexec“ für Paketaktualisierungen verwendet wird, bedeutet das größtenteils, dass dieser Befehl jede neue Binärdatei ausführt und deren Konfiguration erneut verarbeitet. Allerdings enthält das RPM, das wir zum Upgrade von systemd verwenden, bereits ein Skript dafür, sodass es im Falle eines normalen Upgrades normalerweise nicht benötigt wird.

Oder Sie können neu starten. Beides funktioniert.

Mit anderen Worten, daemon-reexecdas Systemd-Verwaltungsprogramm wird erneut ausgeführt, die Systemkonfigurationsdatei wird erneut gelesen und daemon-reloadnur die Konfiguration des Serviceteils wird gelesen, mit Ausnahme der globalen Konfiguration /systemd/system.conf, die dem Schwergewicht entspricht daemon-reload.

Einzelne Dienständerung

Wenn Sie nur das Ressourcenlimit eines einzelnen Dienstes ändern, am Beispiel von Nginx, müssen Sie Folgendes bearbeiten /usr/lib/systemd/system/nginx.service:

Suchen Sie das [Dienstsegment] und fügen Sie die folgende Konfiguration hinzu

[Service]
LimitNOFILE=655360
LimitNPROC=655360

Führen Sie den folgenden Befehl aus und die Konfiguration wird sofort wirksam

# systemctl daemon-reload
# systemctl restart nginx.service

Guess you like

Origin blog.csdn.net/QTM_Gitee/article/details/127992049