Temos muitos aplicativos e serviços da Web (alguns produtos voltados ao público, outros internos e parte de um "back-end" privado)) que são interdependentes entre si. Cada um desses componentes possui 4 ambientes (agrupamentos de servidores / nós que atendem a propósitos específicos):
- Não Produção
DEV
- Ambiente de desenvolvimento integrado, onde a CI constrói mudanças push; útil para engenheiros para solucionar problemas difíceis de encontrar que não são reproduzíveis localmenteQA
- Ambiente de controle de qualidade / teste isoladoDEMO
- Ambiente UAT estável para as partes interessadas do negócio
- Produção
LIVE
- Nosso ambiente ao vivo / produção
A promoção do código é: LOCAL
(máquina do desenvolvedor) => DEV
=> QA
=> DEMO
=> LIVE
.
Digamos que temos um aplicativo chamado myapp
que é apoiado por um serviço da Web RESTful chamado myws
, que por sua vez é apoiado por um banco de dados chamado mydb
.
Atualmente, temos o que eu chamaria de promoção " orquestrada " entre essas dependências: os myapp-dev
pontos para os myws-dev
quais se usa mydb-dev
. Da mesma forma, myapp-qa
pontos para os myws-qa
quais utiliza mydb-qa
. O mesmo para DEMO
e LIVE
.
O problema com isto é que a qualquer momento eu fizer uma alteração para, digamos, myapp
, isso me obriga a fazer alterações myws
e mydb
bem. Mas como cada DEV
ambiente aponta para os ambientes de suas dependências DEV
, significa que tenho que agendar e implantar essas alterações ao mesmo tempo. Além disso, se uma construção se torna instável / quebrada, geralmente reduz outros componentes upstream; por exemplo, se um desenvolvedor quebra algo ao mudar mydb-dev
, os clusters myws-dev
e myapp-dev
geralmente também se tornam instáveis.
Para resolver isso, estou montando uma proposta para o que eu chamaria de estratégia de promoção "em silos ": todas as dependências entre componentes seguem esta diretriz:
- As dependências upstream dependem do
DEMO
ambiente para suas dependências downstream, para todos os seus ambientes de não produção (DEV
,QA
eDEMO
); e - Dependências upstream dependem do
LIVE
ambiente para suas dependências downstream para seu ambiente de produção
Usando esta convenção, myapp-dev
realmente apontaria para myws-demo
, o que seria usado mydb-demo
. Da mesma forma, myapp-qa
também apontaria para myws-demo
e mydb-demo
.
A vantagem aqui que eu posso encontrar é a estabilização de construção : é muito menos provável que o DEMO
ambiente para um determinado componente irá tornar-se instável, porque o código não pode fazê-lo até DEMO
sem testes rigorosos, tanto em DEV
e QA
.
A única desvantagem que posso encontrar para esse método é que, se DEMO
for interrompido para um componente específico, todos os ambientes de não produção para todas as dependências upstream serão subitamente interrompidos. Mas eu diria que isso deve acontecer muito raramente por causa dos testes realizados em DEV
e QA
.
Isto tem de ser um problema que muitos desenvolvedores (muito mais inteligente e experiente do que eu) ter resolvido, e eu não ficaria surpreso se este problema e suas soluções já têm nomes para eles (além de que estou chamando orquestrada / silos). Então pergunto: os méritos de uma estratégia de promoção em silos superam quaisquer contras, e quais são os contras que posso estar negligenciando aqui?
Respostas:
Se estou lendo sua postagem corretamente, não parece que essa proposta realmente resolva um dos supostos problemas.
A "estratégia de promoção em silos" parece que isso só pioraria. Se o myapp v2, o myws v2 e o mydb v2 estiverem apenas no DEV, e o myapp v2 depender do mydb v2 para não falhar, quando tentar executar o myapp v2 no DEV, atingirei a DEMO do mydb v1 e ele trava. Você seria essencialmente forçado a substituir constantemente os silos ou implantar o mydb v2 por todo o caminho para produzir antes mesmo de começar a trabalhar no myapp v2. Mais importante, você nunca testaria o mydb v2 no DEV; portanto, se estiver quebrado, você nem descobrirá até que ele seja interrompido no DEMO, e estará de volta à estaca zero.
Até certo ponto, o problema que você descreve é inevitável, não importa como o seu fluxo de trabalho esteja configurado, mas pode ser minimizado. O truque é garantir que a interface entre mydb e myws (e a interface entre myws e myapp) seja estritamente definida e exija que todas as atualizações nessa interface sejam totalmente compatíveis com versões anteriores . No meu trabalho, temos um esquema XML que define a interface entre nossos aplicativos e serviços, e muitas de nossas ferramentas internas simplesmente não nos permitem fazer atualizações incompatíveis para esses esquemas.
Isso me parece um problema sério, mas não um problema de implantação. Um banco de dados quebrado certamente impedirá o serviço e o aplicativo de funcionar corretamente, mas não deve se tornar "instável". Eles devem estar retornando mensagens de erro de algum tipo, para que qualquer pessoa que execute o myapp no dev veja "Desculpe, nosso banco de dados está com problemas hoje" em vez de simplesmente travar.
Se o problema é que um banco de dados quebrado causa esses problemas, o que você pode fazer é configurar um sistema de "silenciamento temporário" que permita dizer "mydb DEV está quebrado agora, encaminhe todas as consultas myws DEV para mydb DEMO para o por enquanto ". Mas isso deve ser apenas uma maneira de executar correções temporárias até que o mydb DEV esteja funcionando normalmente novamente. Se tudo estiver "em silos" dessa maneira, por padrão, você estará de volta aos problemas que descrevi acima, porque ninguém nunca corre contra o mydb DEV.
Sinto que provavelmente estou interpretando mal sua proposta de alguma forma, mas espero que essa resposta pelo menos torne óbvio o que estava sendo mal interpretado e a melhor forma de reformulá-la.
fonte