Engenharia de Software Sem Poder Reiniciar o Servidor
Software espacial não pode falhar com elegância. Veja como engenheiros escrevem código para sistemas em que um bug pode custar uma missão bilionária.

Seu servidor web cai às 3 da manhã. O Kubernetes o reinicia. Os usuários veem uma página de erro por alguns instantes. Ninguém é demitido. Agora imagine que seu servidor está orbitando Marte, o reinício leva 45 minutos (durante os quais você não tem controle de atitude, regulação térmica nem comunicação), o “usuário” é uma espaçonave de US$ 2,5 bilhões e não existe Kubernetes, apenas o seu código e a CPU endurecida contra radiação que o executa.
O software espacial opera sob restrições que fazem a engenharia de software convencional parecer tranquila. Você não pode fazer deploy de um hotfix. Não pode dar SSH e olhar os logs. Não pode adicionar servidores quando a carga aumenta. Cada linha de código precisa estar correta antes do lançamento, porque depois dele o software fica por conta própria durante anos ou décadas, rodando em hardware que vai sendo lentamente danificado pela radiação, com um link de comunicação que tem atrasos de vários minutos e largura de banda de kilobits por segundo.
As Restrições que Moldam Tudo
Radiação. No espaço, partículas de alta energia bombardeiam constantemente os componentes eletrônicos. Uma única partícula pode inverter um bit na memória (um single-event upset, ou SEU), corromper um registrador ou travar um processador. Isso não é raro: satélites em LEO sofrem milhares de inversões de bits por dia. Hardware de grau espacial usa componentes endurecidos contra radiação, que são mais lentos, mais caros e gerações atrás do hardware de consumo. O processador do Mars Perseverance é um RAD750, aproximadamente equivalente a um PowerPC da era de 1998 rodando a 200 MHz.
Atrasos de comunicação. Marte fica a 4 a 24 minutos de distância por rádio (dependendo da posição orbital). Júpiter fica a 33 a 54 minutos. Isso não é só latência: significa que a espaçonave precisa lidar com qualquer problema de forma autônoma pelo menos durante o tempo de ida e volta, antes que o controle em solo sequer consiga ver o problema, quanto mais enviar um comando. Quando as sondas Voyager encontraram uma anomalia a mais de 22 horas-luz da Terra, o software tomou as próprias decisões por quase dois dias.
Sem acesso físico. Você não pode substituir um componente com defeito, adicionar RAM ou trocar um disco rígido. Se o computador principal morre e o backup não funciona, a missão acabou. Cada modo de falha precisa ser previsto em software antes do lançamento.
Como o Código Espacial é Diferente
O software espacial usa técnicas que seriam consideradas absurdamente superengenheiradas no desenvolvimento de software comum.
Redundância modular tripla (TMR). Cálculos críticos são executados três vezes em três processadores independentes. Um votador compara os três resultados e usa a resposta da maioria. Se um processador produz um resultado errado por causa da radiação, os outros dois o derrotam na votação. Alguns sistemas rodam cinco cópias (redundância pentupla) para mais segurança.
Scrubbing de memória. Um processo em segundo plano lê a memória continuamente, verifica os dados com códigos de correção de erros (ECC) e corrige erros de um único bit antes que eles se acumulem em erros de múltiplos bits não corrigíveis. Isso roda o tempo todo: cada byte da memória é verificado e corrigido várias vezes por segundo.
Watchdog timers. São timers de hardware que precisam ser zerados periodicamente pelo software. Se o software trava (talvez por um travamento induzido pela radiação), o timer expira e dispara um reset de hardware. O software precisa ser projetado para sobreviver a reinicializações inesperadas em qualquer ponto da execução, pois qualquer cálculo pode ser interrompido e reiniciado.
// Simplified space software patterns
// Watchdog — must be kicked regularly or hardware resets
void main_loop(void) {
while (1) {
kick_watchdog(); // Reset the timer — we're alive
// All operations must complete within watchdog timeout
read_sensors();
kick_watchdog();
run_attitude_control();
kick_watchdog();
check_thermal_limits();
kick_watchdog();
process_ground_commands();
kick_watchdog();
}
}
// Critical value stored with redundancy
typedef struct {
int32_t value_a; // Primary copy
int32_t value_b; // Redundant copy
int32_t value_c; // Third copy for voting
} RedundantInt;
int32_t read_redundant(RedundantInt *r) {
// Majority vote — tolerates one corrupted copy
if (r->value_a == r->value_b) return r->value_a;
if (r->value_a == r->value_c) return r->value_a;
if (r->value_b == r->value_c) return r->value_b;
// All three differ — flag anomaly
raise_anomaly(MEMORY_CORRUPTION);
return r->value_a; // Best guess
}
Os Testes São o Produto
O Jet Propulsion Laboratory da NASA estima que os testes de software espacial consomem de 60 a 80% do esforço total de desenvolvimento. Não 60% do tempo, e sim 60% do custo total. O teste é mais caro que o desenvolvimento porque precisa provar a corretude em um grau que testes de software comum nem se aproximam.
Todo caminho de código precisa ser testado. Não “cobertura de código alta” no sentido que desenvolvedores web costumam usar, e sim literalmente cada caminho por cada função, incluindo caminhos de erro, caminhos de timeout e caminhos que tratam falhas de hardware. Cobertura de branches de 100% é o ponto de partida, não o objetivo.
Além dos testes unitários, o software espacial passa por testes hardware-in-the-loop (rodando o software real no hardware de voo real, simulando o ambiente espacial), testes de estresse de longa duração (rodando por meses para encontrar bugs dependentes de tempo) e testes de injeção de falhas (corrompendo memória de propósito, derrubando processadores e cortando links de comunicação para verificar se o software se recupera).
A verificação formal é cada vez mais usada nos componentes mais críticos. Em vez de testar se o código funciona para entradas específicas, a verificação formal prova matematicamente que o código funciona para todas as entradas possíveis. É cara e lenta, mas, para código que controla a atitude (orientação) de uma espaçonave ou gerencia sua propulsão, o custo se justifica.
O Que Dá Errado Mesmo Assim
Apesar desse rigor, o software espacial falha. As falhas são instrutivas porque revelam os limites até da engenharia mais cuidadosa.
- Mars Climate Orbiter (1999) se perdeu porque uma equipe usou unidades imperiais e outra usou métricas. O software estava correto; os requisitos estavam errados. Nenhuma quantidade de testes pega uma especificação errada.
- Ariane 5 Voo 501 (1996) explodiu porque um float de 64 bits foi convertido para um inteiro de 16 bits e estourou. O código foi reaproveitado do Ariane 4, onde o valor nunca ultrapassava a faixa de 16 bits. O código estava correto para o Ariane 4 e catastroficamente errado para o Ariane 5.
- Mars Polar Lander (1999) provavelmente caiu porque uma vibração do sensor durante a abertura das pernas foi interpretada como contato com o solo, fazendo os motores desligarem a 40 metros de altitude. Foi um problema de interpretação de sensor dependente de tempo que os testes não pegaram porque não replicavam perfeitamente as características da vibração.
- A falha inicial do espelho do Hubble (1990) não foi um bug de software: o espelho foi polido no formato errado por causa de um instrumento de teste mal calibrado. A própria ferramenta de teste tinha um bug.
O fio condutor: o código estava correto de acordo com a especificação, mas a especificação não correspondia à realidade. Esse é o tipo de bug mais difícil de prevenir, porque ele existe na lacuna entre o modelo e o mundo.
O Que o Software Terrestre Pode Aprender
A maioria de nós não escreve software espacial. Mas algumas dessas práticas se aplicam diretamente à construção de sistemas confiáveis na Terra.
Projete para reinicialização. O software espacial assume que pode ser reiniciado a qualquer momento e precisa voltar a um estado conhecido e bom. Serviços web também deveriam ter essa propriedade: se seu servidor cai e reinicia, ele se recupera sem intervenção manual? Ele retoma o processamento de onde parou ou perde trabalho? Padrões de engenharia defensiva que engenheiros espaciais consideram obrigatórios costumam ser opcionais no desenvolvimento web, mas não deveriam ser.
Teste modos de falha, não apenas o caminho feliz. Os testes de software espacial injetam falhas de propósito: matam um processo, corrompem memória, derrubam conexões de rede, retornam códigos de erro de todas as chamadas de sistema. A maioria dos testes de aplicações web foca em verificar se as funcionalidades funcionam, não se o sistema lida com falhas de forma elegante.
Redundância para dados críticos. Se sua aplicação armazena dados caros de recriar (registros financeiros, conteúdo de usuários, estado de configuração), armazene-os de forma redundante e verifique-os regularmente. A replicação de banco de dados é o exemplo óbvio, mas a redundância dentro da aplicação (checksums, validação, verificações periódicas de integridade) pega corrupções que a replicação acaba propagando.
Watchdogs para processos críticos. Se um processo não pode travar, monitore-o. Não apenas “o processo está rodando?”, mas “o processo está progredindo?”. Health checks que verificam se o sistema está realmente funcionando (processando requisições, atualizando estado, cumprindo prazos) pegam falhas que o monitoramento apenas em nível de processo deixa passar.
O Novo Software Espacial
A indústria espacial comercial (SpaceX, Rocket Lab, Planet) está desafiando algumas dessas tradições. A SpaceX usa Linux e C++ nos computadores de voo do Falcon 9, uma heresia pelos padrões tradicionais da aeroespacial. A Planet Labs opera centenas de pequenos satélites e os trata mais como um sistema distribuído do que como hardware sob medida: se um satélite falha, a constelação compensa.
Essa mudança reflete uma questão mais ampla: quanta confiabilidade você realmente precisa? Um rover de US$ 2,5 bilhões para Marte justifica cinco anos de testes. Um satélite de comunicações de US$ 500 mil, um entre centenas em uma constelação, justifica bem menos. A prática de engenharia deve acompanhar o perfil de risco, e não seguir cegamente tradições desenvolvidas para outra era.
Mas a lição central vale independentemente do orçamento: software que não pode ser acessado fisicamente após o deploy precisa ser mais confiável do que software que pode. Seja lançando uma espaçonave, fazendo deploy em uma frota de IoT ou operando uma rede de edge computing, o princípio é o mesmo: se você não pode dar SSH e consertar, o software precisa dar conta sozinho. Essa mentalidade, aplicada com critério, deixa todo software melhor.


