News: Faz alguns dias que este blog está rodando em um VPS que aluguei na slicehost. Em um primeiro momento fiz a instalação Lamp padrão, contudo isso resultou em um pequeno inconveniente, consumo excessivo de memória ram:
# Consumo de memória com apache
mysql + apache2 rodando wordpress = 165 mb ram
Considerando que meu VPS tem apenas 256 mb de ram resolvi trocar o apache pelo nginx, o resultado foi bem agradável:
# Consumo de memória com nginx
mysql + fcgi + nginx rodando wordpress = 65 mb ram
O processo de instalação foi extremamente simples, e as configurações custaram alguns poucos momentos no google.
# Pacotes necessários:
apt-get install nginx mysql-server php5 php5-cgi php5-mysql spawn-fcgi
Arquivo de configuração do domínio no nginx
cat /etc/nginx/sites-enabled/tarzxvf.com
server {
listen 80;
server_name tarzxvf.com www.tarzxvf.com;
access_log /var/log/nginx/tarzxvf.com.access.log;
location / {
root /var/www/tarzxvf.com;
index index.html index.htm index.php;
# this move feed requests to feedburner
if ($http_user_agent !~ FeedBurner) {
rewrite ^/feed/ http://feeds.feedburner.com/tarzxvf last;
}
# this serves static files that exist without running other rewrite tests
if (-f $request_filename) {
expires 30d;
break;
}
# this sends all non-existing file or directory requests to index.php
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q=$1 last;
}
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/tarzxvf.com/$fastcgi_script_name;
include fastcgi_params;
}
}
Arquivo de inicialização do fcgi
cat /etc/init.d/spawn-fcgi
#! /bin/sh
### BEGIN INIT INFO
# Provides: spawn-fcgi-php
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts FastCGI for PHP
# Description: starts FastCGI for PHP using start-stop-daemon
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=spawn-fcgi-php
PID=/var/run/spawn-fcgi-php.pid
DAEMON=/usr/bin/spawn-fcgi
DAEMON_OPTS="-f /usr/bin/php-cgi -a 127.0.0.1 -p 9000 -u www-data -g www-data -P $PID"
test -x $DAEMON || exit 0
set -e
case "$1" in
start)
echo "Starting $NAME: "
start-stop-daemon --start --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS
echo "done."
;;
stop)
echo "Stopping $NAME: "
start-stop-daemon --stop --pidfile $PID --retry 5
rm -f $PID
echo "done."
;;
restart)
echo "Stopping $NAME: "
start-stop-daemon --stop --pidfile $PID --retry 5
rm -f $PID
echo "done..."
sleep 1
echo "Starting $NAME: "
start-stop-daemon --start --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS
echo "done."
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|restart}" >&2
exit 1
;;
esac
exit 0
Título alternativo: How to get CPU usage per core with python
Teste de indexação do google
Mais um post para a série “Parseando o /proc” [1]. Dessa vez sem motivo explícito, apenas diversão!
Ambientes de testes:
Comparei os resultados através do htop e obtive uma proximidade alta nos valores, as diferenças se dão provavelmente pelo momento e duração da medição!
Quem puder testar em ambientes com mais núcleos ou uso intensivo da CPU e comparar com as ferramentas do sistema por favor me de um feedback
E quem rir da qualidade do meu inglês nos comentários eu vou banir o ip!
#!/usr/bin/env python import time import os # [ reference ] # Detect number of cpus # http://www.boduch.ca/2009/06/python-cpus.html # Get cpu usage (But this example is not working 100%) # http://ubuntuforums.org/showpost.php?p=853257&postcount=4 INTERVAL = 2 class CPUUsage: def __init__(self): self.cores = self.detectCPUs() def createCoreArray(self): cores = [] for i in range(self.cores): cores.append("") return cores def detectCPUs(self): if hasattr(os, "sysconf"): if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"): ncpus = os.sysconf("SC_NPROCESSORS_ONLN") if isinstance(ncpus, int) and ncpus > 0: return ncpus return 1 # Default def getTimeList(self): core = self.createCoreArray() statFile = file("/proc/stat", "r") if not self.cores == 1: statFile.readline() # this FOR will split lines from proc/stat for every active core for cid in range(self.cores): # when have just one core, split a different range if self.cores == 1: core[cid] = statFile.readline().split(" ")[2:7] # 2:6 else: core[cid] = statFile.readline().split(" ")[1:6] # 1:5 statFile.close() # convert all itens in splited list from STR to INT for every core for i in range(len(core[0])): for cid in range(self.cores): core[cid][i] = int(core[cid][i]) # return the core list now with INT values inside their cpu values # like this: ([core,1,values],[core,2,values],[core,3,values]) return core def deltaTime(self,interval): coreT1=self.createCoreArray() coreT2=self.createCoreArray() # get core TIME 1 state per core coreT1 = self.getTimeList() # wait X seconds to get new state core time.sleep(interval) # get core TIME 2 state per core coreT2 = self.getTimeList() #Get the diference of coreT2.item[i] and coreT1.item[i] for every core for i in range(len(coreT1[0])): for cid in range(self.cores): coreT2[cid][i] -= coreT1[cid][i] return coreT2 def Usage(self): core = self.createCoreArray() cpuUsage = [] core = self.deltaTime(INTERVAL) for cid in range(self.cores): # sum of user,system and nice usage tmp_use = core[cid][0] + core[cid][1]+core[cid][2] # 100.00 * usage / sum of usage + idle + waiting usage = "%.2f" % ((100.00 * tmp_use) / sum(core[cid])) cpuUsage.append(usage) return cpuUsage if __name__ == "__main__": # Show usage per core #print CPUUsage().Usage() x = 0 for item in CPUUsage().Usage(): x = x + 1 print "CPU[%s]: %s" % (str(x),str(item)) |
OK, então você usa linux e conhece o ‘top‘, item básico no repertório de qualquer sysadmin, que permite acompanhar algumas informações sobre a carga do sistema e processos. Essa ferramenta antiga e poderosa, é de uma idéia tão simples porem tão prática, que ganhou um termo para designar ferramentas semelhantes, ferramentas “top-like“.
Para se enquadrar em uma ferramenta top-like o candidato tem que:
Fiz uma lista com 16 ferramentas top-like disponíveis no Ubuntu 9.04. Enquanto fazia a pesquisa, encontrei pelo menos mais meia dúzia sem pacotes para o ubuntu, e se for considerar as que eu não encontrei esse número deve subir consideravelmente.
Esse meme está rolando em muitos planetas. Fiquei curioso e resolvi brincar!
Aí está o resultado.

Na tarde de sábado eu precisava pegar as portas abertas no servidor, da forma mais Real Time possível. Primeira idéia? Naturalmente, foi parsear o resultado do netstat e ‘grepar’ o LISTEN ou OUÇA, mas depois imaginei que beber diretamente da fonte pudesse fazer o negócio andar mais rápido. Pesquisa daqui, pesquisa dali, aparentemente o netstat pega suas informações dos arquivos em /proc/net.
Após umas horinhas consegui o protótipo inicial do código que preciso. Mas durante a caminhada perdi o foco e acabei brincando um pouco mais com o /proc/net/tcp, no fim tinha um netstat simplificado feito em Python.
Então se alguém algum dia precisar recuperar informações de conexões ao estilo netstat aí está o código:
#!/usr/bin/python # Criado por Ricardo Pascal, qualquer dúvida ou # contribuição mande para 'pascal.linux' no gmail! # Pode usar a vontade só lembre-se de citar a autoria ;) # Agradecimento ao pessoal do #python-br na freenode. # A galera lá sempre ajuda. PROC_TCP = "/proc/net/tcp" STATE = { '01':'ESTABLISHED', '02':'SYN_SENT', '03':'SYN_RECV', '04':'FIN_WAIT1', '05':'FIN_WAIT2', '06':'TIME_WAIT', '07':'CLOSE', '08':'CLOSE_WAIT', '09':'LAST_ACK', '0A':'LISTEN', '0B':'CLOSING' } tcp_FH = open(PROC_TCP,'r') content = tcp_FH.readlines() content.pop(0) # remove header tcp_FH.close() def hex2dec(s): return int(s,16) def ip(s): return str(hex2dec(s[6:8])) +"."+ str(hex2dec(s[4:6])) +"."+ \ str(hex2dec(s[2:4])) +"."+ str(hex2dec(s[0:2])) def remove_empty(list): return [x for x in list if x !=''] def get_list(c): result = [] result.append(['ID','IP','PORT','rIP','rPORT','STATS']) for lines in content: line_array = remove_empty(lines.split(' ')) line = [line_array[0], line_array[1].split(':'), \ line_array[2].split(":"),line_array[3]] line = [line[0], ip(line[1][0]), hex2dec(line[1][1]), \ ip(line[2][0]), hex2dec(line[2][1]), STATE[(line[3])]] result.append(line) return result if __name__ == '__main__': for lines in get_list(content): print lines |
PS. Quando eu tiver tempo eu refaço a cama de gato que ta ali na função get_list() e ip().
- SimpleHTTPServer
- BaseHTTPServer
- wsgi
- WebOb
- Aspen
- PEP:333
- Olha que legal, basicamente o meu problema!!
- Static (Olha que legal, basicamente resolve o meu problema!!)
- Albatross
- Spyce
- CherryPY e/ou StandaloneWSGI Server
Imagino que no final vou acabar usando o Standalone WSGI Server (engine do CherryPy) com a solução apresentada no Static. Mas até lá continuo fazendo meus testes com o CherryPy mesmo.
É algo que me irrita profundamente, servidores mal aproveitados que por sua vez demandam mais servidores! Alem dos óbvios custos financeiros envolvidos, existe também o fator “Sysadmin puto da cara” e “Sysadmin pagando o pato por falha no desenvolvimento”.
Essa é a recomendação de leitura da semana:
Hardware is Expensive, Programmers are Cheap
Hardware is Expensive, Programmers are Cheap II
Vale citar que esses textos foram escritos em resposta a esse outro:
Hardware is Cheap, Programmers are Expensive
update 1:
O Eri foi alem e consultou as fontes do texto sobre latência, e indicou esse como leitura para entender bem o conceito.
ps. eu li e confirmo, realmente vale a pena ler o texto
Oi, tudo bom?
Para o sysadmin que ainda não leu, LEIA!
Leia com cuidado, atenção, reflita sobre e depois leia de novo!
http://lonesysadmin.net/2008/09/08/downtime/
http://highscalability.com/latency-everywhere-and-it-costs-you-sales-how-crush-it
nota mental: talvez seria uma boa eu traduzir e postar por aqui!
E se possível eu gostaria de ver um post do Eri Ramos sobre o tema! Acho que ele pode ter uma boa história para contar
apt-get install bootchart
Eis aqui o bootchart gerado no meu Notebook.

