Arquitecturas de Microservicios 
Ernesto Hernández Rodríguez 
Arquitecto Java en Medianet Software 
@ehdez73
¿MicroServicios?
"Microservices is a software architecture design 
pattern, in which complex applications are composed of 
small, independent processes communicating with each 
other using language-agnostic APIs. These services are 
small, highly decoupled and focus on doing a small 
task."
Evolución arquitectura
Beneficios 
∘ Servicios pequeños 
∘ Principio de responsabilidad única 
∘ Fácilmente abarcable 
∘ Políglota 
∘ PoC 
∘ Despliegues 
∘ Escalado eficiente
BUT… 
WAIT A 
MOMENT!
Nuevos desafíos 
∘ ¿Cómo localizo los servicios? 
∘ ¿Qué pasa si alguno falla? 
∘ ¿Cómo los configuro? 
∘ ¿Y las trazas? 
∘ ¿Y los diferentes entornos?
Necesitamos
http://screenagers.me/wp-content/uploads/2012/01/US-bandwidth.png
EUREKA ARCHAIUS HYSTRIX TURBINE 
ZUUL BLITZ4J RIBBON 
http://netflix.github.io
EUREKA 
Service locator 
∘ API REST 
∘ Eureka Server - Peer awarness 
∘ Eureka Client - Service Discovery 
https://github.com/Netflix/eureka
ARCHAIUS 
Configuration management 
∘ Apache Commons Configuration 
∘ Configuration Source 
∘ High throughput 
∘ Thread safe 
∘ Composite configuration 
∘ JMX 
https://github.com/Netflix/Archaius
RIBBON 
Interprocess communication 
∘ Balanceador de carga 
∘ Cliente Eureka 
∘ Hystrix 
https://github.com/Netflix/Ribbon
HYSTRIX 
Circuit Breaker 
∘ Aislar puntos de acceso 
∘ Tolerancia a fallos 
∘ Fallos en cascada 
∘ Dashboard 
https://github.com/Netflix/Hystrix
http://cloud.spring.io/spring-cloud-netflix/images/HystrixGraph.png 
Circuit Breaker
Circuit Breaker 
http://cloud.spring.io/spring-cloud-netflix/images/HystrixFallback.png
Hystrix Dashboard 
http://techblog.netflix.com/2012/12/hystrix-dashboard-and-turbine.html
TURBINE 
Stream aggregator 
Turbine is an application that aggregates all of the 
relevant /hystrix.stream endpoints into a 
combined /turbine.stream for use in the Hystrix 
Dashboard 
https://github.com/Netflix/Turbine
http://youtu.be/zWM7oAbVL4g
ZUUL 
Edge Service 
∘ Router and filter 
∘ Reverse proxy 
∘ Ribbon & Eureka 
∘ Hystrix 
https://github.com/Netflix/Zuul
BLITZ4J 
Fast asynchronous logging 
∘ Basado en log4j 
∘ Menos recursos 
∘ Más rápido 
∘ Archaius 
https://github.com/Netflix/Blitz4j
CorrelationID 
http://ragavj.blogspot.com.es/2013/08/how-to-lookup-error-in-sharepoint-2010.html
ELK STACK 
Files Logstash ElasticSearch Kibana
Spring Cloud 
https://github.com/spring-cloud
Eureka Server 
@Configuration 
@EnableAutoConfiguration 
@EnableEurekaServer 
public class Application { 
public static void main(String[] args) { 
new SpringApplicationBuilder(Application.class) 
.web(true) 
.run(args); 
} 
}
Eureka Server 
@Configuration 
@EnableAutoConfiguration 
@EnableEurekaServer 
public class Application { 
application.yml 
server: 
port: 8761 
eureka: 
instance: 
public static void main(String[] args) { 
hostname: localhost 
client: 
registerWithEureka: false 
fetchRegistry: false 
serviceUrl: 
new SpringApplicationBuilder(Application.class) 
.web(true) 
.run(args); 
} 
} 
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
Eureka Client 
@Configuration 
@ComponentScan 
@EnableAutoConfiguration 
@EnableEurekaClient 
@RestController 
public class Application { 
@RequestMapping("/") 
public String home() { return "Hello world"; } 
public static void main(String[] args) { 
new SpringApplicationBuilder(Application.class) 
.web(true).run(args); 
} 
}
Eureka Client 
@Configuration 
@ComponentScan 
@EnableAutoConfiguration 
@EnableEurekaClient 
@RestController 
public class Application { 
@RequestMapping("/") 
public String home() { return "Hello world"; } 
public static void main(String[] args) { 
new SpringApplicationBuilder(Application.class) 
.web(true).run(args); 
} 
} 
application.yml 
eureka: 
client: 
serviceUrl: 
defaultZone: http://localhost:8761/eureka/
Ribbon 
Transparente vía RestTemplate 
RibbonAutoConfiguration.java 
@Bean 
@ConditionalOnMissingBean(RestTemplate.class) 
public RestTemplate restTemplate(RibbonInterceptor ribbonInterceptor) { 
RestTemplate restTemplate = new RestTemplate(); 
List<ClientHttpRequestInterceptor> list = new ArrayList<>(); 
list.add(ribbonInterceptor); 
restTemplate.setInterceptors(list); 
return restTemplate; 
} 
} 
http://github.com/.../RibbonAutoConfiguration.java
Hystrix wrapper 
@Component 
public class StoreIntegration { 
@HystrixCommand(fallbackMethod = "defaultStores") 
public Object getStores(Map<String, Object> parameters) { 
//do stuff that might fail 
} 
public Object defaultStores(Map<String, Object> parameters) { 
return /* something useful */; 
} 
}
Hystrix Config 
@Configuration 
@EnableAutoConfiguration 
@EnableHystrix 
@EnableHystrixDashboard 
@ComponentScan 
public class Application { 
public static void main(String[] args) { 
new SpringApplicationBuilder(Application.class) 
.web(true) 
.run(args); 
} 
}
Zuul Config 
@EnableZuulProxy 
zuul.proxy.mapping: /api 
zuul.proxy.route.users: /users 
/api/users → /users 
Hystrix → Ribbon → Eureka
Spring Cloud Config 
∘ Properties en repositorio Git 
∘ API 
∘ Profiles 
∘ Encriptado 
∘ @RefreshScope 
∘ PropertySource & Env 
https://github.com/spring-cloud/spring-cloud-config
Spring Cloud Config - Server 
@Configuration 
@EnableAutoConfiguration 
@EnableEurekaClient 
@EnableConfigServer 
public class ConfigServerApplication { 
public static void main(String[] args) { 
SpringApplication.run(ConfigServerApplication.class, args); 
} 
}
Spring Cloud Config - Server 
@Configuration 
@EnableAutoConfiguration 
@EnableEurekaClient 
@EnableConfigServer 
public class ConfigServerApplication { 
public static void main(String[] args) { 
SpringApplication.run(ConfigServerApplication.class, args); 
} 
} 
bootstrap.yml 
spring: 
application: 
name: configserver 
encrypt: 
keyStore: 
location: classpath:keystore.jks 
password: ${KEYSTORE_PASSWORD} # foobar 
alias: test 
application.yml 
spring: 
cloud: 
config: 
server: 
basedir: target/config 
uri: https://github.com/ehdez73/cloud-config 
security: 
user: 
password: '{cipher}AQBunH7b87s86E='
Spring Cloud Config - Client 
@Configuration 
@EnableAutoConfiguration 
@RestController 
public class Application { 
@RequestMapping("/") 
public String home() { return "Hello world"; } 
public static void main(String[] args) { 
new SpringApplicationBuilder(Application.class) 
.web(true) 
.run(args); 
} 
}
Spring Cloud Config - Client 
@Configuration 
@EnableAutoConfiguration 
@RestController 
public class Application { 
@RequestMapping("/") 
public String home() { return "Hello world"; } 
public static void main(String[] args) { 
new SpringApplicationBuilder(Application.class) 
.web(true) 
.run(args); 
} 
} 
bootstrap.yml 
spring: 
cloud: 
config: 
uri: http://localhost:${config.port:8888}
DevOps
https://www.docker.com/whatisdocker/
Dockerfile 
FROM dockerfile/java 
MANTAINER Ernesto Hdez, ehdez73@gmail.com 
ADD target/myapp1.jar /tmp/myapp1.jar 
EXPOSE 8080 
ENTRYPOINT ["java", "-jar", "/tmp/myapp1.jar"] 
$ mvn package 
$ docker build -t ehdez73/myapp1 . 
$ docker run -d -p 8080:8080 --name="m1" ehdez73/myapp1 
$ docker ps 
$ docker stop m1 
$ docker start m1 
https://registry.hub.docker.com/u/dockerfile/java/dockerfile/
http://www.fig.sh/
Fig.sh
fig.yml 
myapp1: 
build: . 
ports: 
- "8880:8880" 
myapp2: 
image: ehdez73/myapp2 
ports: 
- "8881:8881" 
links: 
- db 
db: 
image: postgres 
http://www.fig.sh/yml.html 
$ fig up
DEMO
MINIONIZE THE WORLD !!! 
Minions ipsum tulaliloo 
potatoooo pepete jeje baboiii 
poulet tikka masala chasy la 
bodaaa butt. La bodaaa 
aaaaaah tulaliloo wiiiii la 
bodaaa la bodaaa belloo! 
Tulaliloo para tú belloo! Me 
want bananaaa! Para tú 
aaaaaah bananaaaa para tú jiji 
po kass. Potatoooo tulaliloo 
potatoooo chasy me want 
bananaaa! Ti aamoo! para tú. 
https://github.com/ehdez73/minionize-the-world 
The minions
Muchas gracias 
@ehdez73

Arquitecturas de microservicios - Medianet Software

  • 1.
    Arquitecturas de Microservicios Ernesto Hernández Rodríguez Arquitecto Java en Medianet Software @ehdez73
  • 4.
  • 5.
    "Microservices is asoftware architecture design pattern, in which complex applications are composed of small, independent processes communicating with each other using language-agnostic APIs. These services are small, highly decoupled and focus on doing a small task."
  • 6.
  • 7.
    Beneficios ∘ Serviciospequeños ∘ Principio de responsabilidad única ∘ Fácilmente abarcable ∘ Políglota ∘ PoC ∘ Despliegues ∘ Escalado eficiente
  • 9.
    BUT… WAIT A MOMENT!
  • 10.
    Nuevos desafíos ∘¿Cómo localizo los servicios? ∘ ¿Qué pasa si alguno falla? ∘ ¿Cómo los configuro? ∘ ¿Y las trazas? ∘ ¿Y los diferentes entornos?
  • 11.
  • 13.
  • 14.
    EUREKA ARCHAIUS HYSTRIXTURBINE ZUUL BLITZ4J RIBBON http://netflix.github.io
  • 15.
    EUREKA Service locator ∘ API REST ∘ Eureka Server - Peer awarness ∘ Eureka Client - Service Discovery https://github.com/Netflix/eureka
  • 16.
    ARCHAIUS Configuration management ∘ Apache Commons Configuration ∘ Configuration Source ∘ High throughput ∘ Thread safe ∘ Composite configuration ∘ JMX https://github.com/Netflix/Archaius
  • 17.
    RIBBON Interprocess communication ∘ Balanceador de carga ∘ Cliente Eureka ∘ Hystrix https://github.com/Netflix/Ribbon
  • 18.
    HYSTRIX Circuit Breaker ∘ Aislar puntos de acceso ∘ Tolerancia a fallos ∘ Fallos en cascada ∘ Dashboard https://github.com/Netflix/Hystrix
  • 19.
  • 20.
  • 21.
  • 22.
    TURBINE Stream aggregator Turbine is an application that aggregates all of the relevant /hystrix.stream endpoints into a combined /turbine.stream for use in the Hystrix Dashboard https://github.com/Netflix/Turbine
  • 23.
  • 24.
    ZUUL Edge Service ∘ Router and filter ∘ Reverse proxy ∘ Ribbon & Eureka ∘ Hystrix https://github.com/Netflix/Zuul
  • 25.
    BLITZ4J Fast asynchronouslogging ∘ Basado en log4j ∘ Menos recursos ∘ Más rápido ∘ Archaius https://github.com/Netflix/Blitz4j
  • 27.
  • 28.
    ELK STACK FilesLogstash ElasticSearch Kibana
  • 29.
  • 30.
    Eureka Server @Configuration @EnableAutoConfiguration @EnableEurekaServer public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class) .web(true) .run(args); } }
  • 31.
    Eureka Server @Configuration @EnableAutoConfiguration @EnableEurekaServer public class Application { application.yml server: port: 8761 eureka: instance: public static void main(String[] args) { hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: new SpringApplicationBuilder(Application.class) .web(true) .run(args); } } defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  • 32.
    Eureka Client @Configuration @ComponentScan @EnableAutoConfiguration @EnableEurekaClient @RestController public class Application { @RequestMapping("/") public String home() { return "Hello world"; } public static void main(String[] args) { new SpringApplicationBuilder(Application.class) .web(true).run(args); } }
  • 33.
    Eureka Client @Configuration @ComponentScan @EnableAutoConfiguration @EnableEurekaClient @RestController public class Application { @RequestMapping("/") public String home() { return "Hello world"; } public static void main(String[] args) { new SpringApplicationBuilder(Application.class) .web(true).run(args); } } application.yml eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/
  • 34.
    Ribbon Transparente víaRestTemplate RibbonAutoConfiguration.java @Bean @ConditionalOnMissingBean(RestTemplate.class) public RestTemplate restTemplate(RibbonInterceptor ribbonInterceptor) { RestTemplate restTemplate = new RestTemplate(); List<ClientHttpRequestInterceptor> list = new ArrayList<>(); list.add(ribbonInterceptor); restTemplate.setInterceptors(list); return restTemplate; } } http://github.com/.../RibbonAutoConfiguration.java
  • 35.
    Hystrix wrapper @Component public class StoreIntegration { @HystrixCommand(fallbackMethod = "defaultStores") public Object getStores(Map<String, Object> parameters) { //do stuff that might fail } public Object defaultStores(Map<String, Object> parameters) { return /* something useful */; } }
  • 36.
    Hystrix Config @Configuration @EnableAutoConfiguration @EnableHystrix @EnableHystrixDashboard @ComponentScan public class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class) .web(true) .run(args); } }
  • 37.
    Zuul Config @EnableZuulProxy zuul.proxy.mapping: /api zuul.proxy.route.users: /users /api/users → /users Hystrix → Ribbon → Eureka
  • 38.
    Spring Cloud Config ∘ Properties en repositorio Git ∘ API ∘ Profiles ∘ Encriptado ∘ @RefreshScope ∘ PropertySource & Env https://github.com/spring-cloud/spring-cloud-config
  • 39.
    Spring Cloud Config- Server @Configuration @EnableAutoConfiguration @EnableEurekaClient @EnableConfigServer public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
  • 40.
    Spring Cloud Config- Server @Configuration @EnableAutoConfiguration @EnableEurekaClient @EnableConfigServer public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } } bootstrap.yml spring: application: name: configserver encrypt: keyStore: location: classpath:keystore.jks password: ${KEYSTORE_PASSWORD} # foobar alias: test application.yml spring: cloud: config: server: basedir: target/config uri: https://github.com/ehdez73/cloud-config security: user: password: '{cipher}AQBunH7b87s86E='
  • 41.
    Spring Cloud Config- Client @Configuration @EnableAutoConfiguration @RestController public class Application { @RequestMapping("/") public String home() { return "Hello world"; } public static void main(String[] args) { new SpringApplicationBuilder(Application.class) .web(true) .run(args); } }
  • 42.
    Spring Cloud Config- Client @Configuration @EnableAutoConfiguration @RestController public class Application { @RequestMapping("/") public String home() { return "Hello world"; } public static void main(String[] args) { new SpringApplicationBuilder(Application.class) .web(true) .run(args); } } bootstrap.yml spring: cloud: config: uri: http://localhost:${config.port:8888}
  • 43.
  • 46.
  • 48.
    Dockerfile FROM dockerfile/java MANTAINER Ernesto Hdez, ehdez73@gmail.com ADD target/myapp1.jar /tmp/myapp1.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/tmp/myapp1.jar"] $ mvn package $ docker build -t ehdez73/myapp1 . $ docker run -d -p 8080:8080 --name="m1" ehdez73/myapp1 $ docker ps $ docker stop m1 $ docker start m1 https://registry.hub.docker.com/u/dockerfile/java/dockerfile/
  • 49.
  • 50.
  • 51.
    fig.yml myapp1: build:. ports: - "8880:8880" myapp2: image: ehdez73/myapp2 ports: - "8881:8881" links: - db db: image: postgres http://www.fig.sh/yml.html $ fig up
  • 52.
  • 53.
    MINIONIZE THE WORLD!!! Minions ipsum tulaliloo potatoooo pepete jeje baboiii poulet tikka masala chasy la bodaaa butt. La bodaaa aaaaaah tulaliloo wiiiii la bodaaa la bodaaa belloo! Tulaliloo para tú belloo! Me want bananaaa! Para tú aaaaaah bananaaaa para tú jiji po kass. Potatoooo tulaliloo potatoooo chasy me want bananaaa! Ti aamoo! para tú. https://github.com/ehdez73/minionize-the-world The minions
  • 54.