Pontos Principais
- A integração de APIs, serviços, dados e sistemas tem sido um dos requisitos mais desafiadores, porém essenciais, no contexto do desenvolvimento de aplicações de software corporativo.
- Fizemos uso, para integrar todos essas aplicações distintas, um estilo ponto a ponto, que foi posteriormente substituído pelo estilo ESB (Enterprise Service Bus), juntamente com a Service Oriented Architecture (SOA).
- À medida que cresce a popularidade de microservices e das arquiteturas "nativas em nuvem", surgiu o conceito de um "service mesh". A idéia-chave de um service mesh é manter todo o código da lógica de negócios como parte do serviço, ao mesmo tempo em que transfere a lógica de comunicação da rede para a infraestrutura de comunicação entre esses serviços.
- Como um service mesh oferece alguns dos recursos que fazem parte dos ESBs, há um equívoco de que se trata de um ESB distribuído, que também cuida da integração de aplicações. Isso não está correto.
- Um service mesh destina-se apenas a ser utilizado como uma infraestrutura para comunicação entre serviços, e os desenvolvedores não devem estar construindo nenhuma lógica de negócios dentro do service mesh. Outras estruturas e bibliotecas podem ser usadas para implementar padrões de integração de aplicações corporativas nativos em nuvem.
A integração de APIs, serviços, dados e sistemas tem sido um dos requisitos mais desafiadores, porém essenciais, no contexto do desenvolvimento de aplicações de software corporativo.
Fizemos uso, para integrar todos essas aplicações distintas um estilo ponto a ponto, que foi posteriormente substituído por barramentos de serviço corporativo (ESBs) juntamente com a arquitetura orientada a serviços (SOA).
No entanto, em casos de microservices modernos e de arquiteturas nativas em nuvem, quase não falamos mais sobre integração de aplicações. Isso não significa que todas essas arquiteturas modernas tenham resolvido todos os desafios de integração de aplicações corporativos.
Os desafios para integração de aplicações permaneceram praticamente os mesmos, mas a maneira como resolvemos esses desafios mudou.
Do ESB aos endpoints inteligentes e aos pipes simplificados
A maioria das empresas que adotaram o SOA usou um ESB como o barramento central para conectar e integrar todas as diferentes APIs, serviços, dados e sistemas.
Se um determinado caso de uso de negócios exigisse a conversação com diferentes entidades na organização, o trabalho do ESB seria investigar todas essas entidades e criar uma funcionalidade composta.
Portanto, as soluções de ESB são usualmente potências de todos os recursos integrados de integração, como conectores para sistemas e APIs diferentes, roteamento de mensagens, transformação, comunicação resiliente, persistência e transações.
[Clique na imagem para ampliá-la]
Figura 1: Usando o ESB para integração
No entanto, a arquitetura de microservices opta por substituir o ESB pela construção de endpoints inteligentes e pipes simplificados, o que significa que seus microservices precisam cuidar de toda a integração de aplicativos.
A desvantagem óbvia da descentralização do ESB inteligente é que a complexidade do código de seus microservices aumentará drasticamente, já que eles precisam atender a essas integrações de aplicações, além da lógica de negócios do serviço. Por exemplo, a figura 2 mostra vários microservices (B, F e G) que atuam como endpoints inteligentes, que contêm tanto a lógica da estrutura de comunicação entre vários outros serviços quanto a lógica de negócios.
[Clique na imagem para ampliá-la]
Figura 2: Microservices - comunicação e composição entre serviços
Um dos outros desafios de uma arquitetura de microservices é como construir os recursos de commodity que não fazem parte da lógica de negócios do serviço, como comunicação resiliente, segurança em nível de transporte, estatísticas de publicação, rastreamento de dados para uma ferramenta de observação, etc. para suportar esses recursos de commodity como parte da lógica de serviço. É incrivelmente complexo implementar todos eles em cada microservice, e o esforço necessário pode aumentar bastante se nossos microservices forem escritos em várias linguagens (poliglotas). Um service mesh pode resolver esse problema.
[Clique na imagem para ampliá-la]
Figura 3: Um service mesh em ação
A idéia chave de um service mesh é manter todo o código de lógica de negócios como parte do serviço e, ao mesmo tempo, transferir a lógica de comunicação de rede para a infraestrutura de comunicação entre serviços. Ao usar um service mesh, um determinado microservice não se comunicará diretamente com os outros microservices. Em vez disso, todas as comunicações de serviço a serviço ocorrerão por meio de um componente de software adicional, ficando sem processo, chamado de service-mesh proxy ou sidecar-proxy. Um processo de sidecar é colocado com o serviço na mesma máquina virtual (VM) ou pod (Kubernetes). A camada sidecar-proxy é conhecida como o plano de dados. Todos esses proxies sidecar são controlados através do plano de controle. É onde toda a configuração relacionada às comunicações entre serviços é aplicada.
Um service mesh não é para integração de aplicações
Como um service mesh oferece alguns dos recursos que fazem parte dos ESBs, há um equívoco de que ele é um ESB distribuído que também cuida da integração de aplicações. Isso não está correto. Um service mesh destina-se apenas a ser usado como infraestrutura para comunicação entre serviços, e não devemos criar nenhuma lógica comercial nele. Suponha que você tenha três microservices chamados X, Y e Z, que se comunicam no estilo request/response com X falando com Y e Z para implementar sua funcionalidade de negócios (veja a figura 4). A lógica de negócios da composição deve fazer parte do código do microservice X, e o sidecar do service mesh não deve conter nada relacionado a essa lógica de composição.
[Clique na imagem para ampliá-la]
Figura 4: Lógica de composição do serviço versus service mesh
Da mesma forma, para qualquer serviço que usa comunicação orientada a eventos, o código de serviço deve lidar com todos os detalhes da lógica de negócios (e também vale mencionar que as implementações do service mesh ainda precisam oferecer suporte total à arquitetura orientada a eventos). Portanto, mesmo que executemos nossos microservices ou aplicações nativos em nuvem sobre um service mesh, a integração desses serviços ou aplicações ainda é essencial. A integração de aplicações é um dos requisitos mais importantes, mas em grande parte ocultos, dos modernos microservices e da era da arquitetura nativa em nuvem.
Integração em microservices e aplicações nativas em nuvem
No contexto de microservices e aplicações nativas em nuvem, a integração de aplicações ou a criação de endpoints inteligentes é toda sobre a integração de microservices, APIs, dados e sistemas. Esses requisitos de integração vão desde a integração de vários microservices até a integração com subsistemas monolíticos para criar camadas anticorrupção. Um exame mais detalhado dos requisitos de integração de aplicativos em microservices e nas aplicações nativas em nuvem revela os seguintes recursos principais que precisamos ter em uma estrutura de integração de aplicações:
- O tempo de execução de integração deve ser nativo e em nuvem, capaz de funcionar sem problemas no Docker e no Kubernetes e fornecer integração contínua com o ecossistema nativo em nuvem.
- Ele precisa de orquestrações de serviço/composições ativas para que um determinado serviço contenha a lógica que invoca vários outros serviços para compor uma funcionalidade de negócios.
- Ele precisa de composições reativas de coreografia/serviço para que a comunicação entre serviços ocorra por meio da comunicação síncrona orientada a eventos e nenhum serviço central contenha a lógica de interação entre os serviços.
- Deve-se ter abstrações embutidas para uma ampla gama de protocolos de mensagens (HTTP, gRPC, GraphQL, Kafka, NATS, AMQP, FTP, SFTP, WebSockets, TCP).
- Ele deve oferecer suporte a forking, joining, splitting, looping, e agregação de mensagens ou chamadas de serviço.
- Ele precisa armazenar e encaminhar, fazer entrega persistente e técnicas de mensagens idempotentes.
- Deve ter mapeamento e transformações do tipo de mensagem.
- Ele deve se integrar aos sistemas SaaS (por exemplo, Salesforce), proprietário (por exemplo, SAP) e legado.
- Deve haver roteamento de mensagens orientado a lógica de negócios.
- Deve suportar transações distribuídas com compensações.
- Deve ter fluxos de trabalho de longa duração.
- As camadas anticorrupção devem unir microsserviços e subsistemas monolíticos.
Todos esses recursos são comuns em qualquer microservice ou aplicação nativo em nuvem, mas criá-los do zero pode ser uma tarefa assustadora. É por isso que é realmente importante analisar cuidadosamente esses recursos de integração quando criamos microservices ou aplicações nativos em nuvem e escolhemos a tecnologia ou a estrutura certa com base nos requisitos de integração. Por exemplo, se precisarmos criar um serviço que tenha uma lógica de orquestração complexa, devemos selecionar a estrutura de integração ou a tecnologia que facilita a gravação desses tipos de composições. Se quisermos construir um serviço que seja de longa duração e tenha capacidade de compensação, precisamos selecionar uma estrutura que tenha suporte interno para fluxos de trabalho e compensações (no artigo da InfoQ "Events, Flows and Long-Running Services: A Modern Approach to Workflow Automation"), Martin Schimak e Bernd Rücker fornecem uma análise profunda do estado atual das tecnologias de workflow para arquiteturas nativas em nuvem).
Embora a integração de aplicações tenha sido amplamente negligenciada pela maioria dos especialistas em microservices, autores como Christian Posta (ex-arquiteto chefe da Red Hat e CTO de campo na Solo.io) enfatizaram a importância da integração de aplicações, como na publicação no blog de Christian Posta "Application Safety and Correctness Cannot Be Offloaded to Istio or Any Service Mesh". Bilgin Ibryam escreveu sobre como a arquitetura de integração de aplicações evoluiu de SOA para arquitetura nativa em nuvem em seu artigo na InfoQ sobre "Microservices in a Post-Kubernetes Era", no qual ele enfatiza a descentralização da integração de aplicações com arquitetura nativa em nuvem e como a integração entre aplicações está sendo construída na camada superior de um service mesh.
Desenvolvimento e integração no panorama da CNCF
A Cloud Native Computing Foundation (CNCF) está na vanguarda da criação de microservices e aplicações nativas em nuvem e visa construir ecossistemas sustentáveis e fomentar uma comunidade em torno de uma constelação de projetos de alta qualidade que orquestram containers como parte de uma arquitetura de microservices. O CNCF hospeda projetos compostos de tecnologias de código aberto e estruturas que podem implementar diferentes aspectos de microservices ou de uma arquitetura nativa em nuvem. É interessante ver onde essas tecnologias de integração de aplicações se encaixam em sua stack de tecnologia.
O caminho recomendado pelo CNCF através do cenário nativo em nuvem tem uma seção de Desenvolvimento e Definição de Aplicação, mas nenhuma categoria dedicada ao desenvolvimento ou integração de aplicações. Dada a importância da integração de aplicações, no entanto, podemos vê-los no cenário CNCF no futuro. A Figura 5 inclui tecnologias de Integração de Aplicações em Definição e Desenvolvimento de Aplicações.
[Clique na imagem para ampliá-la]
Figura 5: Integração de aplicações em um futuro panorama CNCF
Tecnologias para integração de aplicações
Embora existam muitas tecnologias monolíticas de integração de aplicações disponíveis, a maioria não é adequada para arquiteturas nativas em nuvem ou de microservices. Apenas alguns provedores de integração existentes implementaram variantes nativas em nuvem de seus produtos e ferramentas.
Existem estruturas de integração dedicadas que facilitam todos os padrões de integração comuns no espaço de integração de aplicações. Geralmente, a maioria dessas tecnologias é herdada da integração convencional baseada em ESB, mas elas foram modificadas e nativamente integradas em arquiteturas nativas em nuvem:
- O Apache Camel/Camel-K é um dos populares frameworks de integração de código aberto e o projeto Camel-K oferece suporte contínuo para o ecossistema Kubernetes no topo do tempo de execução do Camel.
- O WSO2 Micro Integrator é uma variante nativa em nuvem da plataforma WSO2 Enterprise Integrator de código aberto. O Micro Integrator oferece um tempo de execução de integração leve que funciona nativamente no ecossistema Kubernetes.
- Embora o Spring Integration não tenha um tempo de execução dedicado para funcionar no Kubernetes, ele funciona bem na criação de integrações de aplicações em uma arquitetura nativa e em nuvem.
Algumas das estruturas de desenvolvimento de aplicações também atendem aos requisitos de integração de aplicações:
O Spring Boot não é uma estrutura de integração em si, mas possui muitos recursos substanciais necessários para a integração de aplicações.
O Vert.x é um kit de ferramentas para a criação de aplicações reativas e nativas em nuvem, que também podem ser usados para integração de aplicações.
O Micronaut é uma estrutura moderna, baseada em JVM, com uma stack completa para a construção de aplicações de microservices e serverless modulares e facilmente testáveis. Existem algumas abstrações de integração incorporadas ao framework e que evitam as complexidades de frameworks convencionais como o Spring.
Linguagens de programação, como Go, JavaScript/Node.js, etc., possuem determinados recursos de integração de aplicações embutidos ou disponíveis como bibliotecas. Existem novas linguagens emergentes, como a Ballerina, que oferecem abstrações de integração como parte da linguagem.
O Quarkus é uma nova stack Java nativa do Kubernetes que foi criada para GraalVM e OpenJDK HotSpot, montada a partir das melhores bibliotecas e padrões Java. É uma combinação de várias bibliotecas de desenvolvimento de aplicações, como RESTeasy, Camel, Netty etc.
Conclusão
Com a segregação de aplicações monolíticas em aplicações de microservices e nativos em nuvem, o requisito para conectar essas aplicações está se tornando cada vez mais desafiador. Os serviços e aplicações estão dispersos na rede e conectados por estruturas de comunicação distintas. A realização de qualquer caso de uso de negócios requer a integração dos microservices, o que precisa ser feito como parte da lógica de implementação do serviço. Como resultado, a integração de aplicações nativas em nuvem é um dos requisitos mais importantes, porém amplamente ocultos, na era moderna de microservices e de uma arquitetura nativa em nuvem.
O padrão service mesh supera alguns dos desafios na integração de microservices, mas oferece apenas os recursos básicos de comunicação entre serviços, que são independentes da lógica de negócios do serviço e, portanto, qualquer lógica de integração de aplicações relacionada ao caso de uso de negócios deve ainda ser implementado em cada nível de serviço. Assim, é importante selecionar a tecnologia de desenvolvimento mais apropriada para criar serviços especializados em integração e minimizar o tempo de desenvolvimento necessário para unir os serviços. Diversas estruturas e tecnologias estão surgindo para atender a essas necessidades de integração de aplicações no cenário nativo da nuvem, que precisamos avaliar em relação a cada caso de uso específico.
Sobre o Autor
Kasun Indrasiri é o diretor de Arquitetura de Integração da WSO2 e é autor/evangelista em arquitetura microservices e arquitetura de integração corporativa. Ele escreveu os livros Microservices for Enterprise (Apress) e Beginning WSO2 ESB (Apress). Ele também é um committer da Apache e trabalhou como gerente de produto e arquiteto para o WSO2 Enterprise Integrator. Já realizou apresentações na O'Reilly Software Architecture Conference, no GOTO Chicago 2019, e na maioria das conferências WSO2. Ele participa da maioria dos encontros de microservices da Área da Baía de São Francisco/EUA. Fundou o meetup de Microservice, APIs e Integration do Silicon Valley, um encontro sobre microservices neutro de fornecedor na Bay Area.