Problema de desempenho: atraso na primeira solicitação

36

Eu montei um site D7 com um subtema Minelli. Ao longo do caminho, experimentei muito com diferentes temas, diferentes módulos. Em algum lugar ao longo do caminho, desenvolvi um problema de desempenho estranho e agora não sei realmente qual tema / módulo / configuração o causou.

O problema é que, quando visito o site pela primeira vez, leva cerca de 15 segundos para que a primeira página seja exibida. Posso então me mover pelo site e ele é muito responsivo. Se eu deixar por mais ou menos uma hora e depois voltar, a primeira solicitação será novamente muito lenta.

Eu limpei o cache para que esse não seja o problema. Além disso, desativei temas e módulos que não estou usando. Mudei o site para uma nova infraestrutura, mas o problema se seguiu!

Para onde eu vou a seguir?

Kim Prince
fonte
2
Não posso dizer o quanto eu gostaria de resolver isso também. Minha teoria de trabalho é que, depois de uma hora ou mais, o cron foi executado (liberando os caches) e a primeira solicitação demora um pouco devido à necessidade de todas essas consultas de banco de dados não armazenadas em cache. Mas eu só estou supondo
Clive
Eu tenho o mesmo problema. permitindo o armazenamento em cache para usuários anônimos resolveu o problema, mas estou ciente de que não é uma boa solução
znat
@Kim: Eu queria saber se você encontrar a origem do problema e / ou uma boa solução
znat
2
Algumas respostas mencionam o cron do pobre homem: alguém pode experimentar o problema confirmar se disparam o cron usando um crontab ou se dependem do cron do pobre homem?
213 Andy Andy
6
Na verdade, se for cron, provavelmente não é apenas cron, mas update_cron () que procura novos lançamentos, que pode demorar um pouco. tente desativar o update.module para verificar se esse é o problema.
Berdir 5/08/12

Respostas:

16

Há três coisas que eu verificaria.

Primeiro, se você estiver em um site de produção e não estiver editando arquivos PHP, deverá garantir que a APC esteja ativada, tenha memória suficiente e um TTL longo (você pode passar um dia ou nunca expirar, se quiser). Você também pode considerar a configuração apc.stat=0. Os documentos da APC têm todas as informações necessárias para definir o TTL. Para escolher a quantidade de memória, você deve colar o arquivo apc.php em algum lugar protegido e monitorar as estatísticas de uso e rotatividade da memória. Ajuste a memória da APC para que sua taxa de perda seja muito baixa. A lentidão inicial pode ocorrer porque o APC está cheio e esvaziado (IIRC, o APC descarta o cache inteiro quando está cheio, em vez de empregar LRU ou estratégias de cache mais avançadas).

Segundo, verifique se o MySQL foi ajustado adequadamente. Você pode usar o mysqltuner para ajustar seus tamanhos de buffer. Sua lentidão inicial pode ser devido ao carregamento de tabelas do disco e / ou falhas no cache de consulta. Embora não seja perfeito, o mysqltuner leva você na direção certa.

Terceiro, verifique se você tem uma estratégia cron real do Drupal . Pessoalmente, eu desabilitaria o cron automagic em "admin / config / system / cron" e configurava um crontab para executar todas as noites. Você também pode experimentar o Elysia Cron se realmente precisar de um controle mais refinado sobre as coisas. Dessa forma, você pode executar as tarefas necessárias quantas vezes precisar, mas executar as tarefas normais da noite para o dia. Sua lentidão inicial pode ser de execuções cron que acontecem a cada hora. Você pode confirmar isso observando quando o cron é executado em "admin / reports / dblog" e tentando corresponder à sua lentidão.

mpdonadio
fonte
Eu descobri que quase todas as pilhas de dev AMP (M / L / W), mesmo aquelas especificamente para Drupal como Bitnami, estão mal ajustadas ou não estão ajustadas (acho que a pilha dev de Acquia é a exceção). E é claro que a instalação padrão do mySQL para uma máquina de produção não é. Os arquivos de log do InnoDB são por padrão, como 5M, e a memória alocada é minúscula. Freqüentemente, é necessário um ajuste adequado para tornar o site instável - basta apenas inserir o my-medium.cnf ou o my-large.cnf.
Renee
Havia tantas boas respostas para essa pergunta, obrigado a todos que viram esse comentário e contribuíram para a publicação. Eu pensei que essa resposta em particular resumia as principais questões de maneira agradável e sucinta; A verificação cuidadosa desses 3 pontos ajudou a acelerar os sites do Drupal em várias máquinas diferentes. Obrigado @MPD
Clive
9

Ivanhoe123 provavelmente está certo: o Drupal 7 vem com 'pobre homem cron' ativado por padrão. Em resumo, significa que (de vez em quando) o cron é executado antes que o Drupal renderize a página, atrasando tudo.

Sempre tente usar um trabalho cron real nos sites de produção. Para mais detalhes técnicos, consulte http://drupal.org/cron ou fale com sua empresa de hospedagem.

Para desativá-lo, vá para admin / config / system / cron e selecione 'Never'.

Attiks
fonte
Não acho que desativar o cron esteja resolvendo o problema, provavelmente ocultando-o para mais tarde. Mas pelo menos eu acho que você pode restringir o problema de desempenho um pouco para baixo;)
WIIFM
11
Attiks não está dizendo para desativar o cron; ele está dizendo para alterar a opção de chamar tarefas cron quando qualquer usuário estiver visitando uma página no site. Essa é uma opção específica que é o Drupal 6 foi implementada no módulo Poormanscron . Alterar essa opção não significa desativar tarefas cron.
kiamlaluno
8

O módulo Devel oferece log de banco de dados para verificar se você possui alguma consulta de longa duração.

Se isso não ajudar, pegue o XHProf ou o XDebug e encontre o código culpado. O XHProf (um criador de perfil) desenha um bom mapa de todas as funções que estão sendo executadas no servidor e indica quais estão consumindo mais tempo de execução. Por outro lado, quando o XDebug (um depurador) é configurado com um IDE como o Eclipse ( veja o vídeo ), permite detalhar todas as funções que estão sendo executadas LIVE. O criador de perfil lhe dará uma idéia do que está sendo executado; enquanto o depurador mostrará por que está sendo executado.

BetaRide
fonte
2
Sim, existem muitas razões possíveis para algo como isso, colocar o XhProf em xx é geralmente a melhor maneira de encontrar o problema real.
Berdir 06/07/12
6

Apenas pelo sabor da pergunta, penso imediatamente em três (3) coisas

  • MySQL Storage Engine / CPU
  • Cache de banco de dados
  • Travamento da mesa

MySQL Storage Engine

Se você não estiver usando nenhuma pesquisa / indexação do FULLTEXT, recomendo fortemente que você converta todos os seus dados do MyISAM em InnoDB. O MyISAM não foi projetado para tirar proveito de várias CPUs e múltiplos núcleos. O InnoDB foi bastante aprimorado para o uso múltiplo da CPU, bem como para leitura / gravação de hyperthreading.

Aqui estão algumas postagens que eu fiz sobre isso no DBA StackExchange e neste site com relação ao ajuste do MySQL para o InnoDB Performance

Cache de banco de dados

Outro argumento forte para converter todos os dados do MyISAM para o InnoDB é como o MySQL armazena em cache dados / índices. O MyISAM Storage Engine apenas armazena em cache os índices. O InnoDB armazena em cache dados e índices . À luz disso, você pode alocar memória suficiente para o InnoDB Buffer Pool para acomodar um dos seguintes itens (o que for menor)

  • Todos os dados e índices do InnoDB (ideal se você tiver RAM suficiente para isso também para o sistema operacional; elimina atrasos subseqüentes)
  • 75% da RAM instalada (caso você tenha mais dados / índices do InnoDB que a RAM; minimiza atrasos)

Se você estiver usando o MySQL 5.1, poderá definir innodb_max_dirty_pages_pct = 0. Isso aumentará um pouco a E / S do disco, mas o InnoDB Buffer Pool será limpo o suficiente para permitir a rotação de dados e páginas de índice antigas sem surtos de E / S do disco. O MySQL 5.5 e o InnoDB Plugin do MySQL 5.1 não precisam desse ajuste, pois ele possui um melhor mecanismo de liberação padrão do Buffer Pool.

Se o uso do InnoDB estiver fora de questão, talvez você precise usar o memcached ou o verniz. Isso permite que o desenvolvedor determine quanto tempo os dados armazenados em cache residirão na RAM do servidor. Naturalmente, isso exigirá aprimoramento no desenvolvimento para tornar seu aplicativo compatível com memcached / verniz.

Travamento da mesa

Epílogo

Você não pode evitar um atraso inicial após uma reinicialização do MySQL. No entanto, uma vez que você aprimora o MySQL usando as sugestões / informações acima mencionadas, não deve mais sofrer atrasos subsequentes.

RolandoMySQLDBA
fonte
Informação realmente útil, obrigado. Esses problemas seriam capazes de explicar esse problema acontecendo com tanta regularidade / consistência? A maioria dos relatórios que vi estimam que a inatividade no site por 30 a 60 minutos resulta no atraso do retorno do carregamento da página inicial
Clive
2
@Clive Para todos os bancos de dados MyISAM, isso acontecerá se as páginas de índice MyISAM carregadas no cache de chaves MyISAM horas atrás e não utilizadas por um longo período de tempo forem giradas para fora. A chamada desses dados desativados exigirá leituras de disco para o MyISAM. Esse mesmo comportamento também pode ocorrer para o InnoDB, principalmente se o buffer do InnoDB for muito pequeno. Como o InnoDB armazena em cache os dados e as páginas de índice, a conversão de todo o MyISAM em InnoDB e o uso de um grande buffer pool do InnoDB pode minimizar ou até eliminar esses problemas de carregamento de página.
RolandoMySQLDBA
Ótimo, eu vou fazer alguns perfis com base nisso, então, parece promissor. Mais uma vez obrigado
Clive
2
@Clive Gostaria de recomendar o uso de mk-query-digest ou pt-query-digest para fazer sua criação de perfil. Eu escrevi um roteiro agradável no DBA Stackexchange ao perfil cada intervalo fixo de um crontab: dba.stackexchange.com/a/8382/877
RolandoMySQLDBA
5

Eu usaria ferramentas como YSlow ou Firebug etc. para determinar exatamente o que está acontecendo quando você carrega a página e quando carrega a página imediatamente depois. Verifique se é um problema de armazenamento em cache e, além disso, verifique como ele funciona quando você acessa a página como um usuário anônimo e, em seguida, como um usuário autenticado. Compare isso com as configurações de desempenho no Drupal.

Se não for um problema de cache, use o log de consultas do Devel e os logs do MySQL para ver o que está acontecendo no banco de dados. Além disso, se você tiver códigos de operação ou caches similares para melhorar o desempenho no servidor, tente desabilitar alguns números com eles e ligá-los novamente.


fonte
4

Parece que o cron está em execução.

Verifique suas configurações aqui: admin / config / system / cron

Aram Boyajyan
fonte
3

Eu quase derrubei o Drupal no meu último projeto por causa disso.

Mas deve haver mais de uma causa. Ainda estou para encontrar uma solução "corrigir tudo" que funcione sempre que esse problema surgir.

Syslog e Ubuntu / Debain

A primeira vez que deparei com o tempo de carregamento intermitente de 15 segundos foi durante a execução de drupal em sistemas Debian / Ubuntu (dedicados, não compartilhados). Desabilitar o módulo Syslog foi a solução para mim.

Como o @BetaRide disse, o uso do xDebug ou de outro profiler do PHP é extremamente esclarecedor.


Ainda um problema - uma solução alternativa

Quanto às minhas outras instalações, ainda estou perdida.

Esse problema é mais perceptível no meu servidor de desenvolvimento e no meu Drupal de baixo tráfego.

Como solução alternativa, configurei um trabalho cron para carregar a página inicial do site a cada 60 segundos, bem como o script cron do Drupal a cada 300 segundos. Obviamente, isso não é o ideal, mas eu preferiria experimentar ou enrolar o tempo de carregamento de 15 segundos em vez de um visitante humano.

Citricguy
fonte
3

Muitas pessoas sugerem que esse problema pode estar relacionado ao bloqueio de processos em segundo plano síncrono , principalmente relacionado a trabalhos cron pesados .

Se for verdade, existe um ótimo par de módulos em desenvolvimento ativo por gielfeldt * que pode resolver esse problema, ou pelo menos, pode oferecer algumas pistas e ajudar os construtores de sites a diagnosticar e tratar culpados específicos em seus casos. Ambos substituem processos síncronos de bloqueio por HTTP ou comandos assíncronos sem bloqueio e oferecem relatórios relevantes que podem identificar processos problemáticos:

  • O processo em segundo plano e seus módulos incluídos permitem que a fila de processos em segundo plano do Drupal seja processada de forma assíncrona, para que não bloqueiem. Isso pode parar o problema. Além disso, com o módulo do Process Process Apache Server incluído no último desenvolvedor, há um relatório básico da interface do usuário, porém aprimorado, com recursos para supervisionar, desbloquear e inspecionar os horários de início e o andamento desses processos. Isso pode identificar o processo do problema.
  • O Ultimate Cron baseia-se no processo em segundo plano para permitir que as tarefas acionadas por cron tenham seus próprios scehdules assíncronos separados, cada um dos quais pode ser monitorado e parado em uma interface do usuário. Além de ser excelente para separar tarefas pesadas de perda de desempenho de uma limpeza regular com pouca sobrecarga, ele também fornece um relatório com informações convenientes, como a duração da execução de cada tarefa acionada por cron individual, na última execução, status atual, etc. Isso também pode remover o bloqueio e / ou identificar processos problemáticos.

Ambos são módulos muito úteis de qualquer maneira; para esse problema, eles podem ser usados ​​para testar a teoria (som muito plausível) de que os bloqueios são causados ​​por processos de bloqueio síncrono ou execuções cron. Potencialmente, eles poderiam resolver o problema executando-os de forma assíncrona em vez de síncrona, e também poderiam oferecer pistas sobre quais processos específicos estavam causando o atraso. (lembre-se de que a documentação deles é um trabalho em andamento ...

Se, no entanto, eles não puderem ser configurados para ajudar, isso sugere que há mais problemas do que apenas processos em segundo plano síncronos. FWIW, eu nunca tive esse problema específico em um site desde que esses módulos funcionaram corretamente (ainda - toque em madeira) - mas eu já vi isso em meus sites antes, assim como em sites Drupal ao vivo.

Também esteja ciente de outros módulos de plug-in relacionados atualmente em desenvolvimento - por exemplo, em casos complexos de alta intensidade, o Ultimate Cron Queue Scaler , que permite a otimização baseada em limites, pode ajudar a reduzir problemas de desempenho relacionados ao cron.


* sem afiliação, sou apenas um usuário impressionado do trabalho deles

user56reinstatemonica8
fonte
2

Como isso está me atingindo mais uma vez, eu começo a investigar o problema. Definitivamente, posso confirmar que

  1. uma chamada drupal_cron_run()acionada pelo cron do núcleo do poorman adiciona ~ 5s ao tempo de solicitação na minha máquina de desenvolvimento. Isso pode ser testado descomentando os testes em torno da chamada para drupal_cron_run()em modules/system/system.moduleemsystem_run_automated_cron()
  2. limpar todos os caches adiciona ~ 2s ao tempo de solicitação na minha máquina de desenvolvimento. Isso pode ser testado fazendo um drush cc alle recarregando a página novamente.

Isso significa que configurar o cron como nunca e adicionar uma chamada ao cron via crontab torna a situação muito melhor. Atingir algumas páginas frequentemente usadas logo após o reabastecimento do cache melhoraria novamente a experiência do usuário.

Ainda não tenho certeza sobre o cache. Não toquei nas configurações de cache padrão deste site. Eu acho que o drupal está reconstruindo todos os caches de tempos em tempos, talvez acionado pelo cron, mas não tenho certeza de como isso é feito. Mas um atraso de 7s é praticamente o que vejo quando chego à página depois de algumas horas.

BetaRide
fonte
1

Problemas como esse podem deixá-lo maluco e, quando estive em situações semelhantes, ajuda a descobrir o que está causando o problema dando um passo de cada vez e testá-lo como um usuário anônimo e registrado. (método da camada de cebola)

Você mencionou que começou a perceber o problema depois de jogar com alguns temas e codificação personalizada. Não sei quão complexo é o seu site nem a lógica por trás dele, mas as etapas a seguir ajudarão você a encontrar o problema:

  1. No seu servidor, crie uma pasta ou outra conta (isso pode ser melhor) em que você fará uma instalação limpa do Drupal com a mesma versão que você está usando em seu site. Então, sem adicionar nenhum módulo ou tema, teste o tempo que o site leva para responder à primeira solicitação e à seguinte. Se tudo funcionar bem, você poderá ignorar os problemas de configuração do servidor, se estiver se comportando da mesma forma que o seu atual, haverá um erro de configuração no servidor da Web ou no banco de dados.

  2. Se os resultados da etapa 1 forem bons e o servidor estiver respondendo rapidamente e as solicitações a seguir forem rápidas, instale apenas o tema do site atual no site de instalação limpa e teste-o novamente. Se tudo ainda responder rapidamente, seu tema não será o problema e você deverá continuar na etapa 3, caso contrário, precisará iniciar a depuração do tema * 1.

  3. Se, após os testes na etapa 2, o site ainda começar rapidamente a trazer os módulos em seu site atual, certifique-se de testar o tempo de resposta após adicionar e ativar cada módulo * 2.

  4. Se, após adicionar o tema e os módulos, o site ainda responder rapidamente, adicione a configuração, crie tipos de conteúdo, importe visualizações, menus de configuração etc. Não se esqueça de testar a resposta do site após adicionar cada um.

  5. Pronto para instalação e configuração e o site ainda rápido, agora traga os dados. Nós de importação, termos de taxonomia, comentários etc. Sei que devo parecer um registro quebrado, mas sempre teste depois de concluir cada etapa.

* 1 Temas de teste: esse processo pode ser complicado em um tema super elaborado, eis algumas dicas:

  1. Se você vincular a qualquer biblioteca js ou css externa, tente usar uma cópia local da mesma.

  2. No arquivo template.php, verifique a função que pode ter loops mais longos ou infinitos, bem como a função de pré-processamento e / ou as funções do tema do gancho.

  3. Verifique outro arquivo de modelo (page.tpl.php, etc) e procure o processamento PHP bruto de matrizes e objetos.

  4. Se estiver usando "Visualizações" e visualizando arquivos de modelo, verifique também.

  5. Sempre verifique os caminhos, otimize imagens, arquivos js e css. Às vezes, os arquivos js podem ter uma grande altura quando usam vários trechos de código em um único arquivo.

* 2 Módulos de teste : o módulo de teste é um pouco diferente porque é permitido o uso de manipulação pesada com PHP. Aqui estão algumas dicas:

  1. Os módulos suportados pela comunidade (CCK, Views, etc) têm fila de problemas no drupal.org, verifique-os para ver se há algum problema existente sobre o seu problema e se há chances de que exista um patch para corrigi-lo.

  2. Próprio módulo codificado, bem, se você codificou, precisa corrigi-lo, certo? Verifique sua codificação e verifique o uso das funções em api.drupal.org, você pode estar usando uma função de overkilling em vez de um gancho.

  3. Módulo de código personalizado compartilhado da Internet, faça o mesmo na etapa 2, mas desta vez também é possível entrar em contato com o gravador do módulo original e informar sobre o problema.

  4. Se seu site for uma atualização (D5 -> D6 -> D7), verifique os scripts de migração ou atualização (geralmente no arquivo module.install), talvez seja necessário um "índice" extra na nova configuração da tabela para acelerar a consulta SQL lenta X mais rapidamente .

  5. Se você acha que tem uma visão de túnel sobre o problema, saia um pouco e faça alguma outra atividade completamente não relacionada e volte mais tarde para revisar o problema.

  6. Se você executar o ping em um ponto do código, mas não conseguir entender como corrigi-lo, tente explicar o que essa seção deve fazer para uma pessoa que não tem idéia de como programar ou como o Drupal funciona e pronto para ser surpresa.

Nota: Não se assuste se, depois de reconstruir o site, todos começarem a funcionar como um encanto, que é um dos melhores recursos dos computadores.

Emil Orol
fonte
11
Acabei de reinstalar um drupal em branco e sem demora. Então, o próximo passo é empurrar meu tema. No entanto, ele vai ter um monte de tempo desde que eu tenho que esperar por meia hora para a emissão de repetir
znat
11
Fico feliz em saber que não parece ser um problema de configuração de hardware ou servidor. Envie suas descobertas.
Emil Orol
1

Verifique se você não excluiu nenhum módulo sem desinstalá-lo. Isso causa um atraso, porque o Drupal tenta encontrar os arquivos, mas eles não estão mais lá.

Exclua as referências na tabela de variáveis ​​se os módulos não existirem mais.

olho de Gato
fonte
1

Um APM da Web, como o newrelic, é a melhor ferramenta para rastrear problemas de desempenho. Já tive sites chamando uma ou duas linhas de código que faziam coisas estranhas, carregavam matrizes desnecessárias em momentos estranhos e faziam outras coisas que eram bastante invisíveis até encontrá-las com um APM.

beth
fonte
1

Alguém mencionou que o GoDaddy será lento. Muitas empresas de hospedagem baseada em nuvem também terão esse atraso inicial, porque serviços como a AWS o possuem. É mais barato ter servidores desprioritizados automaticamente, e esses servidores precisarão de um ou dois segundos para serem ativados.

Por exemplo, o Pagodabox possui de 3 a 4 segundos para o primeiro byte, até que o servidor esteja feliz. De fato, o Pagodabox monetizou mantendo o servidor acordado, e assim você pode pagar mais para "garantir" seu site.

Além disso, uma CDN pode ajudá-lo. Seu servidor da web / db não será carregado com a veiculação de páginas ou imagens em cache. Um bom tutorial aqui: http://wimleers.com/article/easy-drupal-cdn-integration-for-fun-and-profit

E ... WebPageTest me deixa feliz. http://www.webpagetest.org/ Compare os tempos de carregamento em todo o planeta e com diferentes navegadores da web gratuitamente. Use isso para obter resultados do mundo real para quaisquer alterações que você estiver fazendo.

paul-m
fonte
Esta é uma boa informação para ter, mas o problema ainda ocorre em sites na minha máquina local, consumindo apenas recursos locais
Clive
0

o problema pode estar em qualquer lugar.

  1. Verifique se você não ativou o modo de depuração em nenhum tema ou módulo. Por exemplo, em muitos temas, há uma opção para regenerar o registro de temas.
  2. Se você estiver executando em uma hospedagem compartilhada como o Godaddy, 15 segundos pela primeira vez é normal.
  3. Converta seu site ou página inicial em base de código usando o módulo Drush CTools Export . Isso eliminará qualquer chamada ao banco de dados e seu site será executado inteiramente a partir do php.
  4. Se você ainda tiver problemas, use as configurações Devel ligando query loge page timeropções no admin/config/development/devel. Veja qual dos dois leva mais tempo para gerar a página inteira.
  5. Reinicie o servidor se nada funcionar.
  6. No pior caso, instale o XHProf para ver onde as coisas estão dando errado.
Minty
fonte
11
Você pode explicar o número 2?
31412 John John Elmore
0

Então foi assim que eu corrigi o problema para minha instalação. Não é uma solução real, pois não consegui identificar a fonte exata do problema (se houver), mas é uma boa solução.

1) CSS agregado (configurações de cache). Isso reduziu a latência pela metade

2) Defina cron como nunca (e execute-o externamente) - Nota: Eu tive "tentativas de iniciar o cron enquanto ele já está em execução". Eu acho que estava tentando iniciar o cron a cada lançamento, mas, como falhou, a página do cron não mencionava a tentativa mais recente, mas o sucesso mais recente.

3) Configure um trabalho cron que chame a página inicial com o Lynx a cada 30 minutos

Tudo isso em um servidor de hospedagem compartilhada. Não é o ideal, mas funciona

znat
fonte
0

Eu sugeriria o uso de um cache de front-end ao longo das linhas do módulo Boost (supondo que você esteja compartilhando hospedagem) ou Varnish. Isso funcionará melhor se o acesso ao seu site for principalmente anônimo e o conteúdo da página não for dinâmico (em geral, as páginas não mudam muito).

Essas soluções salvam as páginas renderizadas no primeiro acesso e, em seguida, atendem ao html pré-renderizado, em vez de passar pelo processo completo de inicialização do Drupal, criação de página e temas, economizando muito tempo, especialmente em sites ocupados, mas também em sites como você. descreva quais "vão dormir" e demore muito para acordar.

A única desvantagem real é que (pelo menos para o Boost) você precisará limpar o cache quando o conteúdo do site for alterado. Se você deseja garantir que o site esteja totalmente armazenado em cache com o conteúdo atual, execute drush cc all e, em seguida, faça uma espiral ou wget no site completo periodicamente, via cron.

jmarkel
fonte