Estabilidade de Software - Parte 01
Published: 2023-10-19 16:57:41

Estabilidade é um dos principais atributos de um software, ao mesmo tempo em que é o principal desafio. Manter uma aplicação estável e em constante evolução é uma tarefa complexa que requer planejamento, como qualquer outro aspecto de um bom software.

O planejamento de um software é algo fundamental. A qualidade de um software não é resultado de sorte, então dedique a devida atenção a essa fase do desenvolvimento. Decisões equivocadas nas fases iniciais do projeto podem custar muito caro $$$.

>  _Um design altamente estável geralmente custa o mesmo para implementar que o instável._

O planejamento de software deve ser realista ~~pessimista~~ e sempre considerar que eventos indesejados podem ocorrer. Portanto, é essencial que o software seja capaz de lidar com falhas em produção e consiga preservar a estabilidade.

## Armadilhas para Estabilidade

Quando estamos desenvolvendo software, é comum cometer alguns erros dos quais sempre aprendemos algo. Abaixo, vamos ter algumas dos antipadrões que devemos evitar para construir um software estável.

### Integration Points

>_Os pontos de integração são o principal fator de risco para sistemas, quanto mais integrações mais risco_

Não tenha uma visão otimista com suas integrações. É importante considerar que suas integrações podem falhar e causar indisponibilidades. Portanto, seja cauteloso com as integrações. Existem alguns padrões que irão ajudar a lidar com essas falhas, como  **"Circuit Breaker," SLA, Timeouts e Fallbacks.**

---

### Scaling Effects

>_Padrões que funcionam bem em ambientes pequenos, mas podem ficar lentos ou falhar completamente quando você os aplica a tamanhos de produção_

Um exemplo clássico desse problema é um banco de dados compartilhado entre várias aplicações, onde, durante um pico de acesso o banco de dados fica sobrecarregado impactando todo o sistema, então sempre que **possivel não compartilhe recursos**.

---

### Slow Responses

> _Gerar uma resposta lenta é pior do que retornar um erro._

Falhar rápido permite que o software tente se recuperar do erro mais rapidamente com retries por exemplo. Por outro lado, respostas "lentas" ocupam recursos da máquina e bloqueiam threads, podendo causar uma falha em cascata no software.

---

### Blocked Threads

> _As falhas da aplicação quase sempre estão relacionadas a threads bloqueadas de alguma forma._

Conexões com bancos de dados ou servidores, assim como bibliotecas de terceiros, frequentemente incluem lógica relacionada a threads. Threads bloqueadas podem causar problemas em cascata em seu software, afetando sua disponibilidade e desempenho. Então, tenha cuidado ao lidar com esse recurso.

---

### Attacks of Self-Denial

> _Um bom marketing pode acabar com sua aplicação._

Os 'Attacks of Self-Denial' ocorrem quando a empresa gera um grande volume de tráfego que sua aplicação não consegue lidar e acaba gerando instabilidade no sistema. Por exemplo, isso pode acontecer com campanhas publicitárias que direcionam tráfego direto para o seu sistema. A solução ideal para evitar esse problema é ter uma comunicação eficaz dentro da empresa.

---

### SLA Inversion

> _Seu sistema é tão confiável quanto os sistemas dos quais depende_

Não faça promessas vazias. Ao criar um SLA(Acordo de Nível de Serviço), certifique-se de que suas dependências podem garantir a mesma SLA. Você não pode garantir que seus endpoints consigam responder em 200ms, enquanto suas dependências podem demorar 400ms para responder

---

### Cascading Failures

> _Prevenir falhas em cascata é a chave para a resiliência._

Quando usamos uma arquitetura de microserviços, é normal que um serviço dependa de outros. Se um desses serviços apresenta problemas, que por sua vez afetam outros serviços, isso é conhecido como Cascading Failures, ou seja, falhas em cascata.

É importante garantir que sua aplicação consiga lidar com essa instabilidade de suas dependências para não gerar erros em cascatas no sistema.

---

### Unbounded Result Sets

> _Projete com ceticismo e você alcançará resiliência._

Tenha em mente que as consultas de dados podem retornar um volume imenso de informações. Portanto, estabeleça limites para essas consultas, a fim de evitar surpresas com uma quantidade de dados que possa causar problemas na produção.

---

### Unbalanced Capacities

Imagine um pico de acessos em um site de compras online. Rapidamente, a quantidade de máquinas no aplicativo de frontend aumenta para lidar com a demanda, porém o frontend depende de um backend que não possui recursos suficientes para lidar com o aumento das solicitações. Esse tipo de situação é conhecido como **Unbalanced Capacities**, onde os componentes do sistema têm capacidades diferentes e dependem um do outro. Isso resulta em tempos de resposta mais lentos, erros frequentes ou até mesmo falhas completas no sistema, devido ao fato de o backend estar subdimensionado em relação à carga de trabalho atual.

---

## Conclusão

Ao desenvolver um software, existem muitas armadilhas que podem comprometer a estabilidade. Portanto, na fase de planejamento, é crucial considerar o nível de estabilidade necessário para o seu software. Com base nessa avaliação, crie alternativas para que a aplicação possa lidar com possíveis falhas.

Quanto maiores forem os requisitos de estabilidade, mais complexo o seu software **se tornará e mais caro também**. Sempre **equilibre os riscos com as soluções propostas**. Se o seu produto é um sistema interno, uma breve instabilidade de 10 minutos pode não representar um grande risco. No entanto, para uma instituição financeira, essa mesma instabilidade pode resultar em perdas de milhões.


## Recomendações

Um dos livros que me inspirou na criação deste conteúdo foi   [Release It!: Design and Deploy Production-Ready Software](https://www.amazon.com.br/Release-Design-Production-Ready-Software-English-ebook/dp/B079YWMY2V/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=1697296350&sr=8-1). Recomendo-o se você deseja aprofundar-se nos desafios enfrentados por um software em produção.