Risoluzione dei problemi relativi a carichi elevati sui server Linux

Dopo aver letto le basi dell’ottimizzaione di WordPress su cPanel, vediamo alcuni passaggi avanzati. Questi suggerimenti richiedono una conoscenza più approfondita del file system dell’installazione di WordPress e del database su cui opera.

Difficilmente la causa di elevati carichi sui server è da collegare a difetti nel software cPanel o nelle applicazioni che installa. I carichi elevati del server sono oggetto di osservazione da parte dell’amministratore di sistema o dal provider di servizi.

Cosa causa carichi elevati del server?

L’uso eccessivo di uno dei seguenti elementi può in genere causare questo problema:

  • processore
  • memoria (incluso scambio)
  • disco I/O

Come posso controllare questi elementi?

Dipende se si desidera rivedere l’utilizzo corrente delle risorse o l’utilizzo storico delle risorse.

Una breve lezione sull’uso storico delle risorse “sar” può essere visualizzata utilizzando l’utilità “sar”, che per impostazione predefinita è su tutti i server cPanel.

Le statistiche vengono raccolte quando sysstat viene eseguito da cron (/etc/cron.d/sysstat), ma se crond non è in esecuzione, sysstat non sarà in grado di raccogliere statistiche storiche.

Per visualizzare le cronologie di utilizzo delle risorse da sar, è necessario fornire il percorso del file che corrisponde alla data delle statistiche.

Ad esempio, se desideri visualizzare le medie di carico per il tuo server dal 23 del mese, dovresti eseguire questo comando:

[user@host ~]$ sar -q -f /var/log/sa/sa23

Il comando sopra usa -q per ottenere le informazioni sulla media del carico e -f per specificare da quale file sar ottenere le informazioni. Nota che sar potrebbe non avere dati storici che risalgono a più di una settimana fa.

Non è necessario specificare la data quando si visualizzano le statistiche per il giorno corrente. Pertanto, questo comando mostrerebbe il carico medio per oggi:

[user@host ~]$ sar -q

Si consiglia vivamente di leggere la documentazione per sar:

[user@host ~]$ man sar

Fornisce statistiche per molte cose che possono essere utili da conoscere.

Utilizzo corrente della CPU

Esegui “top” e sulla riga che dice “Cpu(s)”, controlla la sezione “%id” che mostra la percentuale di cui le tue CPU sono inattive. Più alto è il numero, meglio è. Una CPU inattiva al 99% non sta facendo molto di nulla e una CPU inattiva all’1% è pesantemente impegnata.

[user@host ~]$ top c

Suggerimento: premi “P” per ordinare in base ai processi che attualmente consumano più CPU.

Utilizzo storico della CPU

Controlla la colonna “%idle”:

[user@host ~]$ sar -p

Utilizzo corrente della memoria

[user@host ~]$ free -m

Suggerimento: esegui “top c” e premi “M” per vedere quali processi consumano più memoria.

Utilizzo storico della memoria

Questo dipende dalla versione di sar, che usava ‘-r’ per mostrare %memused e %swpused (memoria di scambio usata), ma successivamente cambiato in ‘-S’ per mostrare %swpused.

Controlla “%memused” e “%swpused”:

[user@host ~]$ sar -r

oppure:

[user@host ~]$ sar -S

Una nota sull’utilizzo della memoria: è normale vedere che gran parte della memoria del server viene utilizzata. Perché? Perché il sistema operativo ama memorizzare nella cache le cose. Perché l’accesso ai dati dalla memoria è estremamente veloce e molto più efficiente rispetto all’utilizzo dei dischi del server.

In quanto tale, %memused generalmente non sarà un grosso problema (a meno che forse non si disponga di una partizione di swap, ma questo è un problema in sé e per sé). Dovresti concentrarti su %swpused, che è ciò che viene utilizzato quando la memoria fisica del tuo server è piena. Più basso è il numero, meglio è. Una percentuale %swpused dello 0% significherebbe che il tuo server ha attualmente memoria fisica sufficiente per eseguire le sue attività.

Quanto %swpused è troppo? Dipende dalla tua opinione di “troppo”. In generale, una percentuale bassa e costante di utilizzo dello swap potrebbe non essere un problema sul tuo server. Se osservi %swpused aumentare nel tempo (ad esempio, dall’1%, al 7%, al 32%), qualcosa sul tuo server sta consumando troppa memoria, e sarebbe saggio determinare di cosa si tratta (piuttosto che installare semplicemente più memoria). Se il tuo server finisce per utilizzare tutta la sua memoria fisica e la memoria di scambio, potrebbe non rispondere, richiedendo un riavvio.

Utilizzo corrente di I/O su disco

Nota: questo non funziona sui container OpenVZ/Virtuozzo.

Questo stamperà le statistiche sull’utilizzo del disco 10 volte, ogni 1 secondo. Controlla la colonna %util:

[user@host ~]$ iostat -x 1 10

Cronologia utilizzo I/O su disco

[user@host ~]$ sar -d

Una buona amministrazione del sistema implica sapere quando il carico del server è superiore a quello accettabile. Il motivo principale di ciò (oltre a impedire al server di non rispondere e richiedere un riavvio) è vedere cosa sta accadendo sul server mentre il carico è elevato . Azioni rapide ti consentiranno di risolvere il problema mentre si verifica.

Se il carico del tuo server fosse alto dalle 2:00 alle 4:00 mentre stavi dormendo, ti saresti perso quello che è successo. Mentre sar può essere utile per mostrarti quali risorse specifiche erano alte durante quel periodo, non ti dirà la causa dell’alto consumo. Le cause possono essere molte, inclusi attacchi DoS, attacchi spam, script php progettati male che consumano grandi quantità di memoria, web spider che scansionano i siti in modo troppo aggressivo, problemi hardware, enormi quantità di scritture su disco nel database MySQL di un utente e molto, molto di più.

La buona notizia è che puoi raccogliere e inviare automaticamente molte di queste informazioni mentre il carico è elevato, che puoi rivedere in seguito se necessario. Come? Dal tuo elenco di processi:

[user@host ~]$ ps auxwwwf

Ho creato uno script di shell per questo, che si basa su uno script perl che ho usato per eseguire sui server che ho gestito. Mi è stato molto utile in combinazione con il monitoraggio di altri server (come tramite Nagios). Controlla 6 cose diverse e ti invia un’e-mail con l’elenco dei processi correnti se qualcuno di essi supera la soglia specifica.

Questo script non è sviluppato, mantenuto o supportato da cPanel, Inc. Non aprire ticket su questo script. Se riscontri problemi durante l’utilizzo e richiedi assistenza, puoi inviare una risposta qui o consultare un amministratore di sistema esperto. cPanel non può fornire supporto per questo script.

Le risorse controllate sono le seguenti:

  • 1 minuto di carico medio
  • kilobyte di swap utilizzati
  • kilobyte di utilizzo della memoria
  • pacchetti al secondo in entrata
  • pacchetti al secondo in uscita
  • numero di processi

Come usare lo script

Per eseguire lo script automaticamente, imposta un cron job che lo esegua tutte le volte che vuoi. Ho trovato ogni 5 minuti per essere una buona misura. Lo script non deve essere eseguito come root, quindi non eseguirlo come root.

Se una delle risorse ha superato la soglia definita dall’utente, lo script invierà un messaggio di posta elettronica che contiene l’elenco dei processi correnti (ps auxwwwf).

La riga dell’oggetto dell’e-mail sarà simile a questa:

server.example.com [L: 35] [P: 237] [Swap Use: 1% ] [pps in: 54  pps out: 289]

Ciascuno di questi elementi è spiegato come segue:

  • L – il carico medio di 1 minuto
  • P – il numero di processi nell’elenco dei processi
  • Utilizzo swap: la percentuale di memoria swap utilizzata
  • pps in – pacchetti al secondo in entrata
  • pps out – pacchetti al secondo in uscita

Prima di utilizzare lo script

IMPORTANTE: sarà necessario regolare i valori a proprio piacimento. Non esistono valori predefiniti perfetti. Perché? Perché diversi ambienti server sono, beh, diversi. Ad esempio, potrebbe essere preferibile impostare la soglia media di carico di 1 minuto più alta per un server con 16 core CPU rispetto a un server con solo 1.

NOTA: sarà necessario aggiungere il proprio indirizzo e-mail alla variabile “EMAIL”. Per esempio:

EMAIL="you@example.com"

Probabilmente vorrai anche modificare i seguenti 5 elementi:

  • CARICO MASSIMO
  • MAX_SWAP_USED
  • MAX_MEM_USATO
  • MAX_PPS_OUT
  • MAX_PPS_IN
#!/bin/sh

export PATH=/bin:/usr/bin

##########################################################################
#                                                                        #
#  Copyright Jeff Petersen, 2009 - 2013                                  #
#                                                                        #
#  This program is free software: you can redistribute it and/or modify  #
#  it under the terms of the GNU General Public License as published by  #
#  the Free Software Foundation, either version 3 of the License, or     #
#  (at your option) any later version.                                   #
#                                                                        #
#  This program is distributed in the hope that it will be useful,       #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#  GNU General Public License for more details.                          #
#                                                                        #
#  You should have received a copy of the GNU General Public License     #
#  along with this program.  If not, see <http://www.gnu.org/licenses/>. #
#                                                                        #
##########################################################################


###############################################################################
# START USER CONFIGURABLE VARIABLES
###############################################################################

EMAIL="you@example.com"

# 1 minute load avg
MAX_LOAD=3

# kB
MAX_SWAP_USED=1000

# kB
MAX_MEM_USED=500000

# packets per second inbound
MAX_PPS_IN=2000

# packets per second outbound
MAX_PPS_OUT=2000

# max processes in the process list
MAX_PROCS=400

###############################################################################
# END USER CONFIGURABLE VARIABLES
###############################################################################


IFACE=`grep ETHDEV /etc/wwwacct.conf | awk '{print $2}'`
if [[ "$IFACE" =~ "venet" ]] ; then
    IFACE=venet0
fi

IFACE=${IFACE}:

###############################################################################
# 1 min load avg
###############################################################################
ONE_MIN_LOADAVG=`cut -d . -f 1 /proc/loadavg`
echo "1 minute load avg: $ONE_MIN_LOADAVG"


###############################################################################
# swap used
###############################################################################
SWAP_TOTAL=`grep ^SwapTotal: /proc/meminfo | awk '{print $2}'`
SWAP_FREE=`grep ^SwapFree: /proc/meminfo | awk '{print $2}'`

let "SWAP_USED = (SWAP_TOTAL - SWAP_FREE)"
echo "Swap used: $SWAP_USED kB"


###############################################################################
# mem used
###############################################################################
MEM_TOTAL=`grep ^MemTotal: /proc/meminfo | awk '{print $2}'`
MEM_FREE=`grep ^MemFree: /proc/meminfo | awk '{print $2}'`

let "MEM_USED = (MEM_TOTAL - MEM_FREE)"
echo "Mem used: $MEM_USED kB"


###############################################################################
# packets received
###############################################################################
PACKETS_RX_1=`grep $IFACE /proc/net/dev | awk '{print $2}'`
sleep 2;
PACKETS_RX_2=`grep $IFACE /proc/net/dev | awk '{print $2}'`

let "PACKETS_RX = (PACKETS_RX_2 - PACKETS_RX_1) / 2"
echo "packets received (2 secs): $PACKETS_RX"


###############################################################################
# packets sent
###############################################################################
PACKETS_TX_1=`grep $IFACE /proc/net/dev | awk '{print $10}'`
sleep 2;
PACKETS_TX_2=`grep $IFACE /proc/net/dev | awk '{print $10}'`

let "PACKETS_TX = (PACKETS_TX_2 - PACKETS_TX_1) / 2"
echo "packets sent (2 secs): $PACKETS_TX"

let "SWAP_USED = SWAP_TOTAL - SWAP_FREE"
if [ ! "$SWAP_USED" == 0 ] ; then
    PERCENTAGE_SWAP_USED=`echo $SWAP_USED / $SWAP_TOTAL | bc -l`
    TOTAL_PERCENTAGE=`echo ${PERCENTAGE_SWAP_USED:1:2}%`
else
    TOTAL_PERCENTAGE='0%'
fi


###############################################################################
# number of processes
###############################################################################
MAX_PROCS_CHECK=`ps ax | wc -l`

send_alert()
{
    SUBJECTLINE="`hostname` [L: $ONE_MIN_LOADAVG] [P: $MAX_PROCS_CHECK] [Swap Use: $TOTAL_PERCENTAGE ] [pps in: $PACKETS_RX  pps out: $PACKETS_TX]"
    ps auxwwwf | mail -s "$SUBJECTLINE" $EMAIL
    exit
}


if   [ $ONE_MIN_LOADAVG -gt $MAX_LOAD      ] ; then send_alert
elif [ $SWAP_USED       -gt $MAX_SWAP_USED ] ; then send_alert
elif [ $MEM_USED        -gt $MAX_MEM_USED  ] ; then send_alert
elif [ $PACKETS_RX      -gt $MAX_PPS_IN    ] ; then send_alert
elif [ $PACKETS_TX      -gt $MAX_PPS_OUT   ] ; then send_alert
elif [ $MAX_PROCS_CHECK -gt $MAX_PROCS ] ; then send_alert
fi

Si noti che l’output dell’elenco dei processi contiene diverse colonne utili relative all’utilizzo della CPU e della memoria per ciascun processo:

  • %PROCESSORE
  • %MEM
  • VSZ
  • Rss
  • TIME (mostra da quanto tempo esiste un processo)

Ci sono varie azioni che puoi intraprendere per trovare la causa degli alti carichi del tuo server. Ecco un elenco parziale che sarà sempre incompleto:

  • Controlla l’elenco dei processi MySQL usando “mysqladmin processlist” (o semplicemente “mysqladmin pr” in breve)
  • Controlla l’elenco dei processi MySQL usando mytop
  • coda i tuoi registri! Ascoltare ciò che dice il tuo server è molto importante. Il tuo server è sottoposto a forzatura bruta?
  • Esegui dmesg e controlla eventuali problemi hardware
  • Usa netstat per visualizzare le connessioni al tuo server

Ecco alcuni log da controllare:

  • syslogs: /var/log/messages, /var/log/secure
  • Registri SMTP: /var/log/exim_mainlog, /var/log/exim_rejectlog, /var/log/exim_paniclog
  • Registri POP3/IMAP: /var/log/maillog
  • Log di Apache: /usr/local/apache/logs/access_log, /usr/local/apache/logs/error_log, /usr/local/apache/logs/suexec_log, /usr/local/apache/logs/suphp_log
  • Registri del sito web: /usr/local/apache/domlogs/ (usalo per trovare siti con traffico negli ultimi 60 secondi: find -maxdepth 1 -type f -mmin -1 | egrep -v ‘offset|_log$’)
  • registri cron: /var/log/cron
Elemento aggiunto al carrello.
0 items - 0,00