Server lento per carico di sistema elevato


Hai un server che ospita più siti ma nessuno di questi si apre. Provi ad accedere tramite SSH ma il server è palesemente lento, poco reattivo e quasi ti fa passare la voglia di attendere sessanta secondi per vedere a video ogni carattere che digiti. Probabilmente il tuo VPS o server fisico ha un carico di lavoro troppo elevato, vediamo come capire quanto è grave la situazione e quali sono i processi che richiedono più risorse.

Ci tengo a precisare che un elevato carico di sistema su un webserver non è risolvibile seguendo una procedura standard in quanto può essere causato potenzialmente da migliaia di fattori (un attacco bruteforce su di un sito, una configurazione non adatta alle esigenze reali, problemi dal lato applicativo ecc.) e che la procedura per risolvere la problematica può variare in base ai servizi attivi sul server (Apache, Nginx, PHP, MySQL) e la loro configurazione.

Capire come leggere il load del server e quali sono i processi che utilizzano più risorse sono passi fondamentali da compiere verso la risoluzione del problema.

In questo articolo vedremo due cose:

  • Come leggere e interpretare il carico di sistema
  • Come capire quali processi richiedono più risorse

Load del server

Per capire se il rallentamento del server è da imputare ad un alto load di sistema il comando da dare è w, che non influisce particolarmente sulle performance della macchina.

Il comando w mostra in output l’ora del server, da quanto tempo il sistema è acceso, quanto è il load, gli utenti collegati e cosa stanno facendo:

domenico@server:~$ w
 19:36:24 up 92 days,  8:14,  1 user,  load average: 0,32, 0,19, 1,10
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
domenico pts/0    xx.90.104.xxx      19:25    0.00s  0.09s  0.00s w

Il carico del sistema nel momento in cui è stato digitato il comando w, nell’esempio sopra riportato, è il primo dei tre numeri in alto a destra (nell’esempio è 0,32). Il secondo numero indica il carico di sistema a cinque minuti dalla digitazione di w (0,19) e il terzo numero indica il carico a quindici minuti dalla digitazione del comando (1,10).

Per controllare il carico di sistema si può utilizzare anche il comando uptime che a differenza di w visualizza soltanto l’ora del server, da quanto tempo è online e il load avarage.

Ho utilizzato il comando w perché visualizza anche gli utenti connessi sul server, nel caso in cui ci fosse un accesso non autorizzato possiamo in questo modo immediatamente capirlo e agire di conseguenza.

È un eventualità molto remota, ma nel caso in cui ci fosse un accesso non autorizzato bisogna cambiare la password del sistema e terminare i processi aperti dall’utente malevolo come riportato più avanti.

Ovviamente, toccherà anche capire come è stato possibile che un utente non autorizzato abbia potuto effettuare l’accesso sul server. Ma questa è un’altra storia.

Come leggere il carico di sistema

Leggere il carico si sistema su Unix non è immediato come si può pensare, il modo più veloce per capire come interpretare il valore di load è un esempio pratico:

Supponiamo che il nostro VPS ha 2 vCPU, in questo caso il processore fino ad un carico di 2 processa le richieste che gli vengono fatte senza tempi di attesa.

Se il load di carico supera il valore di 2 vuol dire che i due processori sono occupati al 100% e a mano a mano che eseguono operazioni ne prendono subito in carico delle altre che erano già in attesa di essere processate.

Di conseguenza un valore di load di 16 su un sistema che ha 32 vCPU non è un valore preoccupante in quanto il sistema sta eseguendo tutte le operazioni richieste e sta utilizzando solo il 50% della potenza di calcolo disponibile, diversamente load di 16 su un sistema con solo 2 vCPU è estremamente elevato.

Ma quando bisogna preoccuparsi?

Prendendo sempre in considerazione il nostro VPS con 2 vCPU un load ancora “accettabile” è 6 o 8, al di sopra il sistema diventa palesemente lento e poco reattivo.

Se vogliamo usare una formula matematica per conoscere il load “accettabile” per un server potremmo definirla così:

Numero di processori * 3

Cosa non fare

Non farti passare per la mente di dare il comando htop per vedere quanto è il load del server, htop è un programma fantastico, ma per avviarsi utilizza parecchie risorse e non è per nulla una buona idea aprirlo se il sistema ha già un carico elevato.

Processi che occupano più risorse

Una volta appurato l’elevato carico di sistema bisogna capire da cosa è dovuto. Utilizzeremo per tale scopo il comando ps.

Il comando ps mostra a video tutti i processi attivi sul sistema, personalmente lo utilizzo sempre con queste opzioni aggiuntive.

ps wwauxf

w: Se specificata una volta sola, tronca le linee a 132 caratteri. Se specificata più volte, non tronca le linee.
a: Mostra anche i processi degli altri utenti, e non del solo utente che ha avviato ps.
u: Usa un formato con informazioni utili per l’analisi dell’utilizzo di risorse (memoria e CPU) dei processi.
x: Mostra anche i processi che non hanno un terminale controllante.
f: Visualizza le informazioni con un formato che le specifica tutte.

Dando ps wwauxf riceveremo in output una schermata simile a questa riportata di seguito:

utente1@vm01:~$ ps wwauxf
 USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
 ~~~~~~~~~~~~~~~~
 root         1  0.0  0.1 204532  6940 ?        Ss    2019   9:37 /sbin/init
 root       462  0.0  0.1  59236  5808 ?        Ss    2019   1:13 /lib/systemd/systemd-journald
 root       499  0.0  0.0  45700  3852 ?        Ss    2019   0:26 /lib/systemd/systemd-udevd
 systemd+   629  0.0  0.1 127284  4088 ?        Ssl   2019   0:34 /lib/systemd/systemd-timesyncd
 root       836  0.0  0.0  29664  2836 ?        Ss    2019   0:42 /usr/sbin/cron -f
 root       843  0.0  0.0 250112  3268 ?        Ssl   2019   0:08 /usr/sbin/rsyslogd -n
 root       851  0.0  0.1  46492  4680 ?        Ss    2019   4:09 /lib/systemd/systemd-logind
 root       859  0.0  0.1  69956  6120 ?        Ss    2019   0:00 /usr/sbin/sshd -D
 root     18222  0.0  0.1  95212  6732 ?        Ss   12:06   0:00  _ sshd: utente1 [priv]
 utente1 18229  0.0  0.1  95212  4096 ?        S    12:06   0:00      _ sshd: utente1@pts/0
 utente1 18230  0.0  0.1  20980  4800 pts/0    Ss   12:06   0:00          _ -bash
 utente1 18331  0.0  0.0  38448  3340 pts/0    R+   12:14   0:00              _ ps wwauxf
 root       863  0.0  0.0  14300  2036 ttyS0    Ss+   2019   0:00 /sbin/agetty --keep-baud 115200,38400,9600 ttyS0 vt220
 root       865  0.0  0.0  14524  1632 tty1     Ss+   2019   0:00 /sbin/agetty --noclear tty1 linux
 Debian-+  1111  0.0  0.0  56156  3172 ?        Ss    2019   0:06 /usr/sbin/exim4 -bd -q30m
 root      3926  0.1  1.0 579724 42672 ?        Ssl   2019 114:33 /usr/bin/containerd
 mysql     5845  0.1  5.5 683540 220612 ?       Ssl   2019 124:13 /usr/sbin/mysqld
 utente1 21044  0.0  0.1  64852  6164 ?        Ss    2019   0:00 /lib/systemd/systemd --user
 utente1 21045  0.0  0.0 230056  1764 ?        S     2019   0:00  _ (sd-pam)
 root     21267  0.0  0.2 126804  8428 ?        Ss    2019   0:00 dirmngr --daemon --homedir /tmp/tmpafmuvhwd
 root     24060  0.0  0.7 433008 29568 ?        Ss    2019   8:36 php-fpm: master process (/etc/php/7.3/fpm/php-fpm.conf)
 federic+ 18330  5.6  1.3 446908 53252 ?        S    12:14   0:00  _ php-fpm: pool utente1sito.com
 root     27004  0.0  0.0 164280  2036 ?        Ss    2019   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
 www-data 27005  0.0  0.2 164876  9296 ?        S     2019   5:36  _ nginx: worker process
 www-data 27007  0.0  0.2 164816  9328 ?        S     2019   5:58  _ nginx: worker process
 utente1@vm01:~$

Ci sarebbe molto da scrivere, ma ci limiteremo ad analizzare soltanto i campi principali di questo output:

USER: Indica l’utente che ha inizializzato il processo.

PID: Indica che Process ID ha il processo. (maggiori info qui https://it.wikipedia.org/wiki/PID_(Unix))

%CPU: Indica quale è la percentuale di CPU utilizzata dal processo

%MEM: Indica la percentuale di memoria RAM utilizzata dal processo

STAT: Indica in che stato versa il processo di seguito la descrizione degli stati dal man del comando

PROCESS STATE CODES
       Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process:
       D    uninterruptible sleep (usually IO)
       R    running or runnable (on run queue)
       S    interruptible sleep (waiting for an event to complete)
       T    stopped, either by a job control signal or because it is being traced.
       W    paging (not valid since the 2.6.xx kernel)
       X    dead (should never be seen)
       Z    defunct ("zombie") process, terminated but not reaped by its parent.

       For BSD formats and when the stat keyword is used, additional characters may be displayed:
       <    high-priority (not nice to other users)
       N    low-priority (nice to other users)
       L    has pages locked into memory (for real-time and custom IO)
       s    is a session leader
       l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
       +    is in the foreground process group.

START: orario in cui è stato avviato il processo

TIME: da quanto tempo il processo è attivo

COMMAND: che comando sta eseguendo il processo

Con queste informazioni siamo in grado di capire quali sono i processi che occupano più risorse e iniziare la risoluzione vera e propria del/dei problemi.