É um aplicativo PHP. Como posso minimizar o tempo de inatividade ao atualizar toda a base de código?
É um aplicativo PHP. Como posso minimizar o tempo de inatividade ao atualizar toda a base de código?
Respostas:
O que geralmente fazemos no trabalho é:
/www/app-2009-09-01
/www/application
/www/app-2009-09-08
/www/application
, mas que aponta para as novas fontes:/www/app-2009-09-08
Todo esse processo é feito através de um script automático (a única coisa não automática é lançá-lo quando necessário). Isso significa :
Outra vantagem dessa precedência de link simbólico é que é muito fácil "reverter" uma atualização se notarmos um erro catastrófico somente após colocar a nova versão das fontes em produção: basta mudar os links simbólicos.
Obviamente, isso não impede que você teste a nova versão em seu servidor intermediário antes de colocá-la em produção - mas, quem sabe ... Às vezes, há um bug muito grande que ninguém conseguiu ver enquanto testing :-(
Por exemplo, porque não há testes de carga realizados regularmente na máquina de preparo
(vi a coisa de "reversão" usada algo como 4 ou 5 vezes em 3 anos - a cada vez, salvou o dia - e os sites ^^)
Aqui está um exemplo rápido: suponha que eu tenha esse VirtualHost na minha configuração do Apache:
<VirtualHost *>
ServerName example.com
DocumentRoot /www/application
<Directory /www/application>
# Whatever you might need here (this example is copy-pasted from a test server and test application ^^ )
Options Indexes FollowSymLinks MultiViews +SymLinksIfOwnerMatch
AllowOverride All
php_value error_reporting 6135
php_value short_open_tag on
</Directory>
</VirtualHost>
Bastante "padrão" ... A única coisa é que /www/application
não é um diretório real: é apenas um link simbólico para a versão atual das fontes.
O que significa que quando você colocar as fontes no servidor, mas ainda não tiver alternado, terá algo parecido com isto:
root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root 19 2009-09-08 22:08 application -> /www/app-2009-09-01
Observe que o symlinc aponta para a "versão antiga"
Agora, que a nova versão foi totalmente carregada no servidor, vamos mudar:
root@shark:/www
# rm /www/application
root@shark:/www
# ln -s /www/app-2009-09-08 /www/application
E, agora, os /www/application
pontos para a nova versão das fontes:
root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root 19 2009-09-08 22:09 application -> /www/app-2009-09-08
E nós apenas temos que reiniciar o Apache:
root@shark:/www
# /etc/init.d/apache2 restart
* Restarting web server apache2
As três etapas " remova o link; crie o novo link; reinicie o apache " devem ser feitas rapidamente; isto é, por um script automatizado, e não por um ser humano.
Usando esta solução:
E se usar algum cache de código de operação como APC com a opção stat em 0, isso pode significar ainda menos risco de tempo de inatividade, suponho.
Obviamente, esta é a versão "simples" - se você tiver alguns arquivos enviados, por exemplo, precisará usar outro link simbólico em algum lugar, ou outro VirtualHost ou o que for ...
Espero que isso seja mais claro :-)
Você não pode pegar o código existente e migrar o projeto para um arquivo php de teste separado, e usá-lo enquanto faz suas atualizações? O que quero dizer é que você deve ter um servidor de teste e um servidor de produção para que, quando precisar fazer uma atualização, não ocorra nenhum tempo de inatividade.
Configure um segundo servidor com a base de código atualizada e troque-o o mais rápido possível. :-)
Se não for possível, verifique se a sua base de código está dividida em dezenas de partes menores. Em seguida, o tempo de inatividade seria limitado a apenas uma subparte uma por vez. Os bloqueios de código menores são mais fáceis de substituir e a maioria continuará funcionando sem problemas. Apenas tente isso em um ambiente de teste primeiro!
Primeiro, eu frequentemente uso e gosto de um método semelhante à resposta de Pascal MARTIN.
Outro método que eu também gosto é usar meu SCM para enviar novos códigos. O processo exato depende do seu tipo de SCM (git vs svn vs ...). Se você estiver usando svn, eu gosto de criar uma ramificação "online" ou "produção" que faça checkout como raiz do documento no servidor. Então, sempre que eu quiser enviar um novo código de outra ramificação / tag / tronco, apenas submeto o novo código na ramificação "online" e execute o svn update na raiz do documento. Isso permite reversões muito fáceis, pois há um log de revisão completo do que foi subido / descido para o servidor e quem fez e quando. Você também pode executar facilmente essa ramificação "online" em uma caixa de teste, permitindo verificar o aplicativo que está prestes a enviar.
O processo é semelhante para o git e outros estilos de SCM, apenas modificado para ser mais natural para o estilo de fluxo de trabalho.
Deseja receber / pesquisar em vez de enviar atualizações? Basta ter um trabalho cron ou outro mecanismo mais inteligente, executar automaticamente o svn update.
Extra: você também pode usar esse processo para fazer backup de arquivos que seu aplicativo gravou no disco. Apenas tenha um trabalho cron ou algum outro mecanismo execute svn commit. Agora, os arquivos criados por seu aplicativo são armazenados em backup no SCM, na revisão registrada etc. (por exemplo, se um usuário atualiza um arquivo no disco, mas deseja que você o reverta, basta pressionar a revisão antiga).
Também uso uma abordagem semelhante à de Pascal MARTIN. Mas, em vez de carregar várias versões do meu aplicativo no servidor de produção, mantenho as "construções" atrás do meu firewall, cada uma em um diretório separado com o número e a data da construção. Quando quero fazer upload de uma nova versão, uso um script simples que inclui "rsync -avh --delay-updates". O sinalizador "delay = updates" fará o upload de tudo (diferente) para uma pasta temporária até que todas as atualizações estejam lá e depois mova tudo de uma só vez no final da transferência para os caminhos adequados, para que o aplicativo nunca esteja em um estado meio-velho-meio-novo. Ele tem o mesmo efeito que o método acima, exceto que eu apenas mantenho uma versão do aplicativo no site de produção (é melhor ter apenas os arquivos essenciais básicos no servidor de produção, IMO).