Como o título da pergunta sugere, estou tendo dificuldades para descobrir o que pode ser melhorado no meu aplicativo (ou sintonizado no sistema operacional ubuntu) para obter um desempenho aceitável. Mas primeiro vou explicar a arquitetura:
O servidor front-end é uma máquina de 8 núcleos com 8 GB de RAM executando o Ubuntu 12.04. O aplicativo é gravado inteiramente em javascript e executado no node.js v 0.8.22 (como alguns módulos parecem reclamar em versões mais recentes do nó) eu uso o nginx 1.4 para proxy do tráfego http das portas 80 e 443 a 8 trabalhadores de nó gerenciados e começou a usar a API do cluster de nós. Eu uso a versão mais recente do socket.io 0.9.14 para lidar com as conexões do websocket, nas quais habilitei apenas websockets e xhr-polling como transportes disponíveis. Nesta máquina, também executo uma instância do Redis (2.2)
Eu armazeno dados persistentes (como usuários e pontuações) em um segundo servidor no mongodb (3.6) com 4gigs de RAM e 2 núcleos.
O aplicativo está em produção há alguns meses (está sendo executado em uma única caixa até algumas semanas atrás) e está sendo usado por cerca de 18 mil usuários por dia. Sempre funcionou muito bem além de um problema principal: degradação do desempenho. Com o uso, a quantidade de CPU usada por cada processo aumenta até que ele estatura o trabalhador (que não atende mais a solicitações). Resolvi-o temporariamente, verificando a cpu em uso por cada trabalhador a cada minuto e reiniciando-a se atingir 98%. Portanto, o problema aqui é principalmente CPU, e não RAM. A RAM não é mais um problema, pois eu atualizei para o socket.io 0.9.14 (a versão anterior estava com vazamento de memória), por isso duvido que seja um problema de vazamento de memória, principalmente porque agora é a CPU que cresce rapidamente ( Eu tenho que reiniciar cada trabalhador cerca de 10 a 12 vezes por dia!). A RAM em uso também cresce para ser honesto, mas bem devagar, 1 show a cada 2-3 dias de uso, e o mais estranho é que ele não é lançado, mesmo quando eu reinicio completamente o aplicativo. Só é lançado se eu reiniciar o servidor! isso eu realmente não consigo entender ...
Agora eu descobri o que é incrível, então finalmente posso ver o que está acontecendo no meu servidor de produção e coleto dados há alguns dias. Se alguém quiser ver os gráficos, posso dar acesso, mas basicamente vejo que tenho entre 80 e 200 conexões simultâneas! Eu esperava que o node.js manipulasse milhares, não centenas de solicitações. Além disso, o tempo médio de resposta para o tráfego http varia entre 500 e 1500 milissegundos, o que eu acho realmente muito. Além disso, neste exato momento, com 1300 usuários on-line, esta é a saída de "ss -s":
Total: 5013 (kernel 5533)
TCP: 8047 (estab 4788, closed 3097, orphaned 139, synrecv 0, timewait 3097/0), ports 0
Transport Total IP IPv6
* 5533 - -
RAW 0 0 0
UDP 0 0 0
TCP 4950 4948 2
INET 4950 4948 2
FRAG 0 0 0
o que mostra que tenho muitas conexões fechadas em tempo de espera. Aumentei o máximo de arquivos abertos para 999999, eis a saída do ulimit -a:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 63724
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 999999
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 63724
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Por isso, pensei que o problema poderia estar no tráfego http que, por alguns motivos, satura as portas / soquetes disponíveis (?), Mas uma coisa não faz sentido para mim: por que, quando reinicio os trabalhadores e todos os clientes se reconectam em poucos segundos, a carga no processador do trabalhador diminui para 1% e é capaz de atender a solicitações corretamente até saturar após cerca de 1 hora (no horário de pico)?
Sou principalmente um programador de javascript, não um administrador de sistemas, por isso não sei quanta carga devo esperar para lidar com meus servidores, mas certamente não está funcionando como deveria. Caso contrário, a aplicação é estável e esse último problema está me impedindo de enviar as versões móveis do aplicativo que estão prontas, pois obviamente elas trarão mais carga e eventualmente travarão a coisa toda!
Espero que haja algo óbvio que eu esteja fazendo errado, e alguém ajude a identificá-lo ... sinta-se à vontade para me pedir mais informações e desculpe-me pela duração da pergunta, mas acredito que seja necessário ... desde já, obrigado!
top
quando o uso da CPU é próximo de 100%?