Implantando novo código ao vivo

28

Qual é a melhor prática para implantar novo código em um site ao vivo (e-commerce)?

Por enquanto, parei o apache por +/- 10 segundos ao renomear o diretório public_html_new para public_html e antigo para public_html_old . Isso cria um tempo de inatividade curto antes de eu iniciar o Apache novamente.

A mesma pergunta ocorre se você usar o Git para puxar o novo repositório para o diretório ativo. Posso puxar o repo enquanto o site está ativo? E se eu precisar copiar um banco de dados também?

Durante a compactação de tar (finalidade de backup) do site ativo, notei que ocorreram alterações no diretório de mídia. Isso me indicou que os arquivos continuam mudando periodicamente. E se essas alterações puderem interferir se o Apache não for interrompido durante a implantação.

    
por nicoX 12.08.2014 / 14:08

8 respostas

13

Usar um balanceador de carga é uma boa ideia. Se o site for importante o suficiente para se preocupar com alguns segundos de inatividade, é importante se preocupar com a tolerância a falhas.

Além disso, se estiver em um sistema UNIX, você pode colocar o Apache em espera durante a renomeação (ou atualização de link simbólico, etc.):

killall -STOP httpd  # Pause all httpd processes
mv public_html public_html_orig
mv public_html_new public_html
killall -CONT httpd  # Resume all httpd processes

Isso impedirá que o Apache aceite novas solicitações durante a renomeação. Se você prefere links simbólicos ou alguma outra abordagem, a mesma ideia pode ser usada:

killall -STOP httpd  # Pause all httpd processes
rm /var/www/html
ln -s /var/www/version/03 /var/www/html
killall -CONT httpd  # Resume all httpd processes

Observe que qualquer conexão ou pacote pendente entrará na fila no sistema operacional. Para um site extremamente ocupado, considere ajustar o ListenBacklog, se apropriado para o tipo de trabalhador httpd, e verifique as configurações do sistema operacional relacionadas ao backlog de escuta do TCP.

Você também pode alterar o DocumentRoot no httpd.conf e fazer uma reinicialização normal ( apachectl graceful ). A desvantagem aqui é o aumento do risco de erros, já que você teria que atualizar qualquer configuração Directory .

    
por 14.08.2014 / 16:53
32

O mais rápido e mais fácil é usar um diretório de versão, como

/var/www/version/01
/var/www/version/02

e use um link simbólico atual como seu html_root:

/var/www/html -> /var/www/version/02

Esta técnica integra-se perfeitamente em um sistema de controle de revisão (svn, git, mercurial, ...), como você pode verificar ramificações & tags, altera o link simbólico e recarrega o Apache. O tempo de inatividade é mínimo usando essa técnica e permite reversão muito fácil .

Ele também se integra bem ao sistema de implantação mais complexo, como pacotes RPM ou infra-estrutura de gerenciamento de alterações de configuração (chef, boneco etc.).

    
por 12.08.2014 / 15:26
14

Renomear os diretórios sem desligar o Apache também deve funcionar. Isso encurtará a janela significativamente. mv public_html public_html_old && mv public_html_new public_html deve terminar em uma fração de segundo.

Algumas desvantagens são que essa abordagem fornecerá 404 para qualquer solicitação que ainda possa acontecer durante a janela. E se você executar o comando acima sem ter um diretório public_html_new , ele falhará e deixará você com um site fornecendo 404 em cada solicitação.

Fazê-lo atomicamente com diretórios não é suporte. Mas você poderia fazer isso com links simbólicos. Em vez de ter um diretório chamado public_html , tenha um diretório chamado public_html.version-number e um link simbólico chamado public_html apontando para esse diretório. Agora você pode criar um diretório chamado public_html.new-version-number e um novo symlink chamado public_html.new .

Em seguida, você pode renomear public_html.new para public_html para alternar atomicamente. Observe que mv é "muito inteligente" para executar essa renomeação, mas isso pode ser feito usando os.rename do python ou qualquer outra coisa que chamará a chamada de sistema rename sem tentar ser inteligente.

O que fazer com a base de dados depende de qual banco de dados você está usando e para o que você está usando. Você precisa fornecer muito mais detalhes sobre o banco de dados antes de podermos dar uma boa resposta a essa parte da sua pergunta.

    
por 12.08.2014 / 14:38
11

Symlinks e mv são seus amigos, no entanto, se você realmente precisa evitar que os usuários finais obtenham uma página de erro ao implantar uma nova versão, você deve ter um proxy reverso ou um balanceador de carga em frente a pelo menos 2 back-end servidores (apache no seu caso).

Durante a implantação, você só precisa parar um backend de cada vez, implantar o novo código, reiniciá-lo e, em seguida, iterar nos back-ends restantes.

Os usuários finais sempre serão direcionados para bons back-ends pelo proxy.

    
por 12.08.2014 / 19:29
9

Se você estiver aplicando alterações regularmente em um sistema de produção, eu cuidaria de um ciclo de vida estruturado. Uma boa prática é o link de Capistrano. Esta é uma solução de código aberto para a implantação de software em um ou mais servidores em diversas plataformas e configurações.

Para o Magento, existe até um plugin: link

Para transições de servidor único e quase sem costura, recomendo usar links simbólicos.

    
por 12.08.2014 / 14:57
4

A maneira que eu faço é cometer minhas alterações do meu ambiente de desenvolvimento local para um repositório Git online como o Github. Meu ambiente de produção é executado em um repositório remoto, então tudo que preciso fazer é ssh para o servidor e executar git pull para derrubar as alterações mais recentes. Não há necessidade de parar o seu servidor.

Se você tiver arquivos em seu projeto cujas configurações e / ou conteúdo sejam diferentes de sua versão local (como arquivos de configuração e uploads de mídia), você poderá usar variáveis de ambiente e / ou adicionar esses arquivos / diretórios a um arquivo .gitignore impedir a sincronização com o repositório.

    
por 12.08.2014 / 16:59
3

Minha primeira ideia é:

# deploy into public_html_new, and then:
rsync -vaH --delete public_html_new/ public_html/

Uma boa solução foi usar o rsync. Mudou apenas os arquivos realmente alterados. Cuidado, as barras no final do caminho são importantes aqui.

Normalmente, o apache não precisa ser reiniciado, não é o mundo java. Ele verifica a mudança de cada arquivo php a pedido, e releia (e reconquina) a mudança automaticamente.

Git pull foi eficiente, embora fosse um pouco mais difícil de escrever. É claro que permitiu um amplo espectro de diferentes possibilidades de detecção de mesclagem / mudança.

Esta solução ocorrerá sem problemas apenas se não houver grandes mudanças - se houver grandes mudanças na implantação, um pouco de risco não poderá ser encerrado, porque há um intervalo de tempo não desprezível, quando o código será ser parcialmente alterado e, em particular, não.

Se houver grandes mudanças, minha sugestão foi sua solução inicial (dois renomear).

Aqui está um pouco hardcore, mas solução 100% atômica:

(1) faça um monte alternativo do seu sistema de arquivos, onde o seu magento acontece:

mount /dev/sdXY /mnt/tmp

(2) faça uma --bind de seu public_html_new para public_html:

mount --bind /path/to/public_html_new /path/to/public_html

A partir deste ponto, o apache verá sua nova implantação. Qualquer alteração de um 404 é impossível.

(3) faça a sincronização com o rsync, mas no ponto de montagem alternativo):

rsync -vaH --delete /mnt/tmp/path/to/public_html_new/ /mnt/tmp/path/to/public_html/

(4) remova a montagem de ligação

umount /path/to/public_html
    
por 12.08.2014 / 14:20
1

Mover / substituir a pasta http_public pode ser obtido com os comandos simples mv ou ln -s ou equivalente, enquanto o servidor http continua em execução. Você pode fazer alguns scripts para reduzir significativamente o tempo de inatividade, mas verifique cuidadosamente os códigos de retorno de seus comandos no script, se você automatizar o processo.

Dito isto, se você não quiser obter tempo de inatividade, o aplicativo também deve ser compatível. A maioria dos aplicativos usa um banco de dados para persistência. Ter a versão N do seu aplicativo mexendo com a versão N + 1 (ou o reverso) do seu modelo de dados pode quebrar coisas se não for previsto pela equipe de desenvolvimento.

Da experiência, manter essa consistência por meio de atualizações não é um dado dado à maioria dos aplicativos. Um desligamento adequado, apesar do tempo de inatividade, é uma boa maneira de evitar problemas de consistência.

    
por 17.08.2014 / 14:52