180 Zeilen C-Code zur Implementierung des Epoll-Echo-Servers
350 Zeilen C-Code zur Implementierung des Epoll-Reaktormodells
C1000K
Zweck
Testen Sie, ob der Single-Threaded-Reaktor Millionen von Verbindungen unterstützen kann.
1 Verbindung wird durch ein 5-Tupel eindeutig identifiziert:
- local_ip
- local_port
- peer_ip
- peer_port
- Protokoll
Der Standard-Portbereich von Ubuntu-1604 ist bekanntermaßen: 32768-60999
Angenommen, der Client verfügt über 20.000 verfügbare Ports, der Server öffnet 100 Ports und es werden 2 Clients verwendet Um eine Verbindung zum Server herzustellen, beträgt die theoretische maximale Anzahl von Verbindungen: 20000 x 100 x 2 = 4 Millionen.
Codeänderung
Basierend auf350 Zeilen C-Code zur Implementierung des Epoll-Reaktormodells öffnet der Server 100 Überwachungsports.
Github-vollständiger Code
Konfiguration der virtuellen Maschine
PC-Hardware: I5-9400 6 Kerne, 16G Speicher
Bereiten Sie 3 virtuelle Maschinen (Ubuntu-1604) vor, 1 als Server und 2 als Clients.
Serverkonfiguration: 6G Speicher, CPU 2 Prozessoren 1 Kern
Clientkonfiguration: 3G Speicher, CPU 1 Prozessor 2 Kerne
Speicherbedarf
Um zu vermeiden, dass das Programm aufgrund von unzureichendem Speicher beendet wird, stellen Sie sicher, dass ausreichend Speicher vorhanden ist.
Das Folgende sind nur geschätzte Maximalwerte, die ich getestet habe und die eigentlich nicht so viel Speicher erfordern.
Der verfügbare Speicher des Servers beträgt mehr als 4G
Der verfügbare Speicher des Clients beträgt mehr als 3G
Ich habe a ausgewählt Sauberere virtuelle Maschine für den Client. Sie benötigt nur 200 MB Speicher. Sie können N Kopien entsprechend Ihrer tatsächlichen Situation klonen. Je mehr Clients Sie öffnen, desto schneller werden 1000.000 Verbindungen ausgeführt. Mein Server belegte zunächst 2,3 GB, daher wurden ihm 6 GB zugewiesen.
Ändern Sie die Kernel-TCP-Parameter
Server-Systemeinstellungen
sudo vim /etc/sysctl.conf
Hinzufügen zu:
net.ipv4.tcp_mem = 524288 1048576 1572864
net.ipv4.tcp_wmem = 512 512 1024
net.ipv4.tcp_rmem = 512 512 1024
fs.file-max = 2000000
net.nf_conntrack_max = 2000000
fs.nr_open=2000000
sudo modprobe ip_conntrack
sudo sysctl –p
Client-Systemeinstellungen
sudo vim /etc/sysctl.conf
Hinzufügen zu:
net.ipv4.tcp_mem = 262144 524288 1048576
net.ipv4.tcp_wmem = 256 256 512
net.ipv4.tcp_rmem = 256 256 512
fs.file-max = 2000000
net.nf_conntrack_max = 2000000
fs.nr_open=2000000
sudo modprobe ip_conntrack
sudo sysctl –p
Parametererklärung
- Die Einheit von tcp_mem ist Seite, der Standardwert ist 4 KB
- Oben ist der maximale Wert der Kernel-TCP-Speicherseite des Servers auf 1572864 (6G-Speicher) und der des Clients auf 1048576 (4G-Speicher) festgelegt.
- Die Einheiten von tcp_wmem und tcp_rmem sind Bytes. Durch Verringern des Werts wird weniger Speicher beansprucht. Der Server legt den Mindestwert 512 fest und der Client legt den Mindestwert 256 fest. Es sollte nach dem Testen auskommentiert werden, um Probleme wie einen zu kleinen Puffer und einen Ausfall der SSH-Verbindung zu vermeiden.
- Wenn die Anzahl der geöffneten Dateien 1048576 überschreitet, muss zuerst fs.nr_open festgelegt werden, andernfalls ist die unten stehende Einstellung von limits.conf ungültig.
Ändern Sie die maximale Anzahl von FDS in einem Prozess (ulimit).
sudo vim /etc/security/limits.conf
Fügen Sie abschließend 4 Zeilen hinzu:
* soft core unlimited
* soft stack 12000
* soft nofile 2000000
* hard nofile 2000000
Parametererklärung
- Mehrere Parameter mit einem Wert von 2.000.000 sorgen dafür, dass die theoretische maximale Anzahl an Verbindungen 2 Millionen erreichen kann.
- stack legt die maximale Kapazität des Stacks in KB fest. 2 Millionen Verbindungen werden 2 Clients zugewiesen, und 1 Client entspricht 1 Million. Die Struktur epoll_event belegt 12 Bytes, 12x1 Million = 12 Millionen = 12000 KB. Stellen Sie den Stapel daher auf 12000 ein
kompilieren
machen
Server ausführen
./Server
Client ausführen
./client server_ip server_first_port
- server_first_port Der Server öffnet 100 Ports, der Standard-Portbereich ist 9900-9999, also ist server_first_port 9900
Testergebnisse
In der folgenden Abbildung ist 191.7 der Server und 191.20 und 191.21 die Clients.
Bei Erreichen von 1 Million Verbindungen belegt der Server 4,86 GB Speicher und der Client 1,4 GB Speicher. Wenn man den Anfangswert abzieht, belegt der Server etwa 2,6 GB und der Client etwa 1,2 GB.
Der Server wurde abgeschaltet, als es 1,15 Millionen Verbindungen gab.
Speichernutzung nach Rückkehr zum Normalzustand. Sie können sehen, dass der Server 2,1 GB und der Client etwa 200 MB belegt.
Protokollausgabe von /var/log/syslog nach dem Beenden des Servers, nicht genügend Arbeitsspeicher