Personal tools

Skip to content. | Skip to navigation

Sections

Blog

You are here: Home Blog

Blog

Nginx, SPDY agora é real.

Posted by Cleber J Santos at 31/07/2013 16:50
Filed under: Performance, Nginx, Infra

Já faz um tempo, postei aqui no Blog falando sobre o suporte ao módulo SPDY que estava próximo de ser real no Nginx, venho acompanhando o assunto desde 2012,  a discussão e testes no Google e no chromium.

Após ler sobre o assunto e começar a ver que também o Nginx estava iniciando testes com um módulo que daria suporte ao protocolo me entusiasmei a também inciar testes, então após algum tempo, cá estou eu para finalizar o post. De fato ainda não é um protocolo muito usado, não é um módulo que todos os SysAdmin estão avaliando e usando, creio que por que não saberem, por ainda não ser tão bem divulgado, mas acredito que de fato este se torne um padrão para acelerar conexões SSL, dado que o Google já está usando como padrão no seu buscador.

Desde a versão 1.3.15 do Nginx já temos suporte não nativo do módulo, isso significa que podemos compilar o Nginx e habilitar o suporte ao SPDY desde que tenhamos os requerimentos para isso.

Para quem deseja instalar e começar a utilizar, aqui vai a dica de como fazer, antes de mais nada gostaria de reforçar que, infelizmente tanto o IE quanto o Safari não suportam SPDY. Você poderá verificar a tabela de compatibilidade para suporte de protocolo de rede SPDY em navegadores de desktop e móveis.

Requerimentos.

  • libssl 1.0.1+.
  • libpcre 3, libpcre3-dev.
  • Compilador C (ex. GNU C Compiler)
  • Navegador com suporte ao SPDY (ex. Google Chrome)

Garantindo que o sistema atenda os requisitos podemos seguir instalando o Nginx com o suporte ao módulo, então façamos:
 
$ cd /tmp
$ wget http://nginx.org/download/nginx-1.4.2.tar.gz
$ tar -xzf nginx-1.4.2.tar.gz
 
Com o comando acima estamos descompactando o Nginx versão 1.4.2 no qual iremos compilar.
 
$ cd nginx-1.4.2
$ ./configure --with-http_spdy_module --with-http_ssl_module
$ make
$ sudo make install
 
Lembre-se de que existem outros parâmetros que podem ser passados na compilação, como o local onde o Nginx será instalado por exemplo e outros suportes, mas não irei abordar neste post.
 
Após a instalação você poderá configurar o Nginx com o certificado normalmente como você já deve ter feito antes, a diferença é que agora para habilitar de fato o suporte ao módulo SPDY devemos adicionar spdy na configuração do listen do nosso Nginx como no exemplo abaixo:
 
 server {
        listen          127.0.0.1:443 ssl spdy;
        server_name     mysite.com;
 
        access_log      logs/ssl-access.log;
        error_log       logs/ssl-error.log;
 
        ssl_certificate      ssl/mysite.crt;
        ssl_certificate_key  ssl/mysite.key;
...

 

Para testar você pode instalar no Chrome ou no Firefox uma extensão.
| Comentários

Discutindo a relação com Varnish 3 e Plone 4

Posted by Cleber J Santos at 17/09/2012 09:15

Pois é, já é a segunda vez que dou palestra e posto aqui falando sobre o tema, dessa vez pude palestrar no Plone Symposium, o encontro da comunidade sulamericana de Plone que este ano aconteceu em Brasília, no Auditório do Interlegis.

Vejo no assunto tratado pontos positivos e negativos, infelizmente pelo que pude perceber como ponto negativo é que muitos ainda desconhecem o Varnish, e pior, desconhecem o que é um cache, muitos já ouviram falar, mas não estão tão preocupados em saber se tem um servidor de cache por trás do site.

Alo interessante é que com o assunto Diazo em questão, todo o resto do Plone parece desnecessário :) pelo menos para mim é o que ficou muito visível, e isso é bom claro, apesar da minha palestra não ter a ver com o Diazo, o Plone por padrão não vem com suporte a ESI / SSI (Edge side includes / Server side include), dai minha citação sobre o Diazo. 

"Hoje temos algumas formas que adicionar cache em partes de nosso site, isso mesmo, imagine você poder colocar um cache diferente para cada parte da sua Home, 5 minutos de cache em um portlet de imagens, 1 mês de cache para o rodapé do site, banners sem cache e assim vai." 

Não quero escrever aqui toda a palestra então você pode assistir a palestra ou e também visualizar os slides abaixo.
 
http://www.youtube.com/watch?v=QxG6TItDCfg
 
| Comentários

Suporte SPDY no Nginx se aproxima.

Posted by Cleber J Santos at 18/06/2012 12:00
Filed under: Performance, Infra, Tuning, Nginx

Recentemente um dos desenvolvedores do Nginx Valentin Bartenev, anunciou o suporte SPDY para o servidor web Nginx. SPDY (pronunciado speedy), trata-se de um protocolo de rede experimental desenvolvido essencialmente no Google para transporte de conteúdo web e focado em fazer a Web mais rápida.

Apesar de não ser atualmente um protocolo padrão, o grupo que está desenvolvendo o SPDY afirmou publicamente que está trabalhando em direção a uma padronização, e tem implementações de referência no momento disponíveis em ambos Google Chrome e Mozilla Firefox. O protocolo é similar ao HTTP, tendo como objetivo reduzir o tempo de carga de páginas da internet. Isso é conseguido priorizando e multiplexando a transferência dos sub-recursos da página web para que somente uma conexão por cliente seja necessária.

 Encriptação TLS é praticamente onipresente nas implementações do SPDY, e a transmissões são comprimidas com gzip ou DEFLATE em contraste ao HTTP, em que os cabeçalhos não são comprimidos. Além disso, o servidor indica ou até mesmo envia conteúdo ao invés de esperar requisições individuais para cada recurso de uma página. O nome não é um sigla, mas um versão reduzida da palavra "speedy" do inglês.

Este trabalho foi patrocinado pela Automattic que desde 2008 utilizam Nginx e desde então tem feito parte de quase todas as peças de sua infra.

Desde 2011 a empresa já conversava com o pessoal da Nginx para fechar um acordo, onde a Automattic iria patrocinar o desenvolvimento e a integração do SPDY no Nginx, tendo como única exigência final que que o código resultante deva ser liberado sob uma licença de código aberto para que outros possam se beneficiar de todo o trabalho.

Já existem extensões para as versões recentes dos navegadores Google Chrome e Mozilla Firefox que permitem saber se um site já implementam o SPDY, visitando o próprio Google ou o Twitter já podemos perceber que utilizam o protocolo.

“We’d like to say big thanks to the team at Automattic and especially to Pyry Hakulinen who has been great in helping us test and debug this first public version of SPDY module for nginx. Automattic is a great partner, and we will continue to work with Barry and his team on improvements to nginx and to nginx/SPDY in particular.”

Andrew Alexeev – Nginx, Inc.

E melhor que usso, percebi que apenas este site https://barry.wordpress.com implementa o SPDY no Nginx, quando acessado através de SSL e que trata-se do blog de Barry, o atual chefe de sistemas Wrangler na Automattic e responsável pela execução da infra-estrutura distribuída globalmente, no qual deu nota e alguns detalhes da implementação do SPDY no Blog.

 

O futudo do SPDY será fazer parte da fonte oficial do servidor web Nginx, e confesso, estou ansioso para já testar tudo :) então nos próximos dias irei postar novidades sobre os testes, é claro que para quem desejar já testar pode já pegar os patches beta em http://goo.gl/SlaiA.

Para você que deseja também testar o SPDY com o Nginx, leia o link http://nginx.org/patches/spdy/README.txt.

Desvantagens

Pois é, infelizmente nem tudo são flores, duas desvantagens são:
 
  • O conteúdo enviado mesmo que já haja cache é um desperdício de banda.
  • Softwares de filtragem que dependem do HTTP não funcionarão mais.
  • Muito provável que o IE vai demorar para implementar o suporte a este protocolo.
 

Você sabia?

 
  • O navegador Google Chrome e o Chromium já utilizam o SPDY quando se comunicam com os serviços do Google, como o Google Search, Gmail, Chrome sync e quando exibindo anúncios do Google. O Google reconhece que o uso do SPDY é habilitado em comunicações entre o Chrome e os servidores do Google que usam SSL.
  • A partir da versão 11 do Mozilla Firefox e SeaMonkey V2.8 existe o suporte a SPDY, apesar de não ser habilitado por padrão. O suporte pode ser habilitado através da preferencia network.http.spdy.enabled preference em about:config.
  • No Firefox 13 o SPDY é habilitado por padrão.
  • Também no Google Chrome há um parâmetro de linha de comando (--enable-websocket-over-spdy) que habilita uma implementação experimental do WebSocket sobre SPDY.
  • E também podemos utilizar o Google Chrome para inspecionar as sessões do SPDY, acessando uma URL especial: 
chrome://net-internals/#events&q=type:SPDY_SESSION%20is:active
Para mais informações sobre as especificação do protocolo por favor acesse:  http://www.chromium.org/spdy/spdy-protocol
| Comentários

Python: Google and April Fool's Day

Posted by Cleber J Santos at 09/04/2012 01:16
Filed under: Python, Google

Como bem sabemos o dia da mentira é comemorado por todos e por muitas empresas, até mesmo o Google entrou nessa, e este ano não foi diferente, porém o que venho postar não é sobre o dia da mentira ou sobre as brincadeiras que o Google tem feito, apesar de serem muito divertidas.

O que me chamou a atenção foi o tal do Elegantizr que foi divulgado como um framework que promete deixar o site até 3 vezes mais rápido, e pior, muita gente mesmo caiu nessa!

Risadas a parte, a brincadeira foi tão legal que logo eu quis saber como foi feita. É bem provável que muitos venham a dizer que é algo super simples e etc, porém vale ainda assim blogar.

A brincadeira.

 Trata-se de um arquivo de CSS (http://www.google.com/landing/elegantizr/elegantizr.css) que deve ser incorporado no site:
 
<link rel="stylesheet" href="http://www.google.com/landing/elegantizr/elegantizr.css" />
Analisando o conteúdo do arquivo teremos o seguinte código:
 
:before {
  content: '\41\50\52\49\4C\20\46\4F\4F\4C\20\F4\BF\F4';
}
 
Não entendo muito das mágicas do CSS, e tive que recorrer a pessoas mais confiáveis no assunto como o @agnogueira, @Tamosauskas e o @google, no qual me informaram que  trata-se de pseudo-elementos e que neste caso temos vários, dentre eles temos o before e after que são usados para gerar conteúdos antes e depois do conteúdo de um elemento.
 
A seguir uma exemplo de como :before e :after podem ser usados para inserir a URL logo após o texto de um link ou antes de um texto de um link:
 
Antes do texto de um link.
a:link:before {
  content: " (" attr(href) ") ";
}

Depois do texto de um link.

a:link:after {
   content: " (" attr(href) ") ";
}
Agora não quero me focar em CSS, então espero que os amigos @agnogueira@Tamosauskas possam blogar algo sobre os pseudo-elementos de CSS :D
 

Como fazer.

Agora entramos na parte que gosto, notem que destaquei o trecho do código que é:
 
'\41\50\52\49\4C\20\46\4F\4F\4C\20\F4\BF\F4'
Aqui é onde a brincadeira acontece, este código ai acima trata-se de um texto (string) convertido em hexadecimal, vamos para um exemplo rápido:
 
 
>>> text = 'APRIL FOOL ô¿ô'
>>> text.encode('hex').upper()
'415052494C20464F4F4C20C3B4C2BFC3B4'
 
Note que no meu exemplo o código aparece diferente, isso por que o meu Python está usando encode utf8 como padrão, vejamos agora usando iso-8859-1.
 
>>> text = 'APRIL FOOL ô¿ô'
>>> text.encode('iso-8859-1').encode('hex').upper()
'415052494C20464F4F4C20F4BFF4'
 
Agora o que nos falta é adicionar a cada dois objetos uma barra invertida '\', e teremos:
 
'\41\50\52\49\4C\20\46\4F\4F\4C\20\F4\BF\F4'
A idéia não é mostrar exatamente como foi feito claro, ou seja, fica por conta colocar as barras a cada duas strings como feito acima, porém isso pode ser feito também com Python.
 
Para finalizar fiz este abaixo que irá imprimir a frase Python antes de cada item, note que o procedimento é o mesmo.
 
A conversão.
>>> text = 'Python'
>>> text.encode('iso-8859-1').encode('hex').upper()
'507974686F6E'

O Css.
:before {
  content: '\50\79\74\68\6F\6E';
}


Até a próxima.

| Comentários

JavaScript Minify com Python

Posted by Cleber J Santos at 17/03/2012 19:30
JavaScript Minify com Python

Trabalhando em um projeto recentemente precisei gerar um arquivo menor do jQuery que eu havia modificado, e com isso comecei a me perguntar como o jquery.com o fazia com seus arquivos por exemplo: 

  • jquery-1.7.1.js 244K
  • jquery-1.7.1.min.js 92K

Notaram  a diferença de tamanho? Pois bem, isso me levou a pesquisas, que por sua vez me levou a diversos resultados, uma delas é o link http://www.refresh-sf.com/yui/ que nada mais é que uma interface Web que reduz o arquivo como eu queria fazer.
 
Porém que queria mais que isso, não quero depender de entrar em um site para gerar um arquivo menor, então achei Egg que faz exatamente o que eu queria, e melhor que isso, é pytonica :D http://pypi.python.org/pypi/jsmin
 
Vamos então a solução, para isso vamos usar o próprio jQuery só para testarmos que funciona após ter minimizado o tamanho do arquivo, é claro que isso é apenas um teste, pois o jQuery já lhe dará o arquivo dele como mostrado acima, compactado.
 
Vamos criar uma pasta chamada cobaia, dentro dessa pasta baixe o arquivo mencionado e visualize o tamanho dele:
 
$ mkdir cobaia
$ curl -O http://code.jquery.com/jquery-1.4.4.js
$ ls -hs *.js
No momento você verá o que o arquivo contém 180K, agora vamos criar um arquivo menor. Instale o egg jsmin no seu python com o comando:
 
$ easy_install jsmin
Ou 
$ pip install jsmin
Feito isso acesse o prompt do Python (Estou usando Python 2.6) e vamos converter assim:
$ python
>>> from os import path
>>> from os.path import join
>>>
>>> # Usei o cStringIO por ser mais rápido que o StringIO implementado em Python
>>> from cStringIO import StringIO
>>> 
>>> # As linha abaixo é o que nos garante o uso do jsmin
>>> import jsmin
>>> jmin = jsmin.JavascriptMinify()
>>>
>>> base = path.dirname(path.abspath(path.realpath(__name__)))
>>>
>>> # Abrimos o arquivo original apenas como leitura 
>>> filejs = open(join(base, 'jquery-1.4.4.js'),'r')
>>>
>>> # Pegamos o nome do arquivo original e concatenamos com .min.js
>>> filename_out =  str(str(filejs.name.split('/')[-1]).split('.js')[0] + '.min.js')
>>>
>>> file_out = StringIO()
>>> file_out.write("")
>>>
>>> # Gerando um novo arquivo com modo de escrita
>>> file_out = open(join(base, filename_out),'wb')
>>>
>>> # Por fim passamos para o minify um arquivo de entrada e o de saída
>>> jmin.minify(filejs,file_out)
>>> file_out.close()
 
CTRL+D para sair do console python.
 
Mantive o exemplo acima comentado para que possam melhor entender o que foi feito. Agora podemos usar novamente o comando para ver o tamanho dos arquivos, antes e depois.
$ ls -hs *.js
Note que agora temos um novo arquivo com o nome de jquery-1.4.4.min.js com apenas 112k, pode não parecer muito, mas tenha certeza que isso ajuda muito no desempenho do seu site, ainda mais se você tiver bem mais arquivos.
 
Fiz este mesmo teste em um arquivo que eu tinha de 152k e ele foi para 64k, então veja bem a diferença. Vale testar com seus arquivos, claro que é sempre bom fazer um backup antes ;)

Outra forma de fazer.

Essa é a outra forma de fazer, mas não é pythonica. Achei importante mencionar essa outra forma de fazer, que na verdade é exatamente de onde partiu a idéia em Python e provavelmente as demais ;)
 
O código e projeto original do JSMin é escrito e mantido por Douglas Crockford em C e pode ser acessado em https://github.com/douglascrockford/JSMin.
 
Jsmin é um filtro que omite ou modifica alguns caracteres. Isto não altera o comportamento do programa que estamos reduzindo. O resultado pode ser mais difícil depurar. Vai ser mais difícil de ler.
 
Após baixar o jsmin.c, vamos compilar e usar, abaixo mostro como compilar e como usar, lembrando que estamos usando o arquivo do jquery como modelo. O comando segue o mesmo modelo que em Python, neste caso o binário do jsmin também requer um arquivo de entrada e outro de saída.
 
$ gcc jsmin.c -o jsmin
$ ./jsmin < jquery-1.4.4.js > jquery-1.4.4.min.js
Pronto! Agora temos um arquivo com 108k, menor ainda que o gerado em Python :D
 

O pulo do gato.

Descobri ainda que o jQuery usa o chamado packer (http://dean.edwards.name/packer/) que nada mais é que um compressor de JavaScript, após passar o arquivo que temos de 108k o resultado foi 60k, então aqui descobrimos o pulo do grato usado pelo jQuery.
 
É isso ai, agora você já pode começar a se divertir e colocar um pouco mais de performance em seu site.
| Comentários

Varnish 3, Plone 4: Discutindo a Relação.

Posted by Cleber J Santos at 06/10/2011 10:45

Não preciso dizer o quanto a PythonBrasil [7] foi um sucesso :-D , infelizmente não tive como ver todas as palestras o que seria bizarro conseguir, dado que não sou onipresente. Apesar da minha palestra ter sido em uma sexta-feira no final do dia eu pude extrapolar o tempo, e ainda ficou faltando diversos detalhes.

Um detalhe importante é que o @ericof apareceu e também participou da palestra,  conhecidencia ou não, ocorreu após eu ter invocado seu nome 3 vezes. Em minha apresentação pude mostrar o quanto o Varnish é poderoso, e o quanto a combinação Varnish [3] e Plone [4] pode ser igual a [42]

| Comentários

VMODs: O lego do Varnish 3

Posted by Cleber J Santos at 22/08/2011 00:10
VMODs: O lego do Varnish 3

VMODs, ou simplesmente Varnish Modules é, segundo da documentação de modificações, um dos grandes sucessos obtidos na versão 3: "VMODs on the other hand, was an instant success, because they make it much easier for people to extend Varnish with new functionality".

E realmente, é o mesmo que tenho achado, como bem sabemos desde o Varnish 2.1 podemos usar C inline para criar e estender funcionalidades que por padrão o Varnish não trás, e com a chegada dos módulos essa brincadeira tona-se ainda melhor, por tudo que podemos fazer na VCL.

Sabermos ainda que existem coisas que não temos como fazer na VCL, por exemplo: Procurar um número de IP em um arquivo de banco de dados. Usando código C inline até temos como resolver este problema, já que o Varnish nos provê isso, e lá você pode fazer tudo, mas não é uma forma conveniente ou mesmo legível para resolver tais problemas. Eis o lugar onde VMODs entram em cena.

 

O que é a VMOD?

Trata-se de uma biblioteca compartilhada com algumas funções C que pode ser chamado a partir do código VCL.

A interface entre o VMOD o compilador VCL ("VCC") e o tempo de execução VCL ("VRT") é definido em um arquivo de nome vmod.vcc que um script python de nome "vmod.py" que faz todo o trabalho duro

Executando o vmod.py no arquivo vmod.vcc, será produzido dois arquivos, que são: "vcc_if.c" e "vcc_if.h", no qual devemos usar para construir o nosso arquivo de biblioteca compartilhada.

o vcc_if.c até pode ser esquecido em nosso VMOD, mas o vcc_if.h é importante, ele contém os protótipos para as funções que desejamos exportar para a VCL.

Nota: Uma informação importante, você ainda pode dizer ao Varnish em tempo de execução para qual diretório ele deve olhar para buscar os VMODs. 
vmod_dir
Default: ${VARNISH:DIR}/lib/varnish/vmods


Na prática.

Agora que já temos base do que é um VMOD e como ele funciona, vamos aos exemplos :) , estou usando alguns que encontrei na internet então vamos lá:
 
  • 1º Exemplo.
Autor: Martin Blix Grydeland
Descrição: O módulo implementa o "Olá Mundo!", sendo bem pequeno e simples para entender.
Nota: Após instalar o módulo (como instalar em README) basta executar o seguinte trecho de código em sua VCL.
import example;

sub vcl_deliver {
	# Vamos definit o  resp.http.hello para "Hello, World"
	set resp.http.hello = example.hello("World");
}

 

  • 2º Exemplo

Módulo: https://github.com/leed25d/geoip-vmod
Autor: David Newhall
Descrição: Provê a capacidade de retornar a localização geográfica de um endereço IP.
Nota: Após instalar o módulo (como instalar em README) basta executar o seguinte trecho de código em sua VCL.

import geoip;

sub vcl_recv {
   # Definimos um cabeçalho de solicitação X-GeoIP
   # para o geo do solicitante (ou desconhecido).
   set req.http.X-Forwarded-For = client.ip;
   set req.http.X-GeoIP = geoip.country(req.http.X-Forwarded-For)
}

  • 3º Exemplo
Módulo: https://github.com/varnish/libvmod-curl
Autor: Tollef Fog Heen
Descrião: Este vmod é um dos que mais gosto, ele provê o curls para o Varnish, então podemos usar o varnish como um cliente HTTP e buscar cabeçalhos e corpo nos backends.
Nota: Após instalar o módulo (como instalar em README) basta executar o seguinte trecho de código em sua VCL.
 
import curl;

sub vcl_recv {
    curl.fetch("http://example.com/test");
    if (curl.header("X-Foo") == "bar") {
        …
    }
    curl.free();
}

Estes são alguns dos exemplos que podemos seguir para criar nosso próprio VMOD, nota-se que precisamos saber C para isso, algumas idéias de módulos seria usar C + libxml para fazer parse de arquivos XMLs diretamente no Varnish e já manter em cache, ainda com analise de cabeçalho e etc.. Ou Usar o PIL para gerar imagens ou qualquer outra coisa que sua imaginação desejar, você agora tem o poder do C e do Varnish nas suas mãos.
 

Um pouco mais antes de terminar.

Agora que já estamos mais acostumados e empolgados em poder criar VMODs para trabalhar com o Vanrish, veja alguns exemplos do que podemos fazer com o que já existe. 
 
Nota. Lembre-se que é necessário importar o módulo std ou qualquer outro que iremos utilizar, uma única vez e usar em toda a VCL.
 
  • Adicionando o std.collect(), coletamos vários cabeçalhos HTTP para um único cabeçalho.
import std;

sub vcl_recv {
   std.collect(req.http.foo);
}

sub vcl_fetch {
   std.collect(beresp.http.bar);
}
  • Retornando uma URL em caixa alta ou uma string.
sub vcl_deliver {
        set resp.http.foo = std.toupper(req.url);
}
ou
set beresp.http.x-scream = std.toupper("yes!");
  • Retorna o contrário do toupper, ou seja, strings todas em caixa baixa.
set beresp.http.x-nice = std.tolower("VerY");

Ainda temos random, log, set_up_tos, syslog, fileread, duration e integer, no qual adoraria escrever sobre, mas fica a dica para quem desejar conhecer, o VMOD é realmente uma verdadeira caixa de legos, e o mais legal é que você ainda pode criar novas peças e encaixar nas já existentes. Espero que tenha sido u bom post para você entender e começar a montar a sua VMOD, e espero que post aqui sobre a experiência.

Até a próxima.


Leia também:

| Comentários

Migrando Varnish 2.1 para Varnish 3.0

Posted by Cleber J Santos at 14/08/2011 00:35
Migrando Varnish 2.1 para Varnish 3.0

Nas últimas semanas tenho tido a oportunidade de ficar mais próximo do Varnish, e nas últimas três semanas comecei a migrar do varnish 2.1 para Varnish 3, posso dizer desde já que teve um grande salto de melhorias e também de implementações. Mas neste post irei tratar apenas de como preparar sua configuração de vcl para não ser pego de supresa quando fazer um upgrade da versão.

O exemplo de vcl a seguir foi retirado do svn do Varnish: https://www.varnish-cache.org/trac/browser/etc/zope-plone.vcl e será com base neste vcl que iremos efetuar a migração.

Breve resumo das mudanças de 2.1.5 para 3.0.0

  • Suporte ao módulo VMODs [3].
  • Suporte a Compressão e descompressão, incluindo compressão de fragmentos ESI.
  • Suporte a carregamento preliminar de streaming, tanto em cache ou não.
  • Melhor documentação.
  • Melhor valores padrão para parâmetros.
  • varnishncsa agora com suporte de log com formatos personalizado.
  • varnishlog, varnishncsa  e varnishhist agora com suporte a filtros de registros que correspondem múltiplas expressões.

Para uma lista mais detalhada de alterações leia o documento de alterações.
 

Alterações na VCL.

  

  • log foi movido para o vmod std.[4]

log "Olá mundo";
torna-se
import std;
std.log "Olá mundo";
Nota. A importação do std só é preciso ser feito uma única vez e usada por toda a VCL.
 
 

  • purge agora torna-se o chamadas ban, ou como dito na VCL, são funções ban.

purge() e purge_url() são agora, respectivamente ban() e ban_url(), sendo assim deve-se substituir todas as ocorrências: 
purge(“req.url = ” req.url);
para
ban(“req.url = ” + req.url);

purge
 continua existindo porém não leva nenhum argumento mais, e ainda pode ser usado em vcl_hit ou vcl_miss para fazer purge de itens do cache, onde você iria reduzir o ttl a 0 no Varnish 2.1.
 sub vcl_hit {
   if (req.request == “PURGE”) {
      set obj.ttl = 0s; error 200 “Purged.”;
   }
}
torna-se
sub vcl_hit {
   if (req.request == “PURGE”) {
      purge; error 200 “Purged.”;
   }
}

 

  • beresp.cacheable está fora.

beresp.cacheable está fora do Varnish 3, mas pode ser substituído por beresp.ttl> 0s

 

  • returns agora é feito com a função return()

pass, pipe, lookup, deliver, fetch, hash, pipe e restart não são mais palavras-chave, mas argumentos para a função return(), então:

sub vcl_pass {
   pass;
}

torna-se

sub vcl_pass {
   return(pass);
}

 

  • req.hash foi substituído por hash_data()

Não apendamos mais o hash com +=
set req.hash += req.url;
Agora torna-se
hash_data(req.url);

 

  • esi substituído por beresp.do_esi

Não habilitamos ESI com esi.
esi;
no vcl_fetch tonar-se
set beresp.do_esi = true;

 

pass em vcl_fetch foi renomeado para hit_for_pass

A diferença no comportamento do pass em vcl_recv e vcl_fetch confundem as pessoas, apenas para torna mais claro as coisas, eles são diferentes :) e agora devemos usar return(hit_for_pass) onde usava-se pass no vcl_fetch.

 

  • NOTA.

O Varnish 3 também teve uma mudança de comportamento, isso significa que ele irá retornar um erro quando cabeçalhos forem muito grandes ao em vez de apenas ignorá-los. E se os limites são muito baixos, retornará HTTP 413, então deve-se  alterar limits por http_req_hdr_len e http_req_size. Essas alterações devem ser feitas em tempo de execução, o que significa adicionar como parâmetro do executável varnishd,   exemplo (-p http_req_hdr_len=4096 -p http_req_size=1024).

Para maiores informações sobre parâmetros em tempo de execução acesse a documentação[5].

 

Migrando.

 

Eis aqui nosso exemplo retirado do svn do Varnish, porém convertido para a versão 3.0, retirei quais quer comentários da VCL e efetuei a migração, acredito que depois da explicação dos parâmetros acima você seja capaz de migrar a sua configuração.

 

backend default {
	.host = "127.0.0.1";
	.port = "9673";
}

acl purge {
	"localhost";
	"192.0.2.0"/24;
}

sub vcl_recv {
        if (req.http.host ~ "(www.)?example.com") {
                set req.http.host = "example.com";
		set req.url = regsub(req.url, "^", "/VirtualHostBase/http/example.com:80/example.com/VirtualHostRoot");
        } elsif (req.http.host ~ "(www.)?example.org") {
                set req.http.host = "example.org";
		set req.url = regsub(req.url, "^", "/VirtualHostBase/http/example.org:80/example.org/VirtualHostRoot");
        } else {
                error 404 "Unknown virtual host.";
        }

        if (req.request != "GET" && req.request != "HEAD") {
                if (req.request == "POST") {
                        return(pass);
                }
                
                if (req.request == "PURGE") {
                        if (!client.ip ~ purge) {
                                error 405 "Not allowed.";
                        }
                        return(lookup);
                }
        }
        if (req.http.Cookie && req.http.Cookie ~ "__ac(|_(name|password|persistent))=") {
		if (req.url ~ "\.(js|css)") {
                        remove req.http.cookie;
                        return(lookup);
                }
                return(pass);
        }
}

sub vcl_hit {
        if (req.request == "PURGE") {
                purge;
                error 200 "Purged";
        }
}

sub vcl_miss {
        if (req.request == "PURGE") {
                error 404 "Not in cache";
        }
}

sub vcl_fetch {
        if (beresp.ttl < 3600s) {
                set beresp.ttl = 3600s;
        }
} 

 

Indicação de leitura.

| Comentários

Plone 4, velocidade e Chameleon tudo em comum.

Posted by Cleber J Santos at 14/07/2011 14:30
Plone 4, velocidade e Chameleon tudo em comum.

Num post anterior escrito pelo amigo simplificador @Tamosauskas (Plone mais rápido com Chameleon), foi mencionado a preocupação e empenho que a comunidade Plone tem tido quando o assunto é desempenho. Pois bem, neste post pretendo reforçar este aspecto, lembrando que essa é umas das preocupações da comunidade, tenho também como maior delas a segurança é claro.

Como dito no post do @Tamosauskas, a cada nova versão do Plone percebemos um ganho de desempenho, desde a versão 2.5 até a mais atual em desenvolvimento 4.1rc3 (Atual até a data que estou escrevendo este post), e claro, ganho de novas funcionalidades mudanças significativas para  criação de novos produtos e tipos e a mudança da skin padrão.

O que exatamente é o tal do Chameleon?

No site oficial a melhor definição é "Chameleon is an open-source template engine written in Python.
", de fato, trata-se de um modelo de templates escrito em Python, ele foi escrito para gerar documentos de marcação HTML ou XML para aplicações Web.

Ele usa a linguagem do Page Template, só que sua implementação é bem mais rápida e independente, no qual trás um conjunto de novos recursos e podemos usar em qualquer aplicação escrita em Python (2.5 e superior, incluindo 3.x e PyPy), algumas de suas características são:
 
  • Rápido - Os templates são compilados para byte-code.
  • Extensível - É fácil de estender uma linguagem ou criar sua própria.
  • Testado - Testes automatizados que protege contra regressões.
 
Para o Python 2.7 e superior não existem dependências de bibliotecas, já nas versões 2.5 e 2.6 a ordereddict e unittest2 são pacotes definidos como dependências, mas para se ter uma idéia de como Chameleon é independente, seu sistema de tradução é plugável e baseado em gettext. 
 
Não há um suporte embutido para o pacote zope.i18n. Mas se o pacote for instalado, ele será usado por padrão. O pacote translationstring[3] oferece algumas das mesmas classes de utilidades auxiliares, sem a interface do Zope.
 

Usando Chameleon no seu buildout.

Adicione as linhas em seu buildout:
eggs = ... five.pt>=2.1
zcml = ... five.pt
Estes testes foram efetuados nas versões 4.0.7 e 4.1rc3 do Plone, para um teste simples crie um Page template e coloque o seguinte conteúdo:
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
      xmlns:tal="http://xml.zope.org/namespaces/tal"
      xmlns:metal="http://xml.zope.org/namespaces/metal"
      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
      lang="en"
      metal:use-macro="context/main_template/macros/master"
      i18n:domain="plone">
 <body>
  <metal:main fill-slot="main" tal:define="name string:world">
   Hello ${name}!
  </metal:main>
 </body>
</html>
 
Note que não precisei colocar tal:content para imprimir o texto da variável name, abaixo mais 2 exemplos:
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
      xmlns:tal="http://xml.zope.org/namespaces/tal"
      xmlns:metal="http://xml.zope.org/namespaces/metal"
      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
      lang="en"
      metal:use-macro="context/main_template/macros/master"
      i18n:domain="plone">

 <body>
  <metal:main fill-slot="main">
   <div tal:replace="python:'here==context:'+str(here==context)" />
   <div tal:replace="python:'here==container:'+str(here==container)" />
   <div tal:replace="string:root:${root/getPhysicalPath}" />
   <div tal:replace="string:nothing:${nothing}" />
   <div tal:define="cgi python:modules['cgi']"
        tal:replace="python: dir(cgi)" />
  </metal:main>
 </body>
</html>
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
      xmlns:tal="http://xml.zope.org/namespaces/tal"
      xmlns:metal="http://xml.zope.org/namespaces/metal"
      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
      lang="en"
      metal:use-macro="context/main_template/macros/master"
      i18n:domain="plone">

 <body>
  <metal:main fill-slot="main">
    <table border="1">
      <tr tal:repeat="row python:['apple', 'banana', 'pineapple']">
        <td tal:repeat="col python:['juice', 'muffin', 'pie']">
           ${row/capitalize} ${col}
        </td>
      </tr>
    </table>
  </metal:main>
 </body>
</html>
Para realizar outros testes e aproveitar bem o Chameleon, leia a documentação[1] e sugiro a leitura dos códigos dos produtos Chameleon e five.pt.
 

| Comentários

Buildout, para o que der e vier Parte 2

Posted by Cleber J Santos at 28/06/2011 18:03
Em um post anterior mostrei que podemos utilizar o buildout para instalar praticamente qualquer aplicação que desejarmos, seja ela compilada ou não.
      Como no caso do WordPress, no qual se trata apenas de um pacote compactado e que exige a alteração de seus arquivos de configuração, e também a compilação do aplicativo spawn-fcgi, vale lembrar que caso desejado poderia até compilar o próprio PHP.
 
Neste post pretendo dar continuidade na instalação do ambiente, mostrando como compilamos o servidor Nginx para servir as páginas em PHP, ou em nosso caso, servir o WP, também iremos instalar o Supervisord (Sistema cliente/servidor que permite monitorar e controlar número de processos em sistemas operacionais UNIX-like.)

O buildout.
[buildout]
parts =
    ...
    supervisor
    nginx-build
    nginxctl
    default-server-config

...


[nginx-build]
recipe = zc.recipe.cmmi
url = http://nginx.org/download/nginx-1.0.4.tar.gz
extra_options =
    --with-http_gzip_static_module
    --with-http_stub_status_module
    --with-http_dav_module
    --with-http_ssl_module
    --with-http_flv_module
    --http-client-body-temp-path=${buildout:directory}/tmp
    --http-proxy-temp-path=${buildout:directory}/tmp/proxy
    --http-fastcgi-temp-path=${buildout:directory}/tmp/fastcgi
    --with-md5-asm --with-md5=/usr/include
    --with-sha1-asm
    --with-sha1=/usr/include
    --with-http_realip_module

[nginxctl]
recipe = gocept.nginx
nginx = nginx
configuration =
    daemon off;
    worker_processes 1;

    events {
        worker_connections  1024;
    }

    http {
        include            ${nginx:location}/conf/mime.types;
        default_type       application/octet-stream;
        sendfile           on;
        keepalive_timeout  65;

        include ${buildout:directory}/etc/nginx.conf;
    }


[default-server-config]
recipe = collective.recipe.template
input = ${buildout:directory}/etc/nginx.conf.in
output = ${buildout:directory}/etc/nginx.conf


[supervisor]
recipe = collective.recipe.supervisor
logfile = ${buildout:directory}/var/log/supervisord.log
logfile-backups = 10
loglevel = info
pidfile = ${buildout:directory}/var/supervisord.pid
plugins = superlance
user = admin
password = secret
port = 9001
programs =
	10 fcgi  ${buildout:directory}/parts/fcgi/bin/spawn-fcgi [ -a 127.0.0.1 -p 53217 -P ${buildout:directory}/tmp/fastcgi-php.pid -- /usr/bin/php-cgi] true
	20 nginx ${buildout:directory}/parts/nginxctl/sbin/nginx [ -c ${buildout:directory}/parts/nginxctl/nginxctl.conf] true
Pois bem, adicionamos mais 4 seções, e antes mesmo de continuar, vamos aos detalhes. No post anterior criamos uma pasta com o nome de tmp, agora note que na seção [nginx-build], indicamos alguns diretórios a serem usados pelo Nginx, que são: proxy e fastcgi.

Então crie estes dois diretórios e vamos seguir em frente, também teremos que criar dentro do diretório etc um arquivo com o nome nginx.conf, este contém as configurações para rodar-mos o WP, abaixo o conteúdo deste arquivo.
 
server {
    listen 80;
    server_name *.meusite.com;
    rewrite ^ http://www.meusite.com$request_uri permanent;
}

server {
        location / {
                root /home/cleber/buildout/wordpress;
                index  index.php index.html index.htm;
                fastcgi_index   index.php;

                # this sends all non-existing file or directory requests to index.php
                if (!-e $request_filename) {
                        rewrite ^(.+)$ /index.php?q=$1 last;
                }

                autoindex on;
        }

        location = /favicon.ico {
                empty_gif;
                log_not_found off;
                access_log off;
        }

        # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
        location ~ /\. {
                deny all;
                access_log off;
                log_not_found off;
        }

        try_files $uri $uri/ /index.php;

        location ~ \.php$ {
            include        /home/cleber/buildout/parts/nginx-build/conf/fastcgi_params.default;
            fastcgi_pass   127.0.0.1:53217;
            fastcgi_param  SCRIPT_FILENAME  /home/cleber/buildout/wordpress/$fastcgi_script_name;
        }
}
 
 Pronto, rode o buildout, e depois você já poderá desfrutar de sua aplicação, o supervisor irá criar um um script no diretório bin da instância, agora você pode startar as aplicações usando o comando:
./bin/supervisord

Nota. Vale lembrar que a porta 80 só pode ser aberta pelo root ou por um usuário com poder igual, neste caso estamos falando que o comando acima deverá ser rodado por um usuário com poderes de sudo ou root.

Até a próxima!

| Comentários

Buildout, para o que der e vier

Posted by Cleber J Santos at 25/06/2011 12:05
Buildout, para o que der e vier

Começo dizendo que durante algum tempo fui assombrado pelo buildout, desde a minha entrada na Simples até alguns meses depois, eu tremia sempre que eu tinha de rodar um, a primeira coisa que vinha na cabeça era: "Pronto, agora o ambiente vai ser destruído :(".

Trabalhar com alho no pescoço, pé de coelho e até mesmo trevo de 4 folhas não estava em meu escopo de trabalho, e não é muito meu tipo, pois bem, depois de algumas brigas decidi me tornar o melhor amigo do buildout, após alguns copos de café, e saindo juntos, decidimos fazer as pazes. 

Hoje posso garantir, que em qualquer situação onde preciso instalar alguma aplicação que vá ou não rodar com o Plone, penso no meu amigo buildout.

Duas pessoas que me tiraram esse medo e me deram coragem foi o amigo e inesquecível Dorneles, e também o amigo Érico

E agora a novidade é que não vou falar de como instalar Plone usando buildout, isso tudo para poder mostrar todo o poder do buildout, caso não saiba ainda do que estou falando acesso em http://www.buildout.org/docs/tutorial.html.

Buildout

  • É simples de usar e de manter se você fizer configurações simples e legíveis.
  • Trabalha com eggs.
  • Evita conflitos com os pacotes instalados no site_packages.
  • Evita a instalação diretamente no Python do sistema.
  • Instala dependências a partir das definições dos eggs.
  • Podemos instalar por exemplo:
    • Bancos de dados: PostgreSql, Mysql, Oracle e etc...
    • Serviço de autenticação como o LDAP.
    • Aplicações como: Versões diferentes de Python, Varnish,Squid, Supervisor e etc..
    • Frameworks: Django, Web2Py, Zope
    • CMS: Plone, WordPress e etc..
    • Servidores web: Apache, Nginx e etc...
    • E etc...
Vamos manter as coisas simples, então crie um diretório chamado mybuildout, dentro deste diretório crie a seguinte estrutura de pastas:
 
mybuildout
|- tmp
|- etc
|- src

Essa não é uma estrutura requerida pelo buildout, mas gosto de montar assim, garantindo que qualquer arquivo temporário vá ficar em
tmp por exemplo, arquivos de configurações em etc e aplicações em desenvolvimento em src, dois arquivos são requeridos, são eles: bootstrap.py e buildout.cfg.

Podemos não usar o buildout.cfg e montar o ambiente com outros aquivos, mas isso não vem ao caso, vamos a um exemplo do não uso do Plone, e para não dizerem que não gosto de PHP, iremos instalar o WordPress, então vamos lá.

NOTA. A instalação a seguir foi feita no sistema operacioal Linux (Ubuntu) sendo assim, não garanto que funcione no Windows, mas sim, temos como fazer funcionar da mesma forma no Windows e outros sistemas operacionais.

Também estou partindo do ponto que já temos php instalado no sistema, não quero ter que ficar compilando no buildut o PHP, ainda que dê claro ;)

Comento o buildout logo abaixo.

Instalando o WordPress usando Python, ironia?

[buildout]
parts =
    fcgi
    wp

[wpconf]
wpversion = latest.tar.gz
mydb_name = wp 
mydb_user = wp
mydb_pass = wpnginx
mydb_charset = utf8
mydb_host = localhost

[downloads]
wp_url = http://wordpress.org/${wpconf:wpversion} 
fcgi_url = http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz

[ports]
fastcgi = 53217

[fcgi]
recipe = zc.recipe.cmmi
url = ${downloads:fcgi_url}
configure-options = 
    --prefix=${buildout:directory}/parts/fcgi

[wp]
recipe = plone.recipe.command
command =
    chmod 600 .installed.cfg
    if [ ! -f ${buildout:directory}/${wpconf:wpversion} ]; then wget ${downloads:wp_url}; fi
    tar xzf ${wpconf:wpversion} 
    cp ${buildout:directory}/wordpress/wp-config-sample.php ${buildout:directory}/wordpress/wp-config.php
    ln -dfs ${buildout:directory}/wordpress ${buildout:directory}/var/www/wordpress
    sed -i "s/define('DB_NAME', 'database_name_here')/define('DB_NAME', '${wpconf:mydb_name}')/" ${buildout:directory}/wordpress/wp-config.php
    sed -i "s/define('DB_USER', 'username_here')/define('DB_USER', '${wpconf:mydb_user}')/" ${buildout:directory}/wordpress/wp-config.php
    sed -i "s/define('DB_PASSWORD', 'password_here')/define('DB_PASSWORD', '${wpconf:mydb_pass}')/" ${buildout:directory}/wordpress/wp-config.php
    sed -i "s/define('DB_HOST', 'localhost')/define('DB_HOST', '${wpconf:mydb_host}')/" ${buildout:directory}/wordpress/wp-config.php
    sed -i "s/define('DB_CHARSET', 'utf8')/define('DB_CHARSET', '${wpconf:mydb_charset}')/" ${buildout:directory}/wordpress/wp-config.php
    chmod +x ${buildout:directory}/bin/spawn-fcgi
update-command = ${wp:command

Criei duas seções que servirá para instalar o WordPress e um script de inicialização do php-cgi, este script também vem quando instalamos o servidor lighttpd, que é uma forma de manter o php vivo enquanto podemos dar um restart ou reload no servidor lighttpd, mas isso não vem ao caso.

Também criamos  3 outras seções que são:

wpconf - > Colocamos aqui as configurações do nosso WP, como dados da base de dados [usuário, senha etc ] e a versão que desejamos instalar do WP.
downloads -> Urls das aplicações, WP e fcgi.
ports -> Configuração da porta no qual o fcgi irá rodar

Note que na seção [wp], usei alguns comandos para fazer a mágica acontecer, quero baixar e descompactar o tar.gz, lembrando que em casos de arquivos zip, será necessário alterar a linha.  Após descompactar copiamos o arquivo wp-config-sample.php para wp-config.php, este será o que o Wp irá ler.

E por fim, setamos os dados de acesso ao bando de dados neste arquivo de configuração.

Rode o bootstrap e o buildout: python bootstrap.py && ./bin/buildout -Nvvv -t 30

Ao final teremos o o Wp instalado e pronto pra usar, é claro que faltam detalhes como instalar o servidor Apache ou Nginx, ou um de sua preferência.

Para subir o fcgi você pode executar: 

./parts/fcgi/bin/spawn-fcgi -a 127.0.0.1 -p 53217 -P ./tmp/fastcgi-php.pid -- /usr/bin/php-cgi

A configuração acima, usei com o servidor Nginx, também compilado com buildout, por este motivo adicionei o fcgi, abaixo sugestões de eggs que ajudam nas instalações.

Sugestões.

| Comentários

Botões para compartilhar nas redes sociais.

Posted by Cleber J Santos at 21/04/2011 09:14
Botões para compartilhar nas redes sociais.

Cada vez mais tem crescido o número de redes sociais, e claro não tem melhor maneira de divulgar e compartilhar posts do seu Blog e notícias do seu WebSite ou portal se não através dessas redes. Você já deve ter visto em outros sites, botões para compartilhar posts nas principais redes sociais, como Twitter e Facebook.

Existem diversos produtos que proporciona funcionalidades de compartilhamento para essas redes, e dentre estes vou falar de dois que são:

Ambos os produtos nos proporcionam recursos de compartilhamento de conteúdos do nosso site Plone, porém cada qual tem sua caracteristica, o sc.social.like é um produto mais simples que após instalado irá provê os botões para compartilhamento do Twitter e Facebook, estes botões ficam localizados logo abaixo do título do conteúdo em questão.

Tendo uma interface de configuração no qual pode-se alternar entre os botões recomendar e Curtir do Facebook, e as disposições vertical ou horizontal de ambos os botões, assim como configurações para quais tipos de conteúdos serão exibidos.

Enquanto o sc.social.bookmarks mostra-se como um produto mais completo, provendo um número maior de redes sociais para compartilhamento como Delicious, Digg, Reddit e Twitter e etc... Sendo 62 serviços já inclusos, ao contrário do sc.social.like, ele se dispõe no roda pé do conteúdo.Também é configurável, no qual  pode-se escolher em para quais tipos de conteúdos será exibido.


Qual devo usar?

Como dito, cada qual tem suas caracteristicas, ainda que pareçam servir para o mesmo propósito, temos aqui um produto mais simples e outro mais completo, cabe a você escolher qual usar, o bookmarks não tem por exemplo um contador como no caso dos botões do like, neste caso para sites que desejam mostrar e também saber quantas vezes foram compartilhados determinado conteúdo de seu site, é mais recomendado o uso do like.

Agora para sites que apenas querem disponibilizar aos seus usuários um maior número de redes para que possam compartilhar, fica a recomendação o uso do bookmarks, ou ainda pode-se utilizar ambos, e aproveitar o que cada qual dispõe. Seja qual for a sua escolha, estes são produtos que acredito serem essenciais em um site.

| Comentários

O sabor de diversas versões Python para Linux e OSX usando o collective.buildout.python

Posted by Cleber J Santos at 24/10/2010 20:50

Aproveitando a onda dos Buildouts, agora você pode instalar versões do interpretador Python (2.4, 2.5, 2.6, 2.7 e 3.1) no sistema *UNIX ou OSX, e assim melhor trabalhar com seus projetos de Buildout sem medo de ser feliz.

O sabor de diversas versões Python para Linux e OSX usando o collective.buildout.python | Comentários

Read More…

Document Actions
Spinner