![O DevOps não está morto, mas também não está em ótima saúde](https://optimuscloud.com.br/wp-content/uploads/2024/07/1719936005_O-DevOps-nao-esta-morto-mas-tambem-nao-esta-em-150x150.jpg)
O DevOps não está morto, mas também não está em ótima saúde
2 de julho de 2024![Documentação deficiente é cara: veja como consertar](https://optimuscloud.com.br/wp-content/uploads/2024/07/1719944525_Documentacao-deficiente-e-cara-veja-como-consertar-150x150.jpg)
Documentação deficiente é cara: veja como consertar
2 de julho de 2024Para a maioria das aplicações atuais, dizer que você as hospeda em seu próprio data center será como dizer que você gera sua própria eletricidade. Por que pagar todo esse investimento para fornecer hardware suficiente para cobrir seus picos de carga, o que pode acontecer apenas uma vez por ano, e depois gastar o investimento para alimentar e resfriar essas máquinas, bem como para mantê-las? Deixe alguém como Amazon, Microsoft ou Google fazer isso por você e pague apenas pelo que usar da mesma forma que paga com sua conta de luz.
Esta é a promessa da computação em nuvem: um modelo de preços baseado em serviços públicos com contas mais baixas para executar seus aplicativos empresariais de missão crítica.
Infelizmente, a realidade muitas vezes acaba sendo diferente e as pessoas descobrem que migrar para a nuvem lhes custa mais do que hospedar no local. Como isso pode ser e como podemos resolver isso?
Vejamos especificamente os aplicativos baseados em JVM usando Java. Entretanto, muitas outras linguagens, como Kotlin, Scala e Clojure, também podem ser compiladas para a JVM.
A abordagem moderna para arquitetar aplicativos baseados em nuvem é usar microsserviços. Em vez de desenvolver um aplicativo único e monolítico, dividimos o aplicativo em serviços discretos que podem ser fracamente acoplados, mas altamente coesos. Ao fazer isso, quando um serviço se torna um gargalo no desempenho, podemos criar novas instâncias desse serviço, balancear a carga de uso e eliminar o gargalo sem precisar alterar outras partes do sistema.
É aqui que uma das principais funcionalidades da JVM pode levar ao desperdício de recursos da nuvem.
Para cumprir a promessa de “escrever uma vez, executar em qualquer lugar”.”, Aplicativos Java são compilados em bytecodes, as instruções de uma máquina virtual, em vez de um processador específico. Quando um aplicativo Java é iniciado, a JVM cria um perfil dele e identifica pontos de acesso de código usados com frequência que podem ser compilados em código nativo. Essa compilação just-in-time (JIT) oferece excelente desempenho, pois a JVM sabe exatamente como o código está sendo usado e pode otimizá-lo adequadamente.
No entanto, o tempo necessário para que todas as seções de código usadas com frequência sejam identificadas e compiladas, o que na verdade é um processo mais complexo e de vários estágios, pode ser mais longo do que o desejado. Esse tempo de aquecimento, como é chamado, geralmente não é um problema para processos de longa execução, como servidores da Web ou de aplicativos. Os microsserviços podem iniciar e parar com frequência para responder dinamicamente à variação de carga. Esperar que um microsserviço aqueça antes de poder fornecer capacidade total de carga reduz os benefícios dessa abordagem.
Uma solução frequentemente usada é iniciar várias instâncias de um serviço e deixá-las em execução para que estejam prontas para fornecer desempenho total imediatamente quando necessário. Obviamente, isso representa um grande desperdício e acarreta custos desnecessários de infraestrutura em nuvem.
Como podemos resolver este problema?
Uma abordagem é usar a compilação antecipada (AOT). Em vez de usar a compilação JIT, todo o código é compilado diretamente para instruções nativas. Isso elimina totalmente o aquecimento e o aplicativo inicia com o nível total de desempenho disponível.
Embora pareça a solução ideal, não é isenta de custos e limitações.
AOT compila código sem saber como ele realmente será usado, limitando o potencial de otimização. A compilação JIT possui informações de perfil que permitem otimizações adaptadas precisamente à forma como o aplicativo está sendo usado. Normalmente, isso resulta em um desempenho geral insignificantemente melhor.
Para microsserviços efêmeros, a chamada computação sem servidor, a AOT oferece benefícios definitivos. Para qualquer serviço que seja executado por pelo menos alguns minutos, o JIT resultará em melhor desempenho e, portanto, menores custos de computação em nuvem.
Uma solução alternativa é aquela que a Azul implementou como parte de seu tempo de execução Java de alto desempenho Platform Prime. Isso inclui a tecnologia de eliminação de aquecimento ReadyNow.
O problema, como vimos, é que cada vez que iniciamos uma instância de um microsserviço, a JVM deve realizar a mesma análise para identificar pontos de acesso, coletar informações de perfil e compilá-las em código nativo. Isso acontece mesmo quando já usamos esse microsserviço da mesma maneira muitas vezes. Com o ReadyNow, o serviço é iniciado e pode aquecer na produção usando solicitações do mundo real, não simuladas. Quando o serviço estiver totalmente aquecido (atingiu seu nível ideal de desempenho), um perfil é coletado. Este perfil inclui todas as informações necessárias para obter esse nível de desempenho: uma lista de pontos de acesso, dados de criação de perfil e até mesmo código compilado.
Quando o serviço precisar ser reiniciado, o perfil será fornecido como parte dos parâmetros de execução. A JVM usa o perfil para garantir que, quando estiver pronta para lidar com a primeira transação, o desempenho estará quase no nível de quando o perfil foi criado (cerca de 98%, pois algumas limitações técnicas sobre como a JVM funciona impedem a entrega de 100%).
O resultado é que quase todo o tempo de aquecimento é eliminado, mantendo todos os benefícios de desempenho da compilação JIT. Este sistema oferece total flexibilidade, pois diferentes perfis podem ser utilizados para o mesmo serviço, dependendo de quando e onde o serviço está em uso. Por exemplo, o perfil da carga de trabalho pode ser muito diferente numa segunda-feira de manhã e numa sexta-feira à tarde. Vários perfis podem ser armazenados e o apropriado pode ser selecionado quando necessário.
Agora que os microsserviços baseados em JVM podem ter um tempo de aquecimento mínimo, não há necessidade de manter um conjunto de serviços ocioso em segundo plano. Isso pode reduzir significativamente o desperdício na nuvem.
Uma JVM com desempenho otimizado que também inclua um sistema alternativo de gerenciamento de memória, eliminando a latência para transações normalmente associadas a isso, é uma ótima opção. O sistema de compilação JIT também foi aprimorado para oferecer maior produtividade. Em vez de reduzir o desperdício na nuvem, estes simplesmente reduzem os recursos da nuvem necessários para fornecer a mesma capacidade de carga. O efeito é reduzir ainda mais os custos da nuvem.
Vejamos um exemplo de como isso funcionou para um cliente real. Supercell é uma empresa que administra alguns dos maiores jogos multijogador online do mundo. Para o lançamento recente do Brawl Stars, houve atrasos na ativação de novos servidores enquanto as JVMs compilavam o código necessário. Ao mudar para a Plataforma Azul Prime e explorar o ReadyNow, ele foi capaz de fornecer capacidade de carga muito mais consistente, reduzindo o atraso do jogo e reduzindo o uso da CPU em 20 a 25% para a mesma carga de trabalho.
Claramente, uma JVM que executa código mais rápido significa que são necessários menos recursos de nuvem.
A postagem Como reduzir o desperdício na nuvem apareceu pela primeira vez no The New Stack.