Apache2 + PHP-FPM no Ubuntu

abril 16th, 2013 by caferrari No comments »

As vezes precisamos de um servidor web com performance excelente porém ficamos presos a necessidade do famoso htaccess do apache, então vamos configurar o Apache2 para trabalhar com o PHP-FPM no Ubuntu.

Primeiro vamos instalar o apache2, o php e alguns módulos:

sudo apt-get install apache2-mpm-worker libapache2-mod-fastcgi php5 php5-fpm php5-cgi php-apc

Agora vamos configurar nosso apache para encaminhar as requisições para serem executadas pelo fpm:

Primeiro habilite os módulos que iremos utilizar:

sudo a2enmod actions fastcgi alias rewrite

É necessário um script para que o apache consiga se comunicar com o php-fpm, crie o arquivo /usr/bin/php5-fcgi:

sudo nano /usr/bin/php5-fcgi

E coloque o seguinte conteúdo:

#!/bin/sh
exec /usr/bin/php5-cgi

Agora faça com que este arquivo seja executável:

chmod +x /usr/bin/php5-fcgi

Edite o arquivo /etc/apache2/conf.d/httpd

sudo nano /etc/apache2/conf.d/httpd

E coloque as configurações padrões para todos os vhosts:

<IfModule mod_fastcgi.c>
        AddHandler php5-fcgi .php
        Action php5-fcgi /php5-fcgi
        Alias /php5-fcgi /usr/bin/php5-fcgi
        FastCgiExternalServer /usr/bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization
</IfModule>
<Directory />
	Options FollowSymLinks
	AllowOverride None
</Directory>
<Directory /var/www/>
	Options Indexes FollowSymLinks MultiViews
	AllowOverride All
	Order allow,deny
	allow from all
</Directory>

Edite o arquivo /etc/apache2/sites-enabled/000-default e deixe assim:

<VirtualHost _default_:80>
	DocumentRoot /var/www/
</VirtualHost>

Reinicie o apache:

sudo apache2ctl restart

Crie um arquivo de testes em /var/www/info.php e coloque o seguinte conteúdo

<?php
phpinfo();

Agora é só testar no seu browser, acessando o endereço: http://localhost/info.php

Usando MongoDB como storage de arquivos #2

julho 21st, 2011 by caferrari 1 comment »

No post anterior foi mostrado como montar um replicaSet para guardarmos nossos arquivos, aqui vou mostrar como configurar o servidor de aplicação e uma instância do MongoDB como arbitro.

Minha aplicação vai rodar também em uma maquina Ubuntu Server 11.04, com o PHP5.3, vamos configurar isso tudo de uma vez!

Instalação do PHP

Vamos precisar instalar alguns pacotes para tudo funcionar, comece instalando o mongodb, da mesma forma que foi feito no item “instalação” do post anterior, depois vamos precisar de mais alguns pacotes:

sudo aptitude install libapache2-mod-php5 php-apc php-pear php5-dev build-essential
  • libapache2-mod-php5: Instala o apache2, o php5 e claro, o modulo do apache
  • php-apc: Modulo de cache de opcode do php, para performance =)
  • php-pear: Vamos precisar paixar o modulo do mongo para o php
  • php5-dev e build-essential: Para que o modulo possa ser compilado

Depois de tudo instalado, vamos configurar o php para poder acessar o mongo e reiniciar o apache

sudo pecl install mongo
sudo sh -c 'echo "extension=mongo.so" &gt; /etc/php5/apache2/conf.d/mongodb.ini'
sudo service apache2 restart

Configuração do Árbitro

Como disse no post anterior, o Árbitro é uma instância do mongo que existe apenas para decidir qual dos membros do replicaSet será o novo Master caso algum venha a falhar de alguma forma.

Primeiro edite todos os arquivos /etc/hosts das maquinas do replicaSet e adicione o IP do árbitro (que no meu caso é o IP do servidor de aplicação) e também adicione estas entradas no servidor de aplicação

192.168.0.100      arquivo1a 
192.168.0.101      arquivo1b
192.168.0.102      arquivo1bkp
192.168.0.99       arquivo1arbiter

Depois disso, faça login no servidor que é o seu nó Master do replicaSet, verifique quem é acessando:

http://192.168.0.101:28017/_replSet

e vamos configurar, acesse a administração do mongo:

mongo admin

e adicione o arbitro ao replicaSet:

rs.addArb("arquivo1arbiter")

feito isso, de ctrl+c e confira o status do seu replicaSet (http://192.168.0.101:28017/_replSet):

Com isso nosso replicaSet está pronto para receber nossa aplicação, faça testes desligando o processo de seus clientes e veja como um outro assume, neste caso, se o servidor arquivo1a e arquivo1b caírem, a aplicação para, mas é muito simples adicionar novos nós para aumentar essa segurança,  o mínimo para um replicaSet de produção são 3 instâncias para armazenamento, uma de backup e um arbitro.

até a próxima parte.

Usando MongoDB como storage de arquivos #1

julho 20th, 2011 by caferrari 3 comments »

Estou envolvido em um projeto que vai necessitar armazenar muitos arquivos, e precisava de uma solução que fosse tolerante a falhas e escalasse muito bem, tanto verticalmente (Mais disco) quanto horizontalmente (Mais servidores).

Depois de olhar algumas soluções existentes como MogileFS, Cassandra, entre outros, eu gostei bastante do GridFS do MongoDB, pela simplicidade de configuração e principalmente pelo sistema de eleição de um novo servidor mestre caso o ativo venha a falhar em um determinado replicaSet.

Minha configuração inicial dessa estrutura consiste em dois servidores de Storage (Ubuntu Server 11.04 64bits rodando em VMs vmware em discos diferentes) e uma terceira maquina simples e remota que será um backup onde será configurado meu primeiro ReplicaSet. No servidor de aplicação vou ter o MongoDB rodando como arbitro (sem armazenar dados) apenas para determinar qual o servidor é o mestre caso algum venha a falhar.

Instalação:

Considerando que nos servidores foi instalado o ubuntu server, sem nada, vamos a configuração:

primeiro vamos adicionar a linha na configuração do APT para podermos baixar o pacote oficial do MongoDB, mantido pela 10-gen, crie o arquivo: /etc/apt/sources.list.d/mongo.list e adicione a linha:

deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen

depois de salvar o arquivo, adicione a chave do repositorio:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10

e finalmente instale o mongodb:

sudo aptitude update
sudo aptitude install mongodb-10gen

repita este processo em todas as maquinas de seu replicaSet.

Configuração do MongoDB

Primeiro vamos criar a pasta de armazenamento dos dados e definir as permissões:

sudo mkdir /dados
sudo chown mongodb:mongodb /dados/
sudo chmod 700 mongodb -Rf

Em todos os servidores vamos editar a configuração do MongoDB em /etc/mongodb.conf, aqui ficou assim:

dbpath=/dados/
logpath=/var/log/mongodb/mongodb.log
logappend=true
replSet = arquivo1
rest=true

* o parâmetro rest, faz com o que o servidor crie uma página para monitoramento dos status.

Depois de configurar todos os membros do replicaSet, reinicie o processo em todas as maquinas:

sudo service mongodb restart

Agora temos os servidores prontos para configurar a parte mais simples, o replicaset

Configuração do ReplicaSet

Para facilitar, configure nomes para seus membros do replicaSet no seu servidor de DNS interno ou, edite o arquivo /etc/hosts e adicione as maquinas que serão membro do replicaSet:

192.168.0.100      arquivo1a 
192.168.0.101      arquivo1b
192.168.0.102      arquivo1bkp

* Ajuste os IPs de acordo com sua rede.

Agora, em um servidor qualquer, acesse o console de administração do Mongo:

mongo admin

e crie a configuração do replicaSet:

conf = { _id : 'arquivo1',                    
... members : [
... {_id: 0, host: 'arquivo1a'}, 
... {_id: 1, host: 'arquivo1b'},
... {_id: 2, host: 'arquivo1bkp', priority: 0}
... ]}

* Note que o servidor de backup tem prioridade zero, isto faz com que este servidor nunca seja eleito como servidor Mestre.
confira se está tudo ok:

{
	"_id" : "arquivo1",
	"members" : [
		{
			"_id" : 0,
			"host" : "arquivo1a"
		},
		{
			"_id" : 1,
			"host" : "arquivo1b"
		},
		{
			"_id" : 2,
			"host" : "arquivo1bkp",
			"priority" : 0
		}
	]
}

se estiver ok, ainda no console do Mongo, inicialize o replicaset:

rs.initiate(conf)

em 10 segundos o seu replicaSet deverá estar rodando e pronto para receber dados, veja como está pelo navegador, acessando:

http://192.168.0.100:28017/_replSet

Você verá uma tela com o status de todos os membros do replicaSet:

Bom, é isso, no próximo post vou explicar como configurar o php e efetivamente armazenar arquivos no GridFS, Abraços

Flash Plugin 11 beta no Ubuntu 64

julho 16th, 2011 by caferrari 2 comments »

Saiu recentemente a versão beta do pugin do flash 11, e esta versão está funcionando muito melhor no Ubuntu 64bits, para instalar é bem simples:

wget http://download.macromedia.com/pub/labs/flashplatformruntimes/flashplayer11/flashplayer11_b1_install_lin_64_071311.tar.gz
tar -zxvf flashplayer11_b1_install_lin_64_071311.tar.gz
sudo cp usr / -Rfv
sudo cp libflashplayer.so /usr/lib/flashplugin-installer/ /etc/alternatives/firefox-flashplugin

Depois é só reiniciar seu firefox e conseguir ver aquelas apresentações legais no slideshare.

Pegando a temperatura de qualquer cidade

julho 29th, 2010 by caferrari 13 comments »

Me surgiu um trabalho aqui pelo qual preciso exibir a temperatura atual da cidade, e como estava com insônia decidi brincar um pouco e criar uma solução para isso, fui para o google e pesquisei por “Previsão do Tempo“, me surgiram alguns resultados, porém, gostei mais do UOL.

Depois disso foi correr para a criação do script para ler o HTML e retornar um objeto contendo as informações da temperatura no momento, segue o código escrito em php:

function loadTemp($cidade='Palmas-TO'){
	// variavel para dados de retorno
	$ret = array('url' => "http://tempoagora.uol.com.br/previsaodotempo.html/brasil/$cidade/");
 
	// carrega o html do tempoagora
	$html = file_get_contents($ret['url']);
 
	// Pegamos apenas a parte que interessa do html
	$iniflag = '<!-- Insere dados Atuais de AeroPortos ou Est. Meteorologica -->';
	$fimflag = '<!-- FIM Insere dados Atuais de AeroPortos ou Est. Meteorologica -->';
	$ini = strrpos($html, $iniflag ) + strlen($iniflag);
	$fim = strpos($html, $fimflag, $ini);
	$html = substr($html, $ini, ($fim-$ini));
 
	// pegamos a url do icone
	preg_match('@<img src="/(imagens/icones/[a-zA-Z\-]+.gif)"@', $html, $mat);
	$ret['icone'] = 'http://tempoagora.uol.com.br/' . $mat[1];
 
	// Limpa o código html
	$content = strip_tags($html);
	$content = str_replace('&nbsp;', ' ', $content);
 
	// quebra o que sobrou em um vetor
	$content = explode("\n", $content);
 
	// limpa espaços e linhas em branco
	foreach ($content as $k => &$v){
		$v = trim($v);
		if ($v==='') unset($content[$k]);
	}
 
	// pega horário da verificação
	$lin = array_shift($content);
	preg_match('@[0-9]{1,2}:[0-9]{1,2}@', $lin, $mat);
	$ret['verificado']  = $mat[0];
 
	// pega insidência de nuvens
	$ret['nuvens'] = array_shift($content);
 
	// define nomes melhores para as próximas propriedades
	$keys = array('temperatura', 'sensacao', 'vento', 
			'pressao', 'umidade', 'visibilidade');
 
	// reseta as chaves do vetor
	$content = array_unique($content);
 
	// percorre chaves impares e aplica as propriedades definidas acima
	for ($x=1; $x<=11; $x=$x+2){
		$ret[array_shift($keys)] = $content[$x];
	}
 
	// retorna os dados como um objeto
	return (object)$ret;
}

Analisando o site deles, notei que a temperatura é atualizada de hora em hora, então a melhor forma de utilizar essa solução é utilizando o crontab, que executa a cada hora, eu escolhi executar no quinto minuto de cada hora cheia (5:05, 6:05, etc).

segue o código php que o crontab executa:

require 'loadTemp.php';
// define nome do arquivo de cache
$cache_file = sys_get_temp_dir() . '/temp';
 
// carrega a temperatura
$temp = loadTemp();
 
// salva em cache
file_put_contents($cache_file, serialize($temp));

E para exibir no sistema eu fiz uma funçãozinha:

function temp(){
	$cache_file = sys_get_temp_dir() . '/temp';
	// se o cache existe, retorna o objeto
	if (file_exists($cache_file)) 
		return unserialize(file_get_contents($cache_file));
 
	// senão cria o cache e retorna =)
	$temp = loadTemp();
	file_put_contents($cache_file, serialize($temp));
	return $temp;
}

depois, no local específico, ficou algo mais ou menos assim:

<?php $temp = temp() ?>
<img src="<?php echo $temp->icone ?>" alt="<?php echo $temp->nuvens ?>" />
<span><?php echo $temp->temperatura ?> (<a rel="external" href="<?php echo $temp->url ?>">saiba mais</a>)</span>

Minha forma de pagar por esse uso é manter um link para o Tempoagora, o que é bastante interessante, pois meu visitante pode querer obter mais informações

É isso ai, abraço a todos