Nessa palestra é apresentada a experiência do iFood no uso de técnicas Reactive, que permitem ganhar desempenho e escala em microservices – em arquiteturas que demandam alto nível de processamento e ao mesmo tempo baixo consumo de recursos.
Veremos como o framework Reactor, a base reativa do Spring 5.0, está apoiando a evolução de microservices no iFood. O uso de microservices e Reactive está ajudando a atender um alto tráfego de eventos e requests em tempo real e a acompanhar a demanda de pedidos, que triplica a cada ano.
Serão explorados os pilares do reactive manifesto (Responsive, Elastic, Resilient, Message-driven), conceitos de Reactive Streams e Backpressure e de fluxos bloqueantes/não-bloqueantes – e como aplicar muitos desses conceitos na prática usando o framework Reactor e o Spring 5.0.
3. Order food from
App or Web
Restaurant receives
the order
Confirms the order
and prepare
Back office
operators
Customer search
for restaurants
APIs
Online Delivery
7. Programação imperativa
Descrevemos como um programa deve se comportar
Sequência de passos (comandos)
Chamadas para alterar o estado de um recurso
Tradicional
Fácil entendimento e ensino
8. Mas com o crescimento . . .
Número de acessos
Consumo de recursos
Tempo de resposta aceitável
Falhas não podem impactar
Popularização de Cloud Computing
Adoção de Microservices
12. Responsive: sempre responder e com baixa latência
Resilient: sem downtime, responder mesmo em situações de falha
Elastic: responder mesmo quando for sobrecarregado, auto escalar
Message Driven: comunicação por mensagens async, baixo acoplamento
15. Blocking pode ser um desperdício !
Tempo de resposta pode ficar comprometido
Paralelizar: performance com aumento de Threads
Threads são custosas e limitadas
I/O é lento (chamadas para DB, HTTP…)
Threads esperando resposta :(
Desperdício de recurso !
19. Reactive Programing
● Paradigma baseado no consumo de eventos
● Alteração de dados "over time" -> dispara ações (callback)
● Publish-Subscribe
● Lógica declarativa e composição de operações
● Async e non-blocking
● Escalar vertical -> poucas threads
● Contexto local (não distribuído)
● Desacoplamento no tempo (concorrência)
20. Reactive streams
● Padronização de APIs: manipulação de streams de dados
● Backpressure
○ Feedback enviado para o produtor quando o consumidor está pronto para consumir
○ Importante quando o produtor está mais rápido que o consumidor
● Frameworks: Reactor, RxJava, Akka, Vert.x …
● Java 9: java.util.concurrent.Flow
* Source: Reactive Streams (4)
"Padrão para processamento de fluxo de dados assíncrono com backpressure non-blocking" *
21. Reactor
"Reactor is a fourth-generation Reactive library for building non-blocking
applications on the JVM based on the Reactive Streams Specification"
22. Reactor
Implementação de reactive streams
Publisher
● Mono: 0 ou 1 item
● Flux: sequencia async de 0 a N itens
Subscribers
● Consumir dados de publishers (callbacks de sucesso, erro, completo)
● subscribe() -> trigger para startar fluxo de dados
● Nada ocorre sem subscribe()
23. Exemplo
Flux.range(0, 20)
.filter(n -> n % 2 == 0)
.map(n -> "Number: " + n)
.subscribe(s -> System.out.println( s + " Thread: " + Thread.currentThread().getName()));
Number: 0 Thread: main
Number: 2 Thread: main
Number: 4 Thread: main
Number: 6 Thread: main
Number: 8 Thread: main
Number: 10 Thread: main
Number: 12 Thread: main
Number: 14 Thread: main
Number: 16 Thread: main
Number: 18 Thread: main
29. Reactive Systems
Reatividade em sistemas distribuídos
Desacoplamento
● Tempo: concorrência e paralelismo
● Espaço: transparência na localização de componentes
Conjunto de padrões arquiteturais e princípios
● Message based
● Resilience
● Elasticity
● …
● Location transparency
34. Alguns problemas atacados
Entrega de pedidos aos restaurantes
Sincronização de dados entre sistemas
Integrações com parceiros
Disparo de tarefas (sms, push, emails, cancelamentos…)
38. Resultados positivos
● 16K restaurantes conectados
● Entrega de 3MM pedidos e transição de estados
● Push de pedidos polling
● ⇩Tempos de recepção de pedidos
● Disponibilidade de restaurantes (centralizado)
● Elasticidade com recursos menores
● Independência do sistema legado
● Mais responsivo e resiliente (às falhas)
39.
40. Dificuldades
Debug
Trace de erros e logging
Curva maior para novos desenvolvedores
Dependência de rede e infraestrutura
Monitoramento de lógica específica de cada serviço
Maturidade em ambiente de produção custosa
41. Concluindo...
Migraçao para microservices é realidade
Aplicar princípios reactive entre microservices
Reactive programming internamente para microservices
Melhor uso de recursos (mais com menos)
Necessário para acompanhar todo crescimento!