"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Por que descartamos a arquitetura de sistemas reativos do nosso código?

Por que descartamos a arquitetura de sistemas reativos do nosso código?

Publicado em 2024-09-02
Navegar:646

Este artigo explora nossa decisão de abandonar a arquitetura reativa em nosso projeto de software. Iremos nos aprofundar nos princípios básicos dos sistemas reativos, nos benefícios da E/S sem bloqueio e nos desafios que enfrentamos com uma abordagem reativa.

Compreendendo o estilo de arquitetura reativa

Reactive engloba um conjunto de princípios e diretrizes que visam a construção de sistemas e aplicações distribuídas responsivas, caracterizado por:

  1. Capacidade de resposta: Capaz de lidar rapidamente com solicitações, mesmo sob cargas pesadas.
  2. Resiliência: Capaz de se recuperar de falhas com tempo de inatividade mínimo.
  3. Elasticidade: Pode se adaptar às mudanças nas cargas de trabalho, dimensionando os recursos de acordo.
  4. Orientado por mensagens: utiliza mensagens assíncronas para aprimorar a tolerância a falhas e desacoplar componentes.

Um dos principais benefícios dos sistemas reativos é o uso de E/S sem bloqueio. Essa abordagem evita o bloqueio de threads durante operações de E/S, permitindo que um único thread lide com múltiplas solicitações simultaneamente. Isso pode melhorar significativamente a eficiência do sistema em comparação com o bloqueio tradicional de E/S.
No multithreading tradicional, as operações de bloqueio representam desafios significativos na otimização de sistemas (Figura 1). Aplicativos gananciosos que consomem memória excessiva são ineficientes e penalizam outros aplicativos, muitas vezes necessitando de solicitações de recursos adicionais, como memória, CPU ou máquinas virtuais maiores.

Why we discarded Reactive systems architecture from our code?

Figura 1 – Multithreading tradicional


As operações de E/S são essenciais para os sistemas modernos e gerenciá-las com eficiência é fundamental para evitar comportamentos gananciosos. Os sistemas reativos empregam E/S sem bloqueio, permitindo que um baixo número de threads do sistema operacional lide com inúmeras operações de E/S simultâneas.

Modelo de Execução Reativa

Embora a E/S sem bloqueio ofereça benefícios substanciais, ela introduz um novo modelo de execução distinto das estruturas tradicionais. A programação reativa surgiu para resolver esse problema, pois mitiga a ineficiência dos threads da plataforma ociosos durante as operações de bloqueio (Figura 2).

Why we discarded Reactive systems architecture from our code?

Figura 2 – Ciclo de eventos reativos


Quarkus e Reativo

O Quarkus aproveita um mecanismo reativo desenvolvido com Eclipse Vert.x e Netty, facilitando interações de E/S sem bloqueio. Mutiny, a abordagem preferida para escrever código reativo com Quarkus, adota um paradigma orientado a eventos, em que as reações são desencadeadas por eventos recebidos.

Mutiny oferece dois tipos preguiçosos e orientados a eventos:

  1. Uni: Emite um único evento (um item ou uma falha), adequado para representar ações assíncronas com zero ou um resultado.
  2. Multi: Emite vários eventos (n itens, uma falha ou uma conclusão), representando fluxos de itens, potencialmente ilimitados.

Desafios com Reativo

Embora os sistemas reativos ofereçam benefícios, encontramos vários desafios durante o desenvolvimento:

  • Mudança de paradigma: A programação reativa exige uma mudança fundamental na mentalidade dos desenvolvedores, o que pode ser desafiador, especialmente para desenvolvedores acostumados com programação imperativa. Ao contrário de ferramentas auxiliares como a API Streams, a abordagem reativa exige uma revisão completa da mentalidade.
  • Legibilidade e compreensão do código: O código reativo apresenta dificuldades para novos desenvolvedores compreenderem, levando a um maior tempo gasto para decifrá-lo e compreendê-lo. A complexidade introduzida pelos paradigmas reativos agrava esta questão.

"Na verdade, a proporção de tempo gasto lendo versus escrevendo é bem superior a 10 para 1. Estamos constantemente lendo código antigo como parte do esforço para escrever novo código. ...[Portanto,] facilitar a leitura torna é mais fácil escrever."
Robert C. Martin, Código Limpo: Um Manual de Artesanato de Software Ágil

  • Desafios de depuração: A depuração de código reativo se mostra quase impossível com depuradores IDE padrão devido aos lambdas que encapsulam a maior parte do código. Além disso, a perda de rastreamentos de pilha significativos durante as exceções dificulta ainda mais os esforços de depuração. Maiores esforços de desenvolvimento e teste: A complexidade inerente do código reativo pode levar a ciclos de desenvolvimento mais longos devido ao tempo necessário para escrever, modificar e testar.

Aqui está um exemplo de código reativo usando Mutiny para ilustrar a complexidade:

Multi.createFrom().ticks().every(Duration.ofSeconds(15))
    .onItem().invoke(() - > Multi.createFrom().iterable(configs())
    .onItem().transform(configuration - > {
  try {
    return Tuple2.of(openAPIConfiguration,
        RestClientBuilder.newBuilder()
            .baseUrl(new URL(configuration.url()))
            .build(MyReactiveRestClient.class)
            .getAPIResponse());

  } catch (MalformedURLException e) {
    log.error("Unable to create url");

  }
  return null;
}).collect().asList().toMulti().onItem().transformToMultiAndConcatenate(tuples - > {

  AtomicInteger callbackCount = new AtomicInteger();
  return Multi.createFrom().emitter(emitter - > Multi.createFrom().iterable(tuples)
      .subscribe().with(tuple - >
          tuple.getItem2().subscribe().with(response - > {
              emitter.emit(callbackCount.incrementAndGet());

  if (callbackCount.get() == tuples.size()) {
    emitter.complete();
  }
                    })
                ));

}).subscribe().with(s - > {},
Throwable::printStackTrace, () - > doSomethingUponComplete()))
    .subscribe().with(aLong - > log.info("Tic Tac with iteration: "   aLong));

Futuro Outlook-Project Loom e além

Project Loom, um desenvolvimento recente no ecossistema Java, promete mitigar os problemas associados ao bloqueio de operações. Ao permitir a criação de milhares de threads virtuais sem alterações de hardware, o Project Loom poderia potencialmente eliminar a necessidade de uma abordagem reativa em muitos casos.

"O Projeto Loom vai acabar com a Programação Reativa"
Brian Goetz

Conclusão

Concluindo, nossa decisão de abandonar o estilo de arquitetura reativa é uma abordagem pragmática para a manutenção de longo prazo do nosso projeto. Embora os sistemas reativos ofereçam benefícios potenciais, os desafios que apresentaram para a nossa equipe superaram essas vantagens em nosso contexto específico.

É importante ressaltar que essa mudança não comprometeu o desempenho. Este é um resultado positivo, pois demonstra que uma arquitetura não reativa (imperativa) bem projetada pode fornecer o desempenho necessário sem a complexidade associada à arquitetura reativa no nosso caso.

À medida que olhamos para o futuro, o foco permanece na construção de uma base de código que não seja apenas funcional, mas também fácil de entender e manter para desenvolvedores de todos os níveis de experiência. Isso não apenas reduz o tempo de desenvolvimento, mas também promove uma melhor colaboração e compartilhamento de conhecimento dentro da equipe.

No gráfico abaixo, o eixo X representa a complexidade crescente de nossa base de código à medida que ela evolui, enquanto o eixo Y representa o tempo necessário para essas mudanças de desenvolvimento.

Why we discarded Reactive systems architecture from our code?

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/yanev/why-we-discarded-reactive-systems-architecture-from-our-code-19ni?1 Se houver alguma violação, entre em contato com [email protected] para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3