Atualmente, temos um aplicativo clássico de n camadas: DB / serviço da web / front-end. Tem outros componentes, mas é o layout básico.
Queremos melhorar a disponibilidade do aplicativo por três razões principais:
- Às vezes, nosso host sofre interrupções (como todos acontecem) e queremos minimizar o impacto em nossos clientes; por exemplo, eles ativariam o datacenter B se o datacenter A estivesse inativo.
- Quando atualizamos a versão, encerramos o site para manutenção, e geralmente leva algumas horas (scripts de migração, etc.). Gostaríamos que os usuários tivessem uma transição mais uniforme, com o mínimo de tempo de inatividade possível (eles usam o servidor B enquanto o servidor A está sendo atualizado).
- Opcionalmente, nossos clientes estão localizados em todo o mundo e queremos que eles tenham a melhor experiência possível, apesar de suas possíveis conexões ruins (qualquer pessoa que trabalhe com desenvolvedores indianos deve saber o que quero dizer). Idealmente, gostaríamos de poder conectar um servidor ao escritório (ou usar um datacenter perto da cidade) e ele seria integrado perfeitamente à nossa arquitetura.
Não precisamos remotamente de 99% de disponibilidade, nem mesmo de 95%. É um aplicativo de gerenciamento de documentos. Ninguém se importa. Mas como as migrações podem demorar um pouco, e há clientes em todo o mundo, às vezes impedimos que um cliente trabalhe a maior parte do dia.
Para a parte SQL, mesmo que não haja DBAs "adequados", conhecemos as possibilidades de SQL : replicação, espelhamento etc. No lado do banco de dados, é muito fácil encontrar recursos para isso. O que é mais difícil é tudo o resto: armazenamento de sessões, código, etc. Se meu servidor de serviço da web ficar inativo, como minha interface do usuário sabe que deve mudar? Como minhas sessões persistem nos servidores?
Infelizmente, nenhum de nós tem experiência nessa área e nem sabemos por onde começar a procurar. Existem práticas recomendadas para isso? Padrões de design? Bibliotecas (que devem ser gratuitas porque não temos dinheiro)?
Estamos usando o ASP.Net e o SQL Server, com um serviço da Web WCF no meio. Temos vários serviços do Windows por aí, mas eles não são de missão crítica, e presumo que os métodos para lidar com o site sejam aplicáveis aos serviços.
Eu entendo que a maioria das plataformas em nuvem fornece um sistema interno para isso, mas a hospedagem em nuvem é proibida por causa do administrador de sistemas, que deseja gerenciar tudo sozinho e não confiar em ninguém.
fonte
Respostas:
Você precisa esclarecer que tipo de alta disponibilidade está procurando. Existem aplicativos altamente disponíveis que eu executo que precisam estar atualizados 95% do tempo. Existem outros que precisam rodar em 99%. Posso pensar em cenários de vida ou morte que exigem 100% de tempo de atividade. Apenas esses três têm abordagens e custos drasticamente diferentes.
Basta adivinhar com base em suas necessidades e um SLA de 95 a 99% de tempo de atividade:
Ao contrário de Frederik, não chamarei sua paranoia de nuvem injustificada. Depende dos seus requisitos de tempo de atividade. É concebível que um serviço tenha que ser executado em vários data centers operados por diferentes provedores em diferentes países por causa da redundância. No entanto, devido ao seu estado atual, eu concordo que a AWS, o Azure ou similares provavelmente são apostas seguras para sua empresa.
fonte
Obtendo algum nível de alta disponibilidade na camada da web e do aplicativo:
Idealmente, fatore qualquer estado, incluindo o estado da sessão em sistemas de estado compartilhado, como um banco de dados ou um servidor de estado da sessão na memória. Dependendo do design do seu aplicativo, isso pode causar problemas de desempenho devido à latência adicionada, obtendo uma grande quantidade de estado.
Cada site e camada de aplicativo devem ter um balanceador de carga independente à sua frente. O NGINX fará o truque, mas o IIS também pode fazer isso (ARR).
Se um único banco de dados não puder lidar com a carga, utilize o particionamento do estado da sessão (ou fragmentação ou hash consistente) para rotear uma solicitação específica para uma caixa de banco de dados específica.
Se fatorar o estado de fatoração for muito difícil, você poderá usar a afinidade do servidor para o balanceamento de carga (ou seja, os usuários serão roteados consistentemente para a mesma caixa, geralmente baseados em cookies). Não é tão disponível como uma abordagem de rodízio sem estado, porque uma interrupção de caixa afetará todos os usuários e indicará nessa caixa, mas supera uma interrupção completa (dependendo do caso de uso).
No lado da atualização:
Projete seus scripts de banco de dados de forma que as atualizações do banco de dados possam ser feitas enquanto o sistema estiver em execução, ou seja, mantenha a compatibilidade com versões anteriores. Um padrão que funciona bem para isso é "expandir e depois contratar" -> fazer apenas alterações aditivas e compatíveis com versões anteriores, mas remover dependências nos campos (etc) dos quais você deseja se livrar; então atualize todos os clientes do banco de dados para v-latest; então faça outro db-upgrade para se livrar dos campos antigos (etc) no banco de dados. Isso pode ser um processo lento se você tiver um banco de dados grande e tiver que ter cuidado para não prejudicar o desempenho do seu sistema.
Atualizando a camada do aplicativo: como você não está usando um ambiente em nuvem, recomendo que você siga o padrão de implantação canário: faça uma atualização sem interrupção das caixas da Web e da camada intermediária. Se a implantação der errado, retire a caixa do balanceador de carga, como faria como se tivesse falhado.
Aviso: evoluir um sistema que não foi projetado para HA em um que seja, pode ser um processo longo e caro. Você precisará fazer trocas ao longo do caminho (custo x esforço para atingir um nível específico de disponibilidade)
Sua paranóia da nuvem é injustificada - provedores como a AWS, em conjunto com as boas práticas de sua parte, podem controlar / mitigar a maioria dos riscos - consulte a página de conformidade deles para ter uma idéia de quais regulamentos eles são compatíveis: https: // aws .amazon.com / conformidade /
fonte
TL; DR: criar redundante, modular; teste de disponibilidade; monitorar de perto.
Depois de perceber que a tentativa de extrair qualquer explicação pode demorar muito, escreverei todas as observações que fiz.
Questionando a premissa
Sistema de nuvem é panacéia
Mesmo que você opte totalmente pela nuvem, com um dos principais provedores de nuvem, ainda será necessário projetar seu aplicativo para resiliência. A AWS pode substituir sua VM, mas seu aplicativo deve ser capaz de reiniciar se for deixado no meio da computação.
Não queremos usar o sistema em nuvem, por causa de x / y / z
A menos que você seja uma organização muito grande, é melhor usar sistemas de nuvem. Os três principais sistemas em nuvem (AWS, MSFT, Google) empregam milhares de engenheiros para fornecer SLAs prometidos e o painel fácil de gerenciar. Na verdade, é uma boa pechincha usá-los, em vez de gastar um centavo com isso em casa.
Problemas no escopo e no design
Definir, quantificar e, em seguida, medir continuamente a disponibilidade de um serviço é um desafio maior do que escrever soluções para problemas de disponibilidade.
Definir e medir a 'disponibilidade' é mais difícil do que o esperado
Múltiplas partes interessadas têm uma visão diferente da disponibilidade, e o que pode acontecer é a definição preferida por uma pessoa com salário mais alto que outra definição. Às vezes, essa é a definição correta, mas geralmente o ecossistema não é construído para medir a mesma coisa, porque essa definição ideal é muito difícil de medir, e muito menos monitorar em tempo real. Se você tem uma definição de disponibilidade que não pode ser monitorada em tempo real, você encontrará seu projeto semelhante auto-realizado repetidas vezes com semelhanças assustadoras. Atenha-se a algo que faça sentido e que possa ser facilmente monitorado.
As pessoas subestimam as complexidades do sistema sempre disponível.
Para abordar o elefante na sala, deixe-me dizer o seguinte: "Nenhum sistema multi-computador está 100% disponível, poderá no futuro, mas não com a tecnologia atual". Aqui, pela tecnologia atual, estou me referindo à nossa incapacidade de enviar sinais mais rapidamente do que a velocidade da luz e coisas assim. Todos os engenheiros da comp-sci valem a pena conhecer as limitações da computação distribuída , e a maioria deles não menciona isso nas reuniões, com medo de parecer noobs. Para compensar todos aqueles que não mencionam as limitações da computação distribuída , direi que é complicado, mas nem sempre confia nos computadores .
As pessoas superestimam as capacidades de seus engenheiros
Infelizmente, a disponibilidade cai na categoria em que você não sabe o que deseja, mas sabe o que não quer. É um pouco mais complicado que a categoria 'conheça os desejos', como a interface do usuário. Requer um pouco de experiência e muita leitura para aprender com a experiência dos outros e um pouco mais.
Construindo um sistema disponível desde o início
Certifique-se de evangelizar para todas as equipes de arquitetura e design a prioridade correta da disponibilidade como um requisito do sistema.
Atributos do sistema que ajudam a disponibilidade
As seguintes características do sistema demonstraram ter contribuído para a disponibilidade do sistema:
Redundância
Alguns exemplos disso são: nunca ter apenas uma única VM atrás de um VIP ou nunca armazenar apenas uma única cópia dos seus dados. Essas são as perguntas que um bom IAAS facilitará para você resolver, mas você ainda precisará tomar essas decisões.
Modularidade
Um REST modular é melhor que o SOA monolítico. Na verdade, um microsserviço modular está realmente mais disponível do que o habitual HATEOS REST . O raciocínio pode ser encontrado na discussão relacionada ao rendimento na próxima seção. Se você estiver processando em lote, é melhor processá-lo em lotes razoáveis de 10s em comparação a lidar com um lote de 1.000.000.
Resiliência
Um sistema resiliente está sempre pronto para se recuperar. Essa resiliência se aplica a instâncias como reconhecer o ACK para gravação somente após a gravação no disco RAID e, possivelmente, em pelo menos dois data centers. Outra tendência mais recente é usar estruturas de dados sem conflito , onde a estrutura de dados assume a responsabilidade de resolver conflitos quando apresentada com duas versões diferentes. Um sistema não pode ser resiliente como uma reflexão tardia, ele deve ser previsto e incorporado. Uma falha é garantida a longo prazo, por isso devemos estar sempre preparados com um plano de recuperação.
Trilha de registro
Tecnicamente, esse é um subtipo de resiliência, mas muito especial por causa de sua capacidade de capturar todos os recursos. Apesar do melhor esforço, podemos não ser capazes de prever o padrão de indisponibilidade. Se possível, mantenha trilha de log suficiente das atividades do sistema para poder reproduzir eventos do sistema. Isso, a um grande custo manual, permitirá que você se recupere de situações imprevistas.
Atributos de disponibilidade
A lista não exaustiva de atributos de 'disponibilidade': Para discussão, vamos supor que a pergunta do usuário seja: "Quantos itens eu tenho no meu carrinho de compras?"
Correção
Você deve produzir a resposta mais precisa possível ou pode cometer erros? Apenas para uma referência, quando você retira dinheiro do caixa eletrônico, não é garantido que ele esteja correto. Se o banco descobrir que cometeu um erro, você poderá reverter as transações. Se o seu sistema está produzindo números primos, então eu acho que você pode querer respostas corretas o tempo todo.
Produção
Pule este ponto, se você respondeu sempre correto para a pergunta do tópico anterior. Às vezes, a resposta às perguntas não precisa ser precisa, por exemplo, quantos amigos eu tenho no Facebook agora? Mas a resposta deve estar no estádio +/- 1 o tempo todo. Quando você está produzindo o resultado esperado, seu rendimento é 100.
Consistência
Sua resposta pode estar correta em um ponto no tempo, mas quando a luz sair da tela e entrar na retina do observador, as coisas poderão ter mudado. Faz sua resposta errada? Não, apenas torna inconsistente. A maioria dos aplicativos é eventualmente consistente, mas o truque é definir que tipo de modelo de consistência seu aplicativo fornecerá. Por acaso seu aplicativo pode ser executado em um único computador, você pode pular essa adorável leitura no teorema do CAP .
Custo
Depende muito do impacto total dos efeitos de curto prazo (perda de receita) e efeitos de longo prazo (má reputação, retenção de clientes). Dependendo do tipo de cliente (pago / gratuito, repetido / exclusivo, cativo) e da disponibilidade de recursos, diferentes níveis de garantias de disponibilidade devem ser incorporados.
Para melhorar a disponibilidade de um sistema existente
O gerenciamento operacional de máquinas individuais e uma rede é tão complexo que suponho que você o tenha deixado para o provedor de nuvem ou você já é especialista o suficiente para saber o que está fazendo. Vou tocar em outros tópicos sob disponibilidade. Para a estratégia de longo prazo, Definir-Medir-Analisar-Controle é uma combinação divina, algo que eu já me vi.
Causas de indisponibilidade
Como concordamos que o gerenciamento operacional que abrangeria qualquer gerenciamento de infraestrutura física deveria ser feito por profissionais, abordarei outras causas de indisponibilidade por questões de integridade. A disponibilidade da IMO também deve incluir a falta de comportamento esperado, ou seja, se o usuário não receber a experiência esperada, algo estará indisponível. Com essa definição ampla em mente, o seguinte pode causar indisponibilidade: - Bugs de código - Incidências de segurança - Problemas de desempenho
fonte