Desenvolvimento

9 set, 2013

Bugs que quebram a arquitetura – quando um sonho se torna um pesadelo

Publicidade

A historia dos sistemas de computador é também a historia dos bugs, incluindo bugs épicos, desastrosos que causaram danos e destruição de milhões de dólares e até a morte, assim como muitos outros sistemas menos espetaculares, mas caros, e falhas de projeto. Alguns parecem ser erros pequenos e estúpidos, como o incidente infame do foguete Ariane 5, causado por um erro de programação de uma linha. Mas um erro de programação de uma linha, ou qualquer outro erro ou fracasso isolado, não pode causar sérios danos a um sistema grande, sem falhas fundamentais na arquitetura e design, e falhas na gestão.

Boeing 787 Dreamliner indo pra lugar nenhum
The Economist, 26 de fevereiro de 2013

Esses tipos de problemas são o que Barry Boehm chama de “bugs que quebram a arquitetura“: onde o design de um sistema não se se sustenta no mundo real, quando você se encontra frente a frente com uma fraqueza ou um limite daquilo que é possível com a abordagem que você usou, ou com a plataforma que você escolheu.

Bugs que quebram a arquitetura acontecem nos limites – ou além dos limites – do design, fora dos “caminhos felizes“, normais, nominais. O sistema funciona, exceto por erro excepcional de “um em um milhão”, que ninguém leva a sério até que o problema “um em um milhão” começa a acontecer todos os dias. Ou o sistema dobra sob um aumento inesperado na demanda, uma demanda que não acaba a menos que você não possa encontrar uma forma de expandir rapidamente o sistema para acompanhar – e, se você não puder, você não terá mais um problema de demanda porque os clientes não vão voltar. Ou o que parece ser um problema operacional menor acaba por ser o primeiro sinal de uma confiabilidade fundamental ou problema de segurança no sistema.

Dreamliner está preocupado com questões de segurança
NY Time, 10 de janeiro de 2013

Encontrando bugs que quebram a arquitetura

Começa com um bug desagradável ou um problema operacional isolado ou um incidente de segurança. À medida que você investiga e começa a olhar mais fundo, encontra mais casos, escancarando buracos no projeto, os limites rígidos para o que o sistema pode fazer, ou falhas que não podem ser explicadas e não podem ser interrompidas. O design começa a desvendar como cada problema se abre para outro problema. Corrigir corretamente leva tempo e dinheiro, talvez você até tenha que voltar para a prancheta e rever decisões de arquitetura fundamentais e escolhas tecnológicas. O que parecia ser uma falha aleatória ou um bug feio só se transformou em algo muito pior, e muito, muito mais caro.

Aprofundando na crise para o Boeing 787
NY Times, 17 de janeiro de 2013

O que torna esses problemas especialmente ruins é que eles são encontrados muito tarde, além do design e dos testes de aceitação, geralmente quando o sistema já está em produção, e você tem um monte de clientes reais usando-os para trabalhar de verdade. Isso acontece quando você pode pagar menos para encontrar um problema sério. Quando algo da errado, pode ser difícil reconhecer o quão sério ele é imediatamente. Pode levar dois ou três ou mais fracassos antes de você perceber – e aceitar – quão ruim as coisas realmente estão e antes de ver o suficiente de um padrão para entender onde problema poderia estar.

Baterias do Boeing dizem falhar 10 vezes antes do incidente
Bloomberg, 30 de janeiro de 2013

Até então, você pode estar perdendo clientes e dinheiro e estar sob pressão extrema para chegar a uma solução, e ninguém quer ouvir que tem que parar e voltar para reescrever um pedaço de seu sistema, ou re-arquitetar e começar de novo – ou que precisa de mais tempo para pensar, testar e entender o que está errado, e quais são suas opções antes que você possa dizer quanto tempo levaria e quanto custaria para corrigir as coisas.

Reguladores em torno do Globo Boeing 787s
NY Times, 18 de janeiro de 2013

O que pode quebrar sua arquitetura?

A maioria dos bugs que quebram a arquitetura é um problema fundamental em aspectos não-funcionais importantes de um sistema:

  • Estabilidade e integridade dos dados: alguma parte do sistema não vai aguentar a carga ou falha intermitentemente, após o sistema estar executando por horas, dias ou semanas, ou você perdeu dados importantes de clientes ou não pode recuperar e restaurar o serviço rápido o suficiente depois de uma falha operacional.
  • Escabilidade e rendimento: a plataforma (linguagem, container, camada de comunicação, banco de dados ou todos eles) são lindas para se trabalhar, mas não conseguem se manter à medida que mais clientes chegam, mesmo se você jogar mais hardware para ele. Pergunte ao Twitter sobre a tentativa de escalar Ruby ou ao Facebook sobre escalar PHP ou qualquer pessoa que já tentou escalar Oracle RAC.
  • Latência – requisitos para escalar satisfatoriamente, em tempo real, o tempo de resposta, ou quando você está executando com uma variabilidade inaceitável (você escolheu Java como sua plataforma de tempo de execução, o que acontece quando GC entra em ação?).
  • Segurança: você acabou de ser hackeado e descobre que o único bug que o invasor explorou é apenas o primeiro de centenas de milhares de bugs que precisam ser encontrados e corrigidos, pois seu projeto ou linguagem e a estrutura que você escolheu (ou a maneira como você usou) são tão cheios de buracos de segurança como um queijo suíço.

Esses problemas podem vir de um mal-entendido do que a tecnologia da plataforma subjacente ou framework podem realmente fazer – o que as tolerâncias de projeto para que a arquitetura e tecnologia são. Ou de completamente passar por cima, ignorar ou não entender direito um aspecto importante do projeto.

Esses não são problemas que você pode codificar sua saída, pelo menos não com facilidade. Às vezes, o problema não está no seu código, e sim em uma tecnologia de plataforma tercerizada que não pode se manter atualizada. A linguagem em si, ou uma parte importante da pilha, como o contêiner, banco de dados, camada de comunicação, ou qualquer dependência para um cluster, failover, ou alguma outra mágica. Em alta escala no mundo real, qualquer peça de software que outra pessoa escreveu pode e vai ficar aquém do que você realmente precisa, ou do que o vendedor prometeu.

Boeing, 787 Fornecedor de Bateria em desacordo sobre correções
Wall Street Journal, 27 de fevereiro, 2013

Você vai ter que gastar um tempo trabalhando com um fornecedor (ou às vezes com mais de um) e ajudá-lo a entender o seu problema, e levá-lo a concordar que ele é quem tem que corrigi-lo, e se ele puder corrigi-lo rápido o suficiente, você precisa elaborar um plano B rapidamente, e espero que a sua nova escolha não vá resultar em outros problemas que podem ser tão ruins ou até piores.

Como evitar quebras na arquitetura

Quebras na arquitetura são causadas por decisões que você tomou no início e que deram errado – ou que você não tomou cedo o suficiente, ou não fez nada. Boehm fala sobre bugs que quebram a arquitetura, como parte de um argumento contra o Simple Design – que muitas equipes,  especialmente as de Agile, passam muito tempo focadas no caminho feliz, na criação de novos recursos para fazer o cliente feliz, e não gastam tempo suficiente na arquitetura inicial e pensando sobre o que poderia dar errado. Mas os bugs que quebram a arquitetura têm estado por aí há muito mais tempo que Agile e Simple Design: em Making Software (Capítulo 10 Architecting: How Much and When), Boehm remonta aos anos 1980, quando ele reconheceu pela primeira vez esses tipos de problemas, quando Programação Estruturada e Waterfall eram  o “caminho certo” para fazer as coisas.

A solução de Boehm é uma definição melhor de arquitetura e gerenciamento de risco técnico através de desenvolvimento de software em espiral: um ciclo de vida com arquitetura inicial para identificar áreas de risco, que são exploradas por meio de iterativa, design direcionado ao risco, prototipagem e desenvolvimento em múltiplos estágios. Desenvolvimento em espiral são como os métodos iterativos de desenvolvimento incremental atuais em esteróides, com picos de arquitetura baseada no risco, mas com muito mais tempo de desenvolvimento iterativo e ciclos técnicos de prototipagem, gerenciamento de risco mais formal, mais planejamento, mais burocracia e custos muito mais elevados.

Bugs como esses não podem ser resolvidos gastando mais tempo em arquitetura e técnicas iniciais de gestão de risco – seja através do desenvolvimento de uma espiral ou de uma reforçada, a abordagem disciplinada de desenvolvimento Agile. Mais tempo gasto não irá ajudar se você fizer suposições ingênuas sobre escalabilidade, capacidade de resposta e confiabilidade ou segurança; ou se você não entender esses problemas bem o suficiente para identificar os riscos. Bugs que quebram a arquitetura não serão encontrados em revisões de projeto – porque você não vai estar à procura de algo que você não sabe que poderia ser um problema – a menos que talvez você esteja executando através de exercícios estruturados de modelagem de falhas, como FMEA (Failure mode and effect analysis) ou FMECA (Failure mode, effects and criticality analysis), que o forçam a fazer perguntas difíceis, mas de que poucas pessoas fora de setores regulamentados ouviram falar.

E nem todos os bugs que quebram a arquitetura são detectáveis nos testes. Mesmo com testes extensos, simulação e injeção de falhas, testes destrutivos ou de stress – mesmo se todos os bugs encontrados durante os testes sejam levados a sério (porque esses tipos de testes extremos são muitas vezes consideradas irreais).

Você tem que estar preparado para lidar com bugs que quebram a arquitetura. Antecipando problemas e particionamento sua arquitetura usando algo parecido com os padrões de estabilidade no excelente livro de Michael Nygard “Release it” , pelo menos impedirá que erros graves em tempo de execução se espalhem, derrubando todo o sistema (essas estratégias o ajudarão a escalar e também a conter ataques de segurança). E mesmo quando você vir um erro em um milhão nas revisões, testes ou em produção, entenda o quão sério isso pode ser e aja da forma correta – antes que um sonho se torne um pesadelo.

***

Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em  http://swreflections.blogspot.com.br/2013/04/architecture-breaking-bugs-when.html