Criando Microservices Reativos com Java
Rodrigo Cândido da Silva
@rcandidosilva
Agenda
• Monolito vs. Microservices
• Manifesto Reativo
• Resiliência
• Elasticidade
• Message-Driven
• Perguntas
Monolito vs. Microservices
Microservices
• Pequenos
• Deployment interdependente
• Independente de tecnologia
• Infra-estrutura separada
"Small independent component with well-
defined boundaries that’s doing one thing,
but doing it well"
Manifesto Reativo
Resiliência
• Quais os principais desafios?
• Configuração centralizada
• Serviço de registro e descoberta
• Roteamento
• Tolerância à falhas
• Gestão de segurança
Spring BootSpring Cloud
Spring Cloud + Netflix OSS
Spring Cloud + Netflix OSS
“Nice match to build resilient microservices with
Java"
Gerenciamento de Configuração Spring Cloud Config + Bus
Descoberta de Serviços Netflix Eureka
Balanceamento de Carga Netflix Ribbon
Circuit Breaker Netflix Hystrix + Turbine
Proxy Server Netflix Zuul
Segurança Spring Cloud Security
Spring Cloud Config
Netflix Eureka
Netflix Ribbon
Netflix Hystrix
• Circuit Breaker Pattern
Netflix Zuul
Spring Cloud Security
Discovery	
Client
Relying Party
Resource
Server
Get an access token
& an ID Token (JWT)
Use an access token
Authorization
Server
Iden.ty	Provider	or	
IDP	or		
OpenID	Provider	or	
OP	
	
	
Authorization
Endpoint
Token
Endpoint
Important Stuff
Userinfo
Endpoint
Registration
Endpoint
JWKS
Endpoint
JWKS
Endpoint
Validate
(JWT)
ID Token
/.well-known	
/webfinger	
/openid-configura.on
Check Session IFrame
End Session Endpoint
Elasticidade
• Quais os principais desafios?
• Deployment Distribuído
• Auto Escalabilidade
• Orquestração
• Balanceamento de carga
• Redundância
• Monitoramento
Deployment
Deployment
Monolito Microservice
Auto Scaling
• Capacidade de aumentar e diminuir a escalabilidade
automaticamente
Orquestração
• Gerenciamento da comunicação dos serviços em containers
diferentes
Deployment vs Environments
• Múltiplos ambientes diferentes de execução
Monitoramento
• Utilização de ferramentas para agregação logs
• ELK, Sentry, Logentries, Splunk
• Mecanismos de correlação de eventos
• Spring Cloud Sleuth
• Utilização de ferramentas para tracing
• Zipkin, HTrace
• Monitoramento com health check
• Spring Boot Admin
Ferramentas
AWS ECS
Message-Driven
• Quais os principais desafios?
• Comunicação Assíncrona
• Non blocking I/O
• Ambiente Distribuido
• Queuing
• Consistência
• Event sourcing
• CQRS
Blocking vs Non-Blocking
Sync vs Async
Sync
Async
Reactive Programming
• Baseado no consumo de eventos e streams
• “Everything is stream"
• Alteração de dados “over time” (via callbacks)
• Comunicação Async e Non-Blocking
• Modelo publish / subscribe
• Java 9
• java.util.concurrent.Flow
• reactive-streams.org
Alternativas Reativas com Java EE
JMS EJB 3
Message-Driven
Beans
Asynchronous
Session Beans
CDI
Events
Observers
Servlet
Asynchronous
NIO
JAX-RS
Async on Server
Async on Client
WebSocket
Async Remote
Endpoints
Concurrency
Utilities
RxJava
• Biblioteca para criação de non-blocking apps
• Implementação de reactive streams
• Interage com Java 8 functional API
• Suporta comportamentos especiais
• Error handling, scheduling, flow control
• Utilizado pelo Netflix na “async service layer”
RxJava
RxJava
API Gateway
• Design pattern at microservices
• Requisições podem ser apenas repassadas, ou
modificadas
• Pode implementar uma camada de serviços assíncrona
“Single entry point for the service clients”
Service Endpoint
@RestController
public class UserRestController {
private static final List<User> users = new ArrayList<>();
static {
users.add(new User(1, "Rodrigo", "C", "da Silva"));
users.add(new User(2, "Israel", "B", "Rodriguez"));
users.add(new User(3, "Bruno", "", "Souza"));
users.add(new User(4, "Edson", "", "Yanaga"));
}
@RequestMapping(method = RequestMethod.GET, value = "/users")
public List<User> getUsers() {
return users;
}
@RequestMapping(method = RequestMethod.GET, value = "/user/{id}")
public User getUser(@PathVariable("id") Integer id) {
return users.stream().filter(g -> g.getId() == id)
.collect(Collectors.toList()).get(0);
}
}
Async Service Proxy
@Component
public class UserServiceProxy {
@Autowired UserService service;
@HystrixCommand(fallbackMethod = "defaultUsersObservable")
public Observable<List<User>> getUsersObservable() {
return new ObservableResult<List<User>>() {
@Override
public List<User> invoke() {
return service.getUsers();
}
};
}
public Observable<User> defaultUsersObservable() {
return null;
}
} @FeignClient("USER-SERVICE")
public interface UserService {
@RequestMapping(value = "/users", method = RequestMethod.GET)
List<User> getUsers();
@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
User getUser(@PathVariable("id") Integer id);
}
API Gateway
@RestController
public class APIGateway {
@Autowired
GroupServiceProxy groupService;
@Autowired
UserServiceProxy userService;
@RequestMapping(method = RequestMethod.GET, value = "/userGroups")
public UserGroup getUserGroups() {
Observable<List<Group>> groups = groupService.getGroupsObservable();
Observable<List<User>> users = userService.getUsersObservable();
Observable<UserGroup> userGroupObservable =
Observable.zip(groups, users, (g, u) -> new UserGroup(u, g));
return userGroupObservable.toList().toBlocking().single().get(0);
}
}
Outras Alternativas
Project Reactor
Conclusões
• Arquitetura com microservices é complexa
• Manifesto reativo define princípios para implementar uma
arquitetura de microservices reativa
• Async e Non-Blocking IO são praticas importantes para
atingir princípios reativos
• RxJava oferece uma implementação para streams reativos
• Não se esqueça de implementar API Gateway’s
• Enjoy it ;)
Perguntas
?
References
• http://projects.spring.io/spring-cloud/
• https://netflix.github.io/
• http://www.reactive-streams.org/
• http://www.reactivemanifesto.org/
• https://github.com/reactivemanifesto/website-manifesto/tree/master/public/pdf
• https://github.com/ReactiveX/RxJava
• https://projectreactor.io/
• http://reactivex.io/
• https://cloud.spring.io/spring-cloud-stream/
Muito Obrigado!
@rcandidosilva
rodrigocandido.me

TDC Floripa 2017 - Criando Microservices Reativos com Java

  • 1.
    Criando Microservices Reativoscom Java Rodrigo Cândido da Silva @rcandidosilva
  • 2.
    Agenda • Monolito vs.Microservices • Manifesto Reativo • Resiliência • Elasticidade • Message-Driven • Perguntas
  • 3.
  • 4.
    Microservices • Pequenos • Deploymentinterdependente • Independente de tecnologia • Infra-estrutura separada "Small independent component with well- defined boundaries that’s doing one thing, but doing it well"
  • 5.
  • 6.
    Resiliência • Quais osprincipais desafios? • Configuração centralizada • Serviço de registro e descoberta • Roteamento • Tolerância à falhas • Gestão de segurança
  • 7.
    Spring BootSpring Cloud SpringCloud + Netflix OSS
  • 8.
    Spring Cloud +Netflix OSS “Nice match to build resilient microservices with Java" Gerenciamento de Configuração Spring Cloud Config + Bus Descoberta de Serviços Netflix Eureka Balanceamento de Carga Netflix Ribbon Circuit Breaker Netflix Hystrix + Turbine Proxy Server Netflix Zuul Segurança Spring Cloud Security
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
    Spring Cloud Security Discovery Client RelyingParty Resource Server Get an access token & an ID Token (JWT) Use an access token Authorization Server Iden.ty Provider or IDP or OpenID Provider or OP Authorization Endpoint Token Endpoint Important Stuff Userinfo Endpoint Registration Endpoint JWKS Endpoint JWKS Endpoint Validate (JWT) ID Token /.well-known /webfinger /openid-configura.on Check Session IFrame End Session Endpoint
  • 15.
    Elasticidade • Quais osprincipais desafios? • Deployment Distribuído • Auto Escalabilidade • Orquestração • Balanceamento de carga • Redundância • Monitoramento
  • 16.
  • 17.
  • 18.
    Auto Scaling • Capacidadede aumentar e diminuir a escalabilidade automaticamente
  • 19.
    Orquestração • Gerenciamento dacomunicação dos serviços em containers diferentes
  • 20.
    Deployment vs Environments •Múltiplos ambientes diferentes de execução
  • 21.
    Monitoramento • Utilização deferramentas para agregação logs • ELK, Sentry, Logentries, Splunk • Mecanismos de correlação de eventos • Spring Cloud Sleuth • Utilização de ferramentas para tracing • Zipkin, HTrace • Monitoramento com health check • Spring Boot Admin
  • 22.
  • 23.
    Message-Driven • Quais osprincipais desafios? • Comunicação Assíncrona • Non blocking I/O • Ambiente Distribuido • Queuing • Consistência • Event sourcing • CQRS
  • 24.
  • 25.
  • 26.
    Reactive Programming • Baseadono consumo de eventos e streams • “Everything is stream" • Alteração de dados “over time” (via callbacks) • Comunicação Async e Non-Blocking • Modelo publish / subscribe • Java 9 • java.util.concurrent.Flow • reactive-streams.org
  • 27.
    Alternativas Reativas comJava EE JMS EJB 3 Message-Driven Beans Asynchronous Session Beans CDI Events Observers Servlet Asynchronous NIO JAX-RS Async on Server Async on Client WebSocket Async Remote Endpoints Concurrency Utilities
  • 28.
    RxJava • Biblioteca paracriação de non-blocking apps • Implementação de reactive streams • Interage com Java 8 functional API • Suporta comportamentos especiais • Error handling, scheduling, flow control • Utilizado pelo Netflix na “async service layer”
  • 29.
  • 30.
  • 31.
    API Gateway • Designpattern at microservices • Requisições podem ser apenas repassadas, ou modificadas • Pode implementar uma camada de serviços assíncrona “Single entry point for the service clients”
  • 32.
    Service Endpoint @RestController public classUserRestController { private static final List<User> users = new ArrayList<>(); static { users.add(new User(1, "Rodrigo", "C", "da Silva")); users.add(new User(2, "Israel", "B", "Rodriguez")); users.add(new User(3, "Bruno", "", "Souza")); users.add(new User(4, "Edson", "", "Yanaga")); } @RequestMapping(method = RequestMethod.GET, value = "/users") public List<User> getUsers() { return users; } @RequestMapping(method = RequestMethod.GET, value = "/user/{id}") public User getUser(@PathVariable("id") Integer id) { return users.stream().filter(g -> g.getId() == id) .collect(Collectors.toList()).get(0); } }
  • 33.
    Async Service Proxy @Component publicclass UserServiceProxy { @Autowired UserService service; @HystrixCommand(fallbackMethod = "defaultUsersObservable") public Observable<List<User>> getUsersObservable() { return new ObservableResult<List<User>>() { @Override public List<User> invoke() { return service.getUsers(); } }; } public Observable<User> defaultUsersObservable() { return null; } } @FeignClient("USER-SERVICE") public interface UserService { @RequestMapping(value = "/users", method = RequestMethod.GET) List<User> getUsers(); @RequestMapping(value = "/user/{id}", method = RequestMethod.GET) User getUser(@PathVariable("id") Integer id); }
  • 34.
    API Gateway @RestController public classAPIGateway { @Autowired GroupServiceProxy groupService; @Autowired UserServiceProxy userService; @RequestMapping(method = RequestMethod.GET, value = "/userGroups") public UserGroup getUserGroups() { Observable<List<Group>> groups = groupService.getGroupsObservable(); Observable<List<User>> users = userService.getUsersObservable(); Observable<UserGroup> userGroupObservable = Observable.zip(groups, users, (g, u) -> new UserGroup(u, g)); return userGroupObservable.toList().toBlocking().single().get(0); } }
  • 35.
  • 36.
    Conclusões • Arquitetura commicroservices é complexa • Manifesto reativo define princípios para implementar uma arquitetura de microservices reativa • Async e Non-Blocking IO são praticas importantes para atingir princípios reativos • RxJava oferece uma implementação para streams reativos • Não se esqueça de implementar API Gateway’s • Enjoy it ;)
  • 37.
  • 38.
    References • http://projects.spring.io/spring-cloud/ • https://netflix.github.io/ •http://www.reactive-streams.org/ • http://www.reactivemanifesto.org/ • https://github.com/reactivemanifesto/website-manifesto/tree/master/public/pdf • https://github.com/ReactiveX/RxJava • https://projectreactor.io/ • http://reactivex.io/ • https://cloud.spring.io/spring-cloud-stream/
  • 39.