Microservices Are your Frameworks ready? Martin Eigenbrodt | - - PowerPoint PPT Presentation

microservices
SMART_READER_LITE
LIVE PREVIEW

Microservices Are your Frameworks ready? Martin Eigenbrodt | - - PowerPoint PPT Presentation

Microservices Are your Frameworks ready? Martin Eigenbrodt | martin.eigenbrodt@innoq.com Alexander Heusingfeld | alexander.heusingfeld@innoq.com Microservices? Levels of Architecture Domain architecture Domain architecture Macro (technical)


slide-1
SLIDE 1

Microservices

Are your Frameworks ready?

Martin Eigenbrodt | martin.eigenbrodt@innoq.com Alexander Heusingfeld | alexander.heusingfeld@innoq.com

slide-2
SLIDE 2

Microservices?

slide-3
SLIDE 3

Levels of Architecture

slide-4
SLIDE 4
slide-5
SLIDE 5

Domain architecture

slide-6
SLIDE 6

Macro (technical) architecture Domain architecture

slide-7
SLIDE 7

JRuby C# Scala Groovy
 Java Clojure

slide-8
SLIDE 8

RDBMS NoSQL K/V RDBMS RDBMS/DWH NoSQL
 DocDB

slide-9
SLIDE 9

RDBMS NoSQL K/V RDBMS RDBMS/DWH NoSQL
 DocDB Micro architecture

slide-10
SLIDE 10

Challenges

slide-11
SLIDE 11
slide-12
SLIDE 12

Challenges

slide-13
SLIDE 13

Challenges

> many services to take care of

slide-14
SLIDE 14

Challenges

> many services to take care of > distributed system

slide-15
SLIDE 15

Challenges

> distributed confjguration > service registration & discovery > resilience > fast, automated deployment > metrics

slide-16
SLIDE 16

Macro- vs. Micro Architecture

slide-17
SLIDE 17

Frameworks

slide-18
SLIDE 18

Dropwizard

slide-19
SLIDE 19

Dropwizard

> Glue Code for well known libraries > Java

slide-20
SLIDE 20

Dropwizard libraries

slide-21
SLIDE 21

Dropwizard libraries

> Jetty

slide-22
SLIDE 22

Dropwizard libraries

> Jetty > Jersey

slide-23
SLIDE 23

Dropwizard libraries

> Jetty > Jersey > Metrics

slide-24
SLIDE 24

Dropwizard libraries

> Jetty > Jersey > Metrics > Jackson > Guava > Logback > Hibernate Validator > Apache Http Client > JDBI > Liquibase > Freemarker & Mustache > Joda

slide-25
SLIDE 25

Spring Boot

and Spring Cloud

slide-26
SLIDE 26

Spring Boot

slide-27
SLIDE 27

Spring Boot

> convention over confjguration approach

slide-28
SLIDE 28

Spring Boot

> convention over confjguration approach > Java, Groovy or Scala

slide-29
SLIDE 29

Spring Boot

> convention over confjguration approach > Java, Groovy or Scala > self-contained jar or war

slide-30
SLIDE 30

Spring Boot

> convention over confjguration approach > Java, Groovy or Scala > self-contained jar or war > tackles dependency-hell via pre-packaging

slide-31
SLIDE 31

Spring Cloud

slide-32
SLIDE 32

Spring Cloud

> umbrella project for cloud connectors

slide-33
SLIDE 33

Spring Cloud

> umbrella project for cloud connectors > On top of Spring Boot

slide-34
SLIDE 34

Spring Cloud

> umbrella project for cloud connectors > On top of Spring Boot > confjg server for distributed confjguration

slide-35
SLIDE 35

Spring Cloud

> umbrella project for cloud connectors > On top of Spring Boot > confjg server for distributed confjguration > annotations for service-discovery & resilience

slide-36
SLIDE 36

Play 2

slide-37
SLIDE 37

Play 2

> Java or Scala > based on Akka > strong async support

slide-38
SLIDE 38

Confjguration

slide-39
SLIDE 39

Play - Typesafe Confjg

slide-40
SLIDE 40

Play - Typesafe Confjg

> Confjg Library used by akka, play and other

slide-41
SLIDE 41

Play - Typesafe Confjg

> Confjg Library used by akka, play and other > HOCON - JSON Data Model + syntactic sugar

slide-42
SLIDE 42

Play - Typesafe Confjg

> Confjg Library used by akka, play and other > HOCON - JSON Data Model + syntactic sugar >

  • verride via system property
slide-43
SLIDE 43

Play - Typesafe Confjg

> Confjg Library used by akka, play and other > HOCON - JSON Data Model + syntactic sugar >

  • verride via system property

> rich merge and include possibilities

slide-44
SLIDE 44

Spring Boot

@ComponentScan
 @EnableAutoConfiguration
 public class OrderApp {
 
 public static void main(String[] args) {
 SpringApplication.run(OrderApp.class, args);
 }
 }

slide-45
SLIDE 45

Spring Boot

@ComponentScan
 @EnableAutoConfiguration
 public class OrderApp {
 
 public static void main(String[] args) {
 SpringApplication.run(OrderApp.class, args);
 }
 }

slide-46
SLIDE 46

Spring Boot

> HTTP resource “/autoconfjg” shows all properties

@ComponentScan
 @EnableAutoConfiguration
 public class OrderApp {
 
 public static void main(String[] args) {
 SpringApplication.run(OrderApp.class, args);
 }
 }

slide-47
SLIDE 47

Spring Boot

> HTTP resource “/autoconfjg” shows all properties >

  • verwrite via application.properties or CLI parameter

@ComponentScan
 @EnableAutoConfiguration
 public class OrderApp {
 
 public static void main(String[] args) {
 SpringApplication.run(OrderApp.class, args);
 }
 }

slide-48
SLIDE 48

Spring Boot

> HTTP resource “/autoconfjg” shows all properties >

  • verwrite via application.properties or CLI parameter

> confjguration in git? -> Check spring-cloud confjgserver

@ComponentScan
 @EnableAutoConfiguration
 public class OrderApp {
 
 public static void main(String[] args) {
 SpringApplication.run(OrderApp.class, args);
 }
 }

slide-49
SLIDE 49

Http Client

slide-50
SLIDE 50

Dropwizard

public Product resolveProduct(String url) { Product product = client.resource(url) .accept(MediaType.APPLICATION_JSON).get(Product.class); return product; }

slide-51
SLIDE 51

Spring Boot

public Product resolveProduct(String url) { return restTemplate.getForEntity(url, Product.class);
 }

slide-52
SLIDE 52

WS.url(apiUrl).get.map { response => response.json.as[List[Bestseller]] }.recover { case e => List() }

Play

slide-53
SLIDE 53

Service Discovery

slide-54
SLIDE 54

Service

Service Discovery

Client

Service Registry

  • 2. discover service instances
  • 3. call service instance

Service Service

  • 1. register service ("myself")

& heartbeat

slide-55
SLIDE 55

Spring Cloud

@ComponentScan
 @EnableAutoConfiguration
 @EnableDiscoveryClient
 public class OrdersApp {
 
 public static void main(String[] args) {
 SpringApplication.run(OrdersApp.class, args);
 }
 }

slide-56
SLIDE 56

Spring Cloud

@ComponentScan
 @EnableAutoConfiguration
 @EnableDiscoveryClient
 public class OrdersApp {
 
 public static void main(String[] args) {
 SpringApplication.run(OrdersApp.class, args);
 }
 }

slide-57
SLIDE 57

Spring Cloud

@ComponentScan
 @EnableAutoConfiguration
 @EnableDiscoveryClient
 public class OrdersApp {
 
 public static void main(String[] args) {
 SpringApplication.run(OrdersApp.class, args);
 }
 }

slide-58
SLIDE 58

Service Discovery with Sidecar

Sidecar Client

Service Registry

Sidecar Service

  • 2. register service ("myself")

& heartbeat

  • 4. discover service instances
  • 5. call service instance
  • 1. health

check 3.

slide-59
SLIDE 59

Resilience

slide-60
SLIDE 60

Resilience

> isolate Failure > apply graceful degradation > be responsive in case of failure

slide-61
SLIDE 61

Request

service

http:/ /en.wikipedia.org/wiki/Circuit_breaker

closed

slide-62
SLIDE 62

Request

service

http:/ /en.wikipedia.org/wiki/Circuit_breaker

closed

Request

service

  • pen
slide-63
SLIDE 63

Request

service

http:/ /en.wikipedia.org/wiki/Circuit_breaker

closed

Request

service

  • pen

Request

service

half-

  • pen
slide-64
SLIDE 64

> Provides Command-oriented Integration of Services > Introduces Circuit Breaker, Bulkheads and Isolation > Decouples from Service-dependencies > Provides metrics-facility to protect from failures

slide-65
SLIDE 65

Hystrix & Dropwizard

public class CommandInDropwizard extends TenacityCommand<Product> { @Override protected Product run() throws Exception { Product product = client.resource(url) .accept(MediaType.APPLICATION_JSON).get(Product.class); return product; } protected Product getFallback() { return FALLBACK_PRODUCT } }

slide-66
SLIDE 66

Hystrix & Dropwizard

public class CommandInDropwizard extends TenacityCommand<Product> { @Override protected Product run() throws Exception { Product product = client.resource(url) .accept(MediaType.APPLICATION_JSON).get(Product.class); return product; } protected Product getFallback() { return FALLBACK_PRODUCT } }

slide-67
SLIDE 67

Hystrix & Dropwizard

public class CommandInDropwizard extends TenacityCommand<Product> { @Override protected Product run() throws Exception { Product product = client.resource(url) .accept(MediaType.APPLICATION_JSON).get(Product.class); return product; } protected Product getFallback() { return FALLBACK_PRODUCT } }

slide-68
SLIDE 68

Hystrix & Dropwizard

public class CommandInDropwizard extends TenacityCommand<Product> { @Override protected Product run() throws Exception { Product product = client.resource(url) .accept(MediaType.APPLICATION_JSON).get(Product.class); return product; } protected Product getFallback() { return FALLBACK_PRODUCT } }

slide-69
SLIDE 69

ResolveProductCommand command = new ResolveProductCommand(client, url); Product product = command.execute();

Hystrix & Dropwizard

slide-70
SLIDE 70

Spring Cloud Hystrix

@HystrixCommand(fallbackMethod = “fallbackProduct") private Pair<String, ResponseEntity<Product>> resolveProduct(String productUri) {
 final RestTemplate restTemplate = new RestTemplate();
 return new Pair(productUri, restTemplate.getForEntity(productUri, Product.class));
 } private Pair<String, ResponseEntity<Product>> fallbackProduct(String productUri) {
 final Product product = new Product(productUri, null, BigDecimal.ZERO);
 final ResponseEntity<Product> response = new ResponseEntity<Product>(product, PARTIAL_CONTENT);
 return new Pair(productUri, response);
 }

slide-71
SLIDE 71

Spring Cloud Hystrix

@HystrixCommand(fallbackMethod = “fallbackProduct") private Pair<String, ResponseEntity<Product>> resolveProduct(String productUri) {
 final RestTemplate restTemplate = new RestTemplate();
 return new Pair(productUri, restTemplate.getForEntity(productUri, Product.class));
 } private Pair<String, ResponseEntity<Product>> fallbackProduct(String productUri) {
 final Product product = new Product(productUri, null, BigDecimal.ZERO);
 final ResponseEntity<Product> response = new ResponseEntity<Product>(product, PARTIAL_CONTENT);
 return new Pair(productUri, response);
 }

a u t

  • w

r a p p e d w i t h c

  • m

m a n d !

slide-72
SLIDE 72

Spring Cloud Hystrix

@HystrixCommand(fallbackMethod = “fallbackProduct") private Pair<String, ResponseEntity<Product>> resolveProduct(String productUri) {
 final RestTemplate restTemplate = new RestTemplate();
 return new Pair(productUri, restTemplate.getForEntity(productUri, Product.class));
 } private Pair<String, ResponseEntity<Product>> fallbackProduct(String productUri) {
 final Product product = new Product(productUri, null, BigDecimal.ZERO);
 final ResponseEntity<Product> response = new ResponseEntity<Product>(product, PARTIAL_CONTENT);
 return new Pair(productUri, response);
 }

slide-73
SLIDE 73

Spring Cloud Hystrix

@HystrixCommand(fallbackMethod = “fallbackProduct") private Pair<String, ResponseEntity<Product>> resolveProduct(String productUri) {
 final RestTemplate restTemplate = new RestTemplate();
 return new Pair(productUri, restTemplate.getForEntity(productUri, Product.class));
 } private Pair<String, ResponseEntity<Product>> fallbackProduct(String productUri) {
 final Product product = new Product(productUri, null, BigDecimal.ZERO);
 final ResponseEntity<Product> response = new ResponseEntity<Product>(product, PARTIAL_CONTENT);
 return new Pair(productUri, response);
 }

slide-74
SLIDE 74

Spring Cloud Hystrix

@HystrixCommand(fallbackMethod = “fallbackProduct") private Pair<String, ResponseEntity<Product>> resolveProduct(String productUri) {
 final RestTemplate restTemplate = new RestTemplate();
 return new Pair(productUri, restTemplate.getForEntity(productUri, Product.class));
 } private Pair<String, ResponseEntity<Product>> fallbackProduct(String productUri) {
 final Product product = new Product(productUri, null, BigDecimal.ZERO);
 final ResponseEntity<Product> response = new ResponseEntity<Product>(product, PARTIAL_CONTENT);
 return new Pair(productUri, response);
 }

method reference!

slide-75
SLIDE 75

Play - Circuit Breaker

val apiUrl = "..." val breaker = CircuitBreaker(Akka.system().scheduler, maxFailures = 5, callTimeout = 2.seconds, resetTimeout = 1.minute) def getBestseller : Future[List[Bestseller]] = { breaker.withCircuitBreaker( WS.url(apiUrl).get.map { response => response.json.as[List[Bestseller]] }).recover { case e => List() } }

slide-76
SLIDE 76

Play - Circuit Breaker

val apiUrl = "..." val breaker = CircuitBreaker(Akka.system().scheduler, maxFailures = 5, callTimeout = 2.seconds, resetTimeout = 1.minute) def getBestseller : Future[List[Bestseller]] = { breaker.withCircuitBreaker( WS.url(apiUrl).get.map { response => response.json.as[List[Bestseller]] }).recover { case e => List() } }

slide-77
SLIDE 77

Play - Circuit Breaker

val apiUrl = "..." val breaker = CircuitBreaker(Akka.system().scheduler, maxFailures = 5, callTimeout = 2.seconds, resetTimeout = 1.minute) def getBestseller : Future[List[Bestseller]] = { breaker.withCircuitBreaker( WS.url(apiUrl).get.map { response => response.json.as[List[Bestseller]] }).recover { case e => List() } }

slide-78
SLIDE 78

Play - Circuit Breaker

val apiUrl = "..." val breaker = CircuitBreaker(Akka.system().scheduler, maxFailures = 5, callTimeout = 2.seconds, resetTimeout = 1.minute) def getBestseller : Future[List[Bestseller]] = { breaker.withCircuitBreaker( WS.url(apiUrl).get.map { response => response.json.as[List[Bestseller]] }).recover { case e => List() } }

slide-79
SLIDE 79

Play - Circuit Breaker

val apiUrl = "..." val breaker = CircuitBreaker(Akka.system().scheduler, maxFailures = 5, callTimeout = 2.seconds, resetTimeout = 1.minute) def getBestseller : Future[List[Bestseller]] = { breaker.withCircuitBreaker( WS.url(apiUrl).get.map { response => response.json.as[List[Bestseller]] }).recover { case e => List() } }

slide-80
SLIDE 80

Deployment

slide-81
SLIDE 81

Spring Boot - Packaging

./gradlew build ./gradlew distZip

slide-82
SLIDE 82

Spring Boot - Packaging

./gradlew build ./gradlew distZip

e x e c u t a b l e J A R

slide-83
SLIDE 83

Spring Boot - Packaging

./gradlew build ./gradlew distZip

ZIP + shell-script e x e c u t a b l e J A R

slide-84
SLIDE 84

Play - Packaging

sbt dist sbt debian:packageBin sbt rpm:packageBin

slide-85
SLIDE 85

Metrics

slide-86
SLIDE 86

Dropwizard

> “Metrics” Integrated with Dropwizard > @Timed on Resources > HTTP Client is already instrumented > JVM Data

slide-87
SLIDE 87

"org.apache.http.client.HttpClient.cart.get-requests": { "count": 11, "max": 0.062107, "mean": 0.013355909090909092, "min": 0.005750000000000001, "p50": 0.009454, "p75": 0.010427, "p95": 0.062107, "p98": 0.062107, "p99": 0.062107, "p999": 0.062107, "stddev": 0.016285873488729705, "m15_rate": 0, "m1_rate": 0, "m5_rate": 0, "mean_rate": 2.9714422786532126, "duration_units": "seconds", "rate_units": "calls/second" } "cart.resources.ShoppingCartResource.shoppingCart": { "count": 22, "max": 0.136162, "mean": 0.01208109090909091, "min": 0.00093, "p50": 0.008174500000000001, "p75": 0.011782250000000001, "p95": 0.11783499999999976, "p98": 0.136162, "p99": 0.136162, "p999": 0.136162, "stddev": 0.02813530239821426, "m15_rate": 1.8524577712890011, "m1_rate": 0.18057796798879996, "m5_rate": 1.315746847992022, "mean_rate": 0.133050618509084, "duration_units": "seconds", "rate_units": "calls/second" }

slide-88
SLIDE 88

Dropwizard Metrics

> Exposed over HTTP (as Json) > Exposed as jmx > Others available: stdout, csv, slf4j, ganglia, graphite

slide-89
SLIDE 89

Spring Boot Metrics

> Prepackaged Spring Boot starter module > enables HTTP resources for metrics > confjgurable via application.properties

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#production-ready

slide-90
SLIDE 90

{ "counter.checkouts.withproducts.3": 4, ... }

counterService.increment("checkouts.withproducts." + productUris.size());


GET /metrics HTTP/1.1

Using a counter metric in your Java code… …will display it in the /metrics JSON

Spring Boot Metrics

slide-91
SLIDE 91

Summary

slide-92
SLIDE 92

Modularize into independent, self-contained systems

Summary

slide-93
SLIDE 93

Modularize into independent, self-contained systems Separate micro and macro architectures

Summary

slide-94
SLIDE 94

Modularize into independent, self-contained systems Separate micro and macro architectures Strike a balance between control and decentralization

Summary

slide-95
SLIDE 95

Modularize into independent, self-contained systems Separate micro and macro architectures Strike a balance between control and decentralization MicroServices aren’t micro!

Summary

slide-96
SLIDE 96

Modularize into independent, self-contained systems Separate micro and macro architectures Strike a balance between control and decentralization MicroServices aren’t micro! frameworks can’t solve all your problems

Summary

slide-97
SLIDE 97

Martin Eigenbrodt | @eigenbrodtm martin.eigenbrodt@innoq.com Alexander Heusingfeld | @goldstifu alexander.heusingfeld@innoq.com

innoQ Deutschland GmbH

  • Krischerstr. 100

40789 Monheim am Rhein Germany Phone: +49 2173 3366-0 innoQ Schweiz GmbH

  • Gewerbestr. 11

CH-6330 Cham Switzerland Phone: +41 41 743 0116

www.innoq.com

Ohlauer Straße 43 10999 Berlin Germany Phone: +49 2173 3366-0 Robert-Bosch-Straße 7 64293 Darmstadt Germany Phone: +49 2173 3366-0 Radlkoferstraße 2 D-81373 München Germany Telefon +49 (0) 89 741185-270

Thank you!

Questions? Comments?

https:/ /www.innoq.com/en/talks/2015/02/microservices-jvm-applications-talk