112
MILAN 18/19.11.2015 Microservices architecture labs GIULIO SANTOLI - @gjuljo

Microservices Architecture: Labs

  • Upload
    gjuljo

  • View
    308

  • Download
    1

Embed Size (px)

Citation preview

MILAN 18/19.11.2015

Microservices architecture labs

GIULIO SANTOLI - @gjuljo

MILAN 18/19.11.2015 - GIULIO SANTOLI

RECOMMENDATIONS

SERVICE (9002)

MEMBERSHIP

SERVICE (9001)

Scenario 1: Naive Implementation

MILAN 18/19.11.2015 - GIULIO SANTOLI

1. Go to the Spring Initializer site (https://start.spring.io)

2. Select Gradle Project with Spring Boot 1.2.7

3. Specify in Project Metadata:

Group: com.microservices

Artifact: membership

4. Add the following starters: Web, Eureka Discovery, Hystrix, Actuator

5. Generate the Project (membership.zip) and extract it.

6. Open the file build.gradle with your Java editor (IntelliJ)

Membership Service

MILAN 18/19.11.2015 - GIULIO SANTOLI

package com.microservices;

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication@RestControllerpublic class MembershipApplication {

public static void main(String[] args) {SpringApplication.run(MembershipApplication.class, args);

}

@RequestMapping("/")public String home() {

return "Hello world";}

}

MembershipApplication.java

Add this

method

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> gradlew bootRun

. ____ _ __ _ _

/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

\\/ ___)| |_)| | | | | || (_| | ) ) ) )

' |____| .__|_| |_|_| |_\__, | / / / /

=========|_|==============|___/=/_/_/_/

:: Spring Boot :: (v1.2.7.RELEASE)

2015-11-12 13:41:17.084 INFO 5452 --- [ main] com.microservices.MembershipApplication : Starting MembershipApplication on win81

with PID 5452 (C:\Bluemix\workshop\membership\build\classes\main started by Giulio in C:\Bluemix\workshop\membership)

2015-11-12 13:41:17.212 INFO 5452 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.cont

ext.embedded.AnnotationConfigEmbeddedWebApplicationContext@12f41634: startup date [Thu Nov 12 13:41:17 CET 2015]; root of context hierarchy

2015-11-12 13:41:18.661 INFO 5452 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'bea

nNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireC

andidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfig

uration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/spri

ngframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=;

abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframewo

rk.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=nul

l; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAu

toConfigurationAdapter.class]]

2015-11-12 13:41:20.332 INFO 5452 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (h

ttp)

2015-11-12 13:41:20.896 INFO 5452 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat

2015-11-12 13:41:20.907 INFO 5452 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8

.0.28

2015-11-12 13:41:21.433 INFO 5452 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicat

ionContext

2015-11-12 13:41:21.435 INFO 5452 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initializati

on completed in 4229 ms

2015-11-12 13:41:23.400 INFO 5452 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to

[/]

2015-11-12 13:41:23.427 INFO 5452 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter

' to: [/*]

2015-11-12 13:41:23.428 INFO 5452 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter'

to: [/*]

2015-11-12 13:41:24.132 INFO 5452 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.sprin

gframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@12f41634: startup date [Thu Nov 12 13:41:17 CET 2015]; root o

f context hierarchy

2015-11-12 13:41:24.284 INFO 5452 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.Str

ing com.microservices.MembershipApplication.home()

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership>curl localhost:8080

Hello world

MILAN 18/19.11.2015 - GIULIO SANTOLI

buildscript {...

}

...

dependencies {compile('org.springframework.boot:spring-boot-starter-actuator')compile('org.springframework.cloud:spring-cloud-starter-eureka')compile('org.springframework.cloud:spring-cloud-starter-hystrix')compile('org.springframework.boot:spring-boot-starter-web')compile('com.google.guava:guava:12.0')testCompile('org.springframework.boot:spring-boot-starter-test')

}

...

build.gradle

Add this

line

MILAN 18/19.11.2015 - GIULIO SANTOLI

...@RestController@RequestMapping("/api/member")class MembershipController {

final private Random rand = new Random();final private Map<String, Member> memberStore = ImmutableMap.of(

"Alfa", new Member("Alfa", 10), "Beta", new Member("Beta", 30));

@RequestMapping(method = RequestMethod.POST)public Member register(@RequestBody Member member) {

memberStore.put(member.getUser(), member);return member;

}

@RequestMapping("/{user}")Member login(@PathVariable String user) {

delay();return memberStore.get(user);

}

private void delay() {try { Thread.sleep((int)((Math.abs(2 + rand.nextGaussian()*15))*100)); } catch (InterruptedException e) { throw new RuntimeException(e); }

}}

MembershipApplication.java

Add this

class in

the file

MILAN 18/19.11.2015 - GIULIO SANTOLI

...class Member {

private String user;private Integer age;public Member() {}public Member(String name, Integer age) { this.user = name; this.age = age; }public final String getUser() { return user; }public final void setUser(String name) { this.user = name; }public final Integer getAge() { return age; }public final void setAge(Integer age) { this.age = age;}

}

MembershipApplication.java

Add this

class in

the file

server:port: ${PORT:9001}

application.yml

Create this

file in

"resources"

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> gradlew bootRunC:\membership> curl localhost:9001/api/member/AlfaC:\membership> curl localhost:9001/api/member/Beta

MILAN 18/19.11.2015 - GIULIO SANTOLI

1. Go to the Spring Initializer site (https://start.spring.io)

2. Select Gradle Project with Spring Boot 1.2.7

3. Specify in Project Metadata:

Group: com.microservices

Artifact: recommendations

4. Add the following starters: Web, Hystrix, Eureka Discovery, Actuator

5. Generate the Project (recommendations.zip) and extract it.

6. Open the file build.gradle with your Java editor (IntelliJ)

Recommendations Service

MILAN 18/19.11.2015 - GIULIO SANTOLI

package com.microservices;

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.Bean;import org.springframework.web.client.RestTemplate;

@SpringBootApplicationpublic class RecommendationsApplication {

public static void main(String[] args) {SpringApplication.run(RecommendationsApplication.class, args);

}

@Beanpublic RestTemplate restTemplate() {

return new RestTemplate();}

}

RecommendationsApplication.java

Add this

method

MILAN 18/19.11.2015 - GIULIO SANTOLI

...class Member {

private String user;private Integer age;public Member() {}public Member(String name, Integer age) { this.user = name; this.age = age; }public final String getUser() { return user; }public final void setUser(String name) { this.user = name; }public final Integer getAge() { return age; }public final void setAge(Integer age) { this.age = age;}

}

class Movie {public String title;public Movie() {}public Movie(String title) { this.title = title; }public final String getTitle() { return this.title; }public void setTitle(String title) { this.title = title; }

}

class UserNotFoundException extends Exception { private static final long serialVersionUID = 7806250577893330972L;}

RecommendationsApplication.java

Add these

classes in

the file

MILAN 18/19.11.2015 - GIULIO SANTOLI

...@RestController@RequestMapping("/api/recommendations")class RecommendationController {

@AutowiredRestTemplate restTemplate;

Set<Movie> kidRecommendations = Sets.newHashSet(new Movie("Big Hero 6"), new Movie("Frozen"));Set<Movie> adultRecommendations = Sets.newHashSet(new Movie("The Martian"),

new Movie("The Hobbit"));

@RequestMapping("/{user}")public Set<Movie> findRecommendationsForUser(@PathVariable String user) throws UserNotFoundException {

Member member = restTemplate.getForObject("http://localhost:9001/api/member/{user}", Member.class, user);

if(member == null) throw new UserNotFoundException();return member.getAge() < 17 ? kidRecommendations : adultRecommendations;

}}

RecommendationsApplication.java

Add this

class in

the file

MILAN 18/19.11.2015 - GIULIO SANTOLI

server:port: ${PORT:9002}

application.yml

Create this

file in

"resources"

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\recommendations> gradlew bootRunC:\recommendations> curl http://localhost:9002/api/recommendations/AlfaC:\recommendations> curl http://localhost:9002/api/recommendations/Beta

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: localhost

Server Port: 9001

Document Path: /api/member/Alfa

Document Length: 24 bytes

Concurrency Level: 100

Time taken for tests: 14.427 seconds

Complete requests: 1000

Failed requests: 0

Total transferred: 172000 bytes

HTML transferred: 24000 bytes

Requests per second: 69.31 [#/sec] (mean)

Time per request: 1442.710 [ms] (mean)

Time per request: 14.427 [ms] (mean, across all concurrent requests)

Transfer rate: 11.64 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 0 0.9 0 25

Processing: 13 1226 884.6 1038 4835

Waiting: 11 1225 884.8 1037 4834

Total: 13 1226 884.6 1038 4835

Percentage of the requests served within a certain time (ms)

50% 1038

66% 1500

75% 1768

80% 1934

90% 2515

95% 2930

98% 3453

99% 3814

100% 4835 (longest request)

C:> ab -c 100 -n 1000 http://localhost:9001/api/member/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: localhost

Server Port: 9002

Document Path: /api/recommendations/Alfa

Document Length: 43 bytes

Concurrency Level: 100

Time taken for tests: 19.096 seconds

Complete requests: 1000

Failed requests: 0

Total transferred: 230000 bytes

HTML transferred: 43000 bytes

Requests per second: 52.37 [#/sec] (mean)

Time per request: 1909.590 [ms] (mean)

Time per request: 19.096 [ms] (mean, across all concurrent requests)

Transfer rate: 11.76 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 0 1.1 0 25

Processing: 23 1623 1012.4 1422 5302

Waiting: 23 1619 1013.9 1421 5302

Total: 23 1624 1012.4 1423 5302

Percentage of the requests served within a certain time (ms)

50% 1423

66% 1878

75% 2194

80% 2402

90% 3033

95% 3627

98% 4234

99% 4815

100% 5302 (longest request)

C:> ab -c 100 -n 1000 http://localhost:9002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

RECOMMENDATIONS

SERVICE (9002)

MEMBERSHIP

SERVICE (9001)

Scenario 2: Service Discovery

EUREKA

SERVER

(DISCOVERY)

EUREKA

SERVER

(9000)

EUREKA

CLIENT

EUREKA

CLIENT

MILAN 18/19.11.2015 - GIULIO SANTOLI

1. Go to the Spring Initializer site (https://start.spring.io)

2. Select Gradle Project with Spring Boot 1.2.7

3. Specify in Project Metadata:

Group: com.microservices

Artifact: eurekaserver

4. Add the following starters: Eureka Server

5. Generate the Project (eurekaserver.zip) and extract it.

6. Open the file build.gradle with your Java editor (IntelliJ)

Netflix Eureka Service

MILAN 18/19.11.2015 - GIULIO SANTOLI

package com.microservices;

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication@EnableEurekaServerpublic class EurekaserverApplication {

public static void main(String[] args) {SpringApplication.run(EurekaserverApplication.class, args);

}}

EurekaserverApplication.java

Add this

annotation

MILAN 18/19.11.2015 - GIULIO SANTOLI

server:port: ${PORT:9000}

eureka:instance:

hostname: localhostclient:

registerWithEureka: falsefetchRegistry: falseserviceUrl:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

application.yml

Create this

file in

"resources"

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\eurekaserver> gradlew bootRunC:\> curl -s -H "Accept: application/json" http://localhost:9000/eureka/apps

MILAN 18/19.11.2015 - GIULIO SANTOLI

package com.microservices;

import …

@SpringBootApplication@RestController@EnableEurekaClientpublic class MembershipApplication { … }

...

MembershipApplication.java

Add this

annotation

MILAN 18/19.11.2015 - GIULIO SANTOLI

server:port: ${PORT:9001}

spring:application.name: membership

security:basic:

enabled: false

eureka:leaseRenewalIntervalInSeconds: 3client:

registryFetchIntervalSeconds: 5instanceInfoReplicationIntervalSeconds: 5initialInstanceInfoReplicationIntervalSeconds: 5serviceUrl:defaultZone: http://localhost:9000/eureka/

instance:metadataMap:instanceId: ${spring.application.name}:${server.port}

application.yml

Add

these

lines

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> gradlew bootRunC:\membership> curl http://localhost:9001/api/member/AlfaC:\> curl -s -H "Accept: application/json" http://localhost:9000/eureka/apps

MILAN 18/19.11.2015 - GIULIO SANTOLI

package com.microservices;

import ...

@EnableEurekaClientpublic class RecommendationsApplication {

public static void main(String[] args) { ... }

/* @Beanpublic RestTemplate restTemplate() { return new RestTemplate();}*/

}

class RecommendationController {

...

@RequestMapping("/{user}")public Set<Movie> findRecommendationsForUser(@PathVariable String user) {

Member member = restTemplate.getForObject("http://membership/api/member/{user}", Member.class, user);

...}

}

RecommendationsApplication.java

Remove

this method

Add this

annotation

Replace the

hostname

MILAN 18/19.11.2015 - GIULIO SANTOLI

server:port: ${PORT:9002}

spring:application.name: recommendations

security:basic:

enabled: false

eureka:leaseRenewalIntervalInSeconds: 3client:

registryFetchIntervalSeconds: 5instanceInfoReplicationIntervalSeconds: 5initialInstanceInfoReplicationIntervalSeconds: 5serviceUrl:defaultZone: http://localhost:9000/eureka/

instance:metadataMap:instanceId: ${spring.application.name}:${server.port}

application.yml

Add

these

lines

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\recommendations> gradlew bootRunC:\recommendations> curl http://localhost:9002/api/recommendations/AlfaC:\> curl -s -H "Accept: application/json" http://localhost:9000/eureka/apps

MILAN 18/19.11.2015 - GIULIO SANTOLI

MEMBERSHIP

SERVICE (9001)

RECOMMENDATIONS

SERVICE (9002)

MEMBERSHIP

SERVICE (9003)

Scenario 3: Load Balancing

EUREKA

SERVER

(DISCOVERY)

EUREKA

SERVER

(9000)

EUREKA

CLIENT

EUREKA

CLIENT

RIBBON

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> set PORT=9003 && gradlew bootRunC:\recommendations> curl http://localhost:9002/api/recommendations/AlfaC:\> curl -s -H "Accept: application/json" http://localhost:9000/eureka/apps

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: localhost

Server Port: 9002

Document Path: /api/recommendations/Alfa

Document Length: 43 bytes

Concurrency Level: 100

Time taken for tests: 19.096 seconds

Complete requests: 1000

Failed requests: 0

Total transferred: 230000 bytes

HTML transferred: 43000 bytes

Requests per second: 52.37 [#/sec] (mean)

Time per request: 1909.590 [ms] (mean)

Time per request: 19.096 [ms] (mean, across all concurrent requests)

Transfer rate: 11.76 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 0 1.1 0 25

Processing: 23 1623 1012.4 1422 5302

Waiting: 23 1619 1013.9 1421 5302

Total: 23 1624 1012.4 1423 5302

Percentage of the requests served within a certain time (ms)

50% 1423

66% 1878

75% 2194

80% 2402

90% 3033

95% 3627

98% 4234

99% 4815

100% 5302 (longest request)

C:> ab -c 100 -n 1000 http://localhost:9002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: localhost

Server Port: 9002

Document Path: /api/recommendations/Alfa

Document Length: 43 bytes

Concurrency Level: 100

Time taken for tests: 16.302 seconds

Complete requests: 1000

Failed requests: 0

Total transferred: 236000 bytes

HTML transferred: 43000 bytes

Requests per second: 61.34 [#/sec] (mean)

Time per request: 1630.229 [ms] (mean)

Time per request: 16.302 [ms] (mean, across all concurrent requests)

Transfer rate: 14.14 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 0 0.5 0 3

Processing: 28 1380 909.4 1227 4661

Waiting: 26 1379 909.7 1225 4661

Total: 29 1381 909.4 1227 4661

Percentage of the requests served within a certain time (ms)

50% 1227

66% 1617

75% 1917

80% 2138

90% 2740

95% 3078

98% 3700

99% 3967

100% 4661 (longest request)

C:> ab -c 100 -n 1000 http://localhost:9002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

Scenario 4: Circuit Breaker

MEMBERSHIP

SERVICE (9001)

RECOMMENDATIONS

SERVICE (9002)EUREKA

SERVER

(DISCOVERY)

EUREKA

SERVER

(9000)

EUREKA

CLIENT

EUREKA

CLIENT

RIBBON +

HYSTRIX

MILAN 18/19.11.2015 - GIULIO SANTOLI

...class RecommendationController {

...Set<Movie> familyRecommendations = Sets.newHashSet(new Movie("Iron Man"),

new Movie("Spiderman"));

@RequestMapping("/{user}")@HystrixCommand(fallbackMethod = "recommendationsFallback“,

ignoreExceptions = UserNotFoundException.class,commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",

value = "5000")})public Set<Movie> findRecommendationsForUser(@PathVariable String user)

throws UserNotFoundException {}

public Set<Movie> recommendationsFallback(String user) {return familyRecommendations;

}}...

RecommendationsApplication.java

Add this

Set

Add this

annotation

Add this

method

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\recommendations> gradlew bootRunC:\recommendations> curl http://localhost:9002/api/recommendations/Alfa[{"title":"Frozen"},{"title":"Big Hero 6"}]

(STOP MEMBERSHIP SERVICE)

C:\recommendations> curl http://localhost:9002/api/recommendations/Alfa[{"title":"Spiderman"},{"title":"Iron Man"}]

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: localhost

Server Port: 9002

Document Path: /api/recommendations/Alfa

Document Length: 43 bytes

Concurrency Level: 100

Time taken for tests: 19.096 seconds

Complete requests: 1000

Failed requests: 0

Total transferred: 230000 bytes

HTML transferred: 43000 bytes

Requests per second: 52.37 [#/sec] (mean)

Time per request: 1909.590 [ms] (mean)

Time per request: 19.096 [ms] (mean, across all concurrent requests)

Transfer rate: 11.76 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 0 1.1 0 25

Processing: 23 1623 1012.4 1422 5302

Waiting: 23 1619 1013.9 1421 5302

Total: 23 1624 1012.4 1423 5302

Percentage of the requests served within a certain time (ms)

50% 1423

66% 1878

75% 2194

80% 2402

90% 3033

95% 3627

98% 4234

99% 4815

100% 5302 (longest request)

C:> ab -c 100 -n 1000 http://localhost:9002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: localhost

Server Port: 9002

Document Path: /api/recommendations/Alfa

Document Length: 44 bytes

Concurrency Level: 100

Time taken for tests: 8.962 seconds

Complete requests: 3000

Failed requests: 52(Connect: 0, Receive: 0, Length: 52, Exceptions: 0)

Total transferred: 710948 bytes

HTML transferred: 131948 bytes

Requests per second: 334.73 [#/sec] (mean)

Time per request: 298.749 [ms] (mean)

Time per request: 2.987 [ms] (mean, across all concurrent requests)

Transfer rate: 77.47 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 1 3.1 0 111

Processing: 1 245 314.7 167 3295

Waiting: 1 165 251.0 132 3283

Total: 1 246 314.8 168 3297

Percentage of the requests served within a certain time (ms)

50% 168

66% 258

75% 297

80% 330

90% 378

95% 690

98% 1359

99% 1634

100% 3297 (longest request)

C:> ab -c 100 -n 3000 http://localhost:9002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

Scenario 5: Hystrix Dashboard

MEMBERSHIP

SERVICE (9001)

RECOMMENDATIONS

SERVICE (9002)EUREKA

SERVER

(DISCOVERY)

EUREKA

SERVER

(9000)EUREKA

CLIENT

EUREKA

CLIENT

RIBBON +

HYSTRIX

HYSTRIX

DASHBOARD

(8888)

MILAN 18/19.11.2015 - GIULIO SANTOLI

1. Go to the Spring Initializer site (https://start.spring.io)

2. Select Gradle Project with Spring Boot 1.2.7

3. Specify in Project Metadata:

Group: com.microservices

Artifact: hystrixdashboard

4. Add the following starters: Hystrix Dashboard

5. Generate the Project (hystrixdashboard.zip) and extract it.

6. Open the file build.gradle with your Java editor (IntelliJ)

Netflix Hystrix Dashboard

MILAN 18/19.11.2015 - GIULIO SANTOLI

package com.microservices;

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

@SpringBootApplication@EnableHystrixDashboardpublic class HystrixdashboardApplication {

public static void main(String[] args) {SpringApplication.run(HystrixdashboardApplication.class, args);

}}

HystrixdashboardApplication.java

Add this

annotation

server.port: ${PORT:8888}spring.application.name: hystrix-dashsecurity.basic.enabled: false

application.yml

Create this

file in

"resources"

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\hystrixdashboard> gradlew bootRunOPEN THE BROWSER AT: http://localhost:8888/hystrixINSERT THE FOLLOWING LINK: http://localhost:9002/hystrix.stream

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> ab -c 100 -n 1000 http://localhost:9002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

Scenario 6: Edge Server and Data Aggregation

MEMBERSHIP

SERVICE (9001)

RECOMMENDATIONS

SERVICE (9002)EUREKA

SERVER

(DISCOVERY)

EUREKA

SERVER

(9000)EUREKA

CLIENT

EUREKA

CLIENT

RIBBON +

HYSTRIX

HYSTRIX

DASHBOARD

(8888)

ZUUL EDGE SERVER

(7777)

EUREKA

CLIENT

RIBBON +

HYSTRIX

TURBINE

AGGREGATION

(9999)

MILAN 18/19.11.2015 - GIULIO SANTOLI

1. Go to the Spring Initializer site (https://start.spring.io)

2. Select Gradle Project with Spring Boot 1.2.7

3. Specify in Project Metadata:

Group: com.microservices

Artifact: zuul

4. Add the following starters: Eureka Discovery, Hystrix, Ribbon, Zuul,

Actuator

5. Generate the Project (zuul.zip) and extract it.

6. Open the file build.gradle with your Java editor (IntelliJ)

Netflix Edge Server

MILAN 18/19.11.2015 - GIULIO SANTOLI

package com.microservices;

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication@EnableZuulProxypublic class ZuulApplication {

public static void main(String[] args) {SpringApplication.run(ZuulApplication.class, args);

}}

ZuulApplication.java

Add this

annotation

MILAN 18/19.11.2015 - GIULIO SANTOLI

server.port: ${PORT:7777}spring.application.name: edgeserversecurity.basic.enabled: false

eureka:client.serviceUrl.defaultZone: http://localhost:9000/eureka/instance.metadataMap.instanceId: ${spring.application.name}:${server.port}

zuul:ignoredServices: '*'routes:

recommendations:path: /api/recommendations/**stripPrefix: false

membership:path: api/member/**stripPrefix: false

application.yml

Create this

file in

"resources"

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\zuul> curl http://localhost:7777/api/recommendations/AlfaC:\zuul> curl http://localhost:7777/api/recommendations/Beta

MILAN 18/19.11.2015 - GIULIO SANTOLI

1. Go to the Spring Initializer site (https://start.spring.io)

2. Select Gradle Project with Spring Boot 1.2.7

3. Specify in Project Metadata:

Group: com.microservices

Artifact: turbine

4. Add the following starters: Eureka Discovery, Hystrix, Ribbon, Turbine,

Actuator

5. Generate the Project (turbine.zip) and extract it.

6. Open the file build.gradle with your Java editor (IntelliJ)

Netflix Monitoring Aggregation

MILAN 18/19.11.2015 - GIULIO SANTOLI

package com.microservices;

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.turbine.EnableTurbine;

@SpringBootApplication@EnableTurbinepublic class TurbineApplication {

public static void main(String[] args) {SpringApplication.run(TurbineApplication.class, args);

}}

TurbineApplication.java

Add this

annotation

MILAN 18/19.11.2015 - GIULIO SANTOLI

server.port: ${PORT:7777}spring.application.name: edgeserversecurity.basic.enabled: false

eureka:client:

serviceUrl:defaultZone: http://localhost:9000/eureka/

zuul:ignoredServices: '*'routes:

recommendations:path: /api/recommendations/**stripPrefix: false

application.yml

Create this

file in

"resources"

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\turbine> gradlew bootRunOPEN THE BROWSER AT: http://localhost:8888/hystrixINSERT THE FOLLOWING LINKS:

http://localhost:7777/hystrix.streamhttp://localhost:9999/turbine.stream?cluster=EDGESERVERhttp://localhost:9999/turbine.stream?cluster=RECOMMENDATIONS

MILAN 18/19.11.2015 - GIULIO SANTOLI

MILAN 18/19.11.2015 - GIULIO SANTOLI

Scenario 7: Running on Docker

RECOMMENDATIONS

(5002:9002)

MEMBERSHIP

(5001:9001)

EUREKA

(5000:9000)

link:eurekasrv

link:eurekasrv

Docker Engine

MILAN 18/19.11.2015 - GIULIO SANTOLI

server:port: ${PORT:9000}

eureka:instance:

hostname: localhostclient:

registerWithEureka: falsefetchRegistry: falseserviceUrl:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

---# Eureka instance when used on Dockerspring:profiles: docker

eureka:instance:

hostname: eurekasrv

application.yml

Modify the file

for eureka

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\eurekaserver> gradlew bootRepackageC:\eurekaserver> java -jar build\libs\eurekaserver-0.0.1-SNAPSHOT.jar

FROM java:8VOLUME /tmpENV SPRING_PROFILES_ACTIVE dockerCOPY build/libs/eurekaserver-0.0.1-SNAPSHOT.jar app.jarRUN bash -c 'touch /app.jar'EXPOSE 9000ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

Dockerfile

Create this file in

"eurekaserver"

MILAN 18/19.11.2015 - GIULIO SANTOLI

eureka:build: eurekaserverrestart: alwaysports:

- "5000:9000"

docker-compose.yml

Create this file

In the main directory

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> docker-compose build

C:\> docker-compose up -d eureka

C:\> docker-compose psName Command State Ports

------------------------------------------------------------------------------------------------------------workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcp

C:\> docker-compose logs eureka

C:\> docker-machine env –shell cmd docker192.168.99.100

OPEN THE BROWSER AT: http://192.168.99.100:5000/

MILAN 18/19.11.2015 - GIULIO SANTOLI

MILAN 18/19.11.2015 - GIULIO SANTOLI

...

---spring:profiles: docker

logging.file: /tmp/membership.log

eureka:instance:

preferIpAddress : trueclient:

serviceUrl:defaultZone: http://eurekasrv:9000/eureka/

application.yml

Modify the file

for membership

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> gradlew bootRepackageC:\membership> java -jar build\libs\memberhip-0.0.1-SNAPSHOT.jar

FROM java:8VOLUME /tmpENV SPRING_PROFILES_ACTIVE dockerADD build/libs/membership-0.0.1-SNAPSHOT.jar app.jarRUN bash -c 'touch /app.jar'EXPOSE 9001ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

Dockerfile

Create this file in

memberhip

MILAN 18/19.11.2015 - GIULIO SANTOLI

eureka:build: eurekaserverrestart: alwaysports:

- "5000:9000"

membership:build: membershiprestart: alwayslinks:

- eureka:eurekasrvports:

- "5001:9001"

docker-compose.yml

Add the following

statements

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> docker-compose build membership

C:\> docker-compose up -d memberhip

C:\> docker-compose psName Command State Ports

-------------------------------------------------------------------------------------------------------------------workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcpworkshop_membership_1 java -Djava.security.egd=f ... Up 0.0.0.0:5001->9001/tcp

C:\> docker-compose logs memberhip

C:\> curl http://192.168.99.100:5001/api/member/Alfa

OPEN THE BROWSER AT: http://192.168.99.100:5000/

MILAN 18/19.11.2015 - GIULIO SANTOLI

MILAN 18/19.11.2015 - GIULIO SANTOLI

...

---spring:profiles: docker

logging.file: /tmp/recommendations.log

eureka:instance:

preferIpAddress : trueclient:

serviceUrl:defaultZone: http://eurekasrv:9000/eureka/

application.yml

Modify the file

for recommendations

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\recommendations> gradlew bootRepackageC:\recommendations> java -jar build\libs\recommendations-0.0.1-SNAPSHOT.jar

FROM java:8VOLUME /tmpENV SPRING_PROFILES_ACTIVE dockerADD build/libs/recommendations-0.0.1-SNAPSHOT.jar app.jarRUN bash -c 'touch /app.jar'EXPOSE 9002ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

Dockerfile

Create this file in

recommendations

MILAN 18/19.11.2015 - GIULIO SANTOLI

eureka:build: eurekaserverrestart: alwaysports:

- "5000:9000"

membership:build: membershiprestart: alwayslinks:

- eureka:eurekasrvports:

- "5001:9001"

recommendations:build: recommendationsrestart: alwaysports:

- "5002:9002"links:

- eureka:eurekasrv

docker-compose.yml

Add the following

statements

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> docker-compose build recommendations

C:\> docker-compose up -d recommendations

C:\> docker-compose psName Command State Ports----------------------------------------------------------------------------------------------------------------------------workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcpworkshop_membership_1 java -Djava.security.egd=f ... Up 0.0.0.0:5001->9001/tcpworkshop_recommendations_1 java -Djava.security.egd=f ... Up 0.0.0.0:5002->9002/tcp

C:\> docker-compose logs recommendations

C:\> curl http://192.168.99.100:5002/api/recommendations/AlfaC:\> curl http://192.168.99.100:5002/api/recommendations/Beta

OPEN THE BROWSER AT: http://192.168.99.100:5000/

MILAN 18/19.11.2015 - GIULIO SANTOLI

MILAN 18/19.11.2015 - GIULIO SANTOLI

MEMBERSHIP

(5001:9001)

Scenario 8: Hystrix and Load Balancing

RECOMMENDATIONS

(5002:9002)

MEMBERSHIP

(5001:9001)

EUREKA

(5000:9000)

link:eurekasrv

link:eurekasrv

Docker Engine

HYSTRIX

(5555:8888)

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\hystrixdashboard> gradlew bootRepackageC:\hystrixdashboard> java -jar build\libs\hystrixdashboard-0.0.1-SNAPSHOT.jar

FROM java:8VOLUME /tmpCOPY build/libs/hystrixdashboard-0.0.1-SNAPSHOT.jar app.jarRUN bash -c 'touch /app.jar'EXPOSE 8888ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

Dockerfile

Create this file in

hystrixdashboard

MILAN 18/19.11.2015 - GIULIO SANTOLI

...

hystrix:build: hystrixdashboardrestart: alwaysports:

- “5555:8888"

docker-compose.yml

Add the following

statements

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> docker-compose build hystrix

C:\> docker-compose up -d hystrix

C:\> docker-compose psName Command State Ports----------------------------------------------------------------------------------------------------------------------------workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcpworkshop_hystrix_1 java -Djava.security.egd=f ... Up 0.0.0.0:5555->8888/tcpworkshop_membership_1 java -Djava.security.egd=f ... Up 0.0.0.0:5001->9001/tcpworkshop_recommendations_1 java -Djava.security.egd=f ... Up 0.0.0.0:5002->9002/tcp

C:\> curl http://192.168.99.100:5002/api/recommendations/AlfaC:\> curl http://192.168.99.100:5002/api/recommendations/Beta

MILAN 18/19.11.2015 - GIULIO SANTOLI

OPEN THE BROWSER AT: http://192.168.99.100:5555/hystrixINSERT THE FOLLOWING LINK: http://172.17.0.5:9002/hystrix.stream

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> ab -c 100 -n 3000 http://192.168.99.100:5002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> docker-compose stop membershipC:\membership> docker-compose rm -f –v membership

...

membership:build: membershiprestart: alwayslinks:

- eureka:eurekasrvports:

- "5001:9001"

...

docker-compose.yml

Remove these

lines

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> docker-compose up -d membership

C:\> docker-compose scale membership=2

C:\> docker-compose psName Command State Ports----------------------------------------------------------------------------------------------------------------------------workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcpworkshop_hystrix_1 java -Djava.security.egd=f ... Up 0.0.0.0:5555->8888/tcpworkshop_membership_1 java -Djava.security.egd=f ... Up 9001/tcpworkshop_membership_2 java -Djava.security.egd=f ... Up 9001/tcpworkshop_recommendations_1 java -Djava.security.egd=f ... Up 0.0.0.0:5002->9002/tcp

C:\> curl http://192.168.99.100:5002/api/recommendations/AlfaC:\> curl http://192.168.99.100:5002/api/recommendations/Beta

MILAN 18/19.11.2015 - GIULIO SANTOLI

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: 192.168.99.100

Server Port: 5002

Document Path: /api/recommendations/Alfa

Document Length: 44 bytes

Concurrency Level: 50

Time taken for tests: 11.212 seconds

Complete requests: 1000

Failed requests: 72 (Connect: 0, Receive: 0, Length: 72, Exceptions: 0)

Total transferred: 243928 bytes

HTML transferred: 43928 bytes

Requests per second: 89.19 [#/sec] (mean)

Time per request: 560.624 [ms] (mean)

Time per request: 11.212 [ms] (mean, across all concurrent requests)

Transfer rate: 21.25 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 3 1.5 2 16

Processing: 7 455 461.0 383 5505

Waiting: 5 319 446.5 221 5290

Total: 9 458 461.0 385 5507

Percentage of the requests served within a certain time (ms)

50% 385

66% 459

75% 517

80% 567

90% 689

95% 1061

98% 2141

99% 2915

100% 5507 (longest request)

C\:> ab -c 50 -n 1000 http://localhost:9002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: 192.168.99.100

Server Port: 5002

Document Path: /api/recommendations/Alfa

Document Length: 44 bytes

Concurrency Level: 50

Time taken for tests: 14.943 seconds

Complete requests: 1000

Failed requests: 93 (Connect: 0, Receive: 0, Length: 93, Exceptions: 0)

Total transferred: 243907 bytes

HTML transferred: 43907 bytes

Requests per second: 66.92 [#/sec] (mean)

Time per request: 747.134 [ms] (mean)

Time per request: 14.943 [ms] (mean, across all concurrent requests)

Transfer rate: 15.94 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 3 2.0 2 24

Processing: 15 611 536.9 483 4565

Waiting: 14 432 514.3 288 4558

Total: 16 614 537.0 484 4568

Percentage of the requests served within a certain time (ms)

50% 484

66% 614

75% 709

80% 787

90% 1068

95% 1456

98% 2590

99% 3025

100% 4568 (longest request)

C\:> ab -c 50 -n 1000 http://localhost:9002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

Scenario 9: Centralized Logging with ELK

RECOMMENDATIONS

(5002:9002)

MEMBERSHIP

EUREKA

(5000:9000)

link:eurekasrv

link:eurekasrv

Docker Engine

ELASTICSEARCH

HYSTRIX

(5555:8888)

LOGSTASH

(/tmp)

KIBANA

(5601:5601)

link:elasticsearch

link:elasticsearch

volume:logstashfw

volume:logstashfw

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> docker-compose stop

C:\> docker-compose rm -f -v

C:\> docker-compose psName Command State Ports------------------------------

FROM logstashCOPY conf/logstash-spring-boot.conf /conf/logstash-spring-boot.confCOPY conf/custompatterns /opt/logstash/patterns/custompatterns

Dockerfile

Create this file in

logstash

MILAN 18/19.11.2015 - GIULIO SANTOLI

input {file {path => [ "/tmp/*.log" ]

}}

filter {multiline {

pattern => "^(%{TIMESTAMP_ISO8601})"negate => truewhat => "previous"

}grok {

# Do multiline matching with (?m) as the above mutliline filter may add newlines to the log messages.match => [ "message", "(?m)^%{TIMESTAMP_ISO8601:logtime}%{SPACE}%{LOGLEVEL:loglevel} %{SPACE}%{NUMBER:pid}%{SPACE}---

%{SPACE}%{SYSLOG5424SD:threadname}%{SPACE}%{JAVACLASSSHORT:classname}%{SPACE}:%{SPACE}%{GREEDYDATA:logmessage}" ]}

}

output {elasticsearch { hosts => ["elasticsearch:9200"] }stdout { codec => rubydebug }

}

logstash-spring-boot.conf

Create these file in

logstash/conf

JAVACLASSSHORT (?:[\.]?[a-zA-Z0-9-]+\.)*[A-Za-z0-9$]+ custompatterns

MILAN 18/19.11.2015 - GIULIO SANTOLI

...

elasticsearch:image: elasticsearchcommand: elasticsearch -Des.network.host=::0

kibana:image: kibanaports:- "5601:5601"

links:- elasticsearch

logstash:build: logstashcommand: logstash -f /conf/logstash-spring-boot.conflinks:- elasticsearch

volumes:- /tmp/

docker-compose.yml

Add the following

statements

MILAN 18/19.11.2015 - GIULIO SANTOLI

...

membership:build: membershiprestart: alwayslinks:

- eureka:eurekasrvvolumes_from:- logstash

recommendations:build: recommendationsrestart: alwaysports:

- "5002:9002"links:

- eureka:eurekasrvvolumes_from:- logstash

...

docker-compose.yml

Add these

statements

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\logstash> docker-compose build logstash

C:\logstash> docker-compose up -d elasticsearch eurekaC:\logstash> docker-compose up -d kibana logstashC:\logstash> docker-compose up -d membershipC:\logstash> docker-compose up -d recommendations

C:\>docker-compose psName Command State Ports------------------------------------------------------------------------------------------------------------------------------workshop_elasticsearch_1 /docker-entrypoint.sh elas ... Up 9200/tcp, 9300/tcpworkshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcpworkshop_kibana_1 /docker-entrypoint.sh kibana Up 0.0.0.0:5601->5601/tcpworkshop_logstash_1 /docker-entrypoint.sh logs ... Upworkshop_membership_1 java -Djava.security.egd=f ... Up 9001/tcpworkshop_recommendations_1 java -Djava.security.egd=f ... Up 0.0.0.0:5002->9002/tcp

MILAN 18/19.11.2015 - GIULIO SANTOLI

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\logstash> curl http://192.168.99.100:5002/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

MEMBERSHIP

(80)

Scenario 10: Cloud Foundry

RECOMMENDATIONS

(80)

MEMBERSHIP

(80)

EUREKA

(80)

HYSTRIX

(80)

EUREKA

SERVICE

MILAN 18/19.11.2015 - GIULIO SANTOLI

server:port: ${PORT:9000}

eureka:instance:

hostname: ${vcap.application.uris[0]:localhost}client:

registerWithEureka: falsefetchRegistry: falseserviceUrl:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

---spring:profiles: docker

eureka:instance:

hostname: eurekasrv

application.yml

Modify the file

for eureka

MILAN 18/19.11.2015 - GIULIO SANTOLI

---applications:- name: giulio-eurekamemory: 256Minstances: 1path: build/libs/eurekaserver-0.0.1-SNAPSHOT.jarenv:

JAVA_OPTS: "-Djava.security.egd=file:/dev/./urandom"

manifest.yml

Create this file

for eureka

Use a unique

Name!

C:\eurekaserver> gradlew bootRepackage

C:\eurekaserver> java -jar build\libs\eurekaserver-0.0.1-SNAPSHOT.jar

C:\eurekaserver> cf push

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\eurekaserver> cf appsGetting apps in org [email protected] / space demo as [email protected]

name requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\> cf cups giulio-eureka-service -p "{\"uri\": \"http://giulio-eureka.mybluemix.net/eureka/\"}«

C:\> cf servicesGetting services in org [email protected] / space demo as [email protected]

name service plan bound apps last operationgiulio-eureka-service user-provided

Define a

custom service

MILAN 18/19.11.2015 - GIULIO SANTOLI

server.port: ${PORT:9001}

spring.application.name: membership

security.basic.enabled: false

eureka:leaseRenewalIntervalInSeconds: 3client:registryFetchIntervalSeconds: 5instanceInfoReplicationIntervalSeconds: 5initialInstanceInfoReplicationIntervalSeconds: 5serviceUrl:defaultZone: ${vcap.services.giulio-eureka-service.credentials.uri:http://localhost:9000/eureka/}

instance:hostname: ${vcap.application.uris[0]:localhost}metadataMap:instanceId: ${spring.application.name}:${server.port}

---spring:profiles: cloud

eureka.instance.nonSecurePort: 80

...

application.yml

Modify the file

for members

MILAN 18/19.11.2015 - GIULIO SANTOLI

---applications:- name: giulio-membershipmemory: 256Minstances: 1path: build/libs/membership-0.0.1-SNAPSHOT.jarenv:

JAVA_OPTS: "-Djava.security.egd=file:/dev/./urandom"SPRING_PROFILES_ACTIVE: cloud

services:- giulio-eureka-service

manifest.yml

Create this file in

membership

Use a unique

Name!

C:\membership> gradlew bootRepackage

C:\membership> java -jar build\libs\membership-0.0.1-SNAPSHOT.jar

C:\membership> cf push

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> cf appsname requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.netgiulio-membership started 1/1 256M 1G giulio-membership.mybluemix.net

C:\membership> curl http://giulio-membership.mybluemix.net/api/member/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

server.port: ${PORT:9002}

spring.application.name: recommendations

security.basic.enabled: false

eureka:leaseRenewalIntervalInSeconds: 3client:registryFetchIntervalSeconds: 5instanceInfoReplicationIntervalSeconds: 5initialInstanceInfoReplicationIntervalSeconds: 5serviceUrl:defaultZone: ${vcap.services.giulio-eureka-service.credentials.uri:http://localhost:9000/eureka/}

instance:hostname: ${vcap.application.uris[0]:localhost}metadataMap:instanceId: ${spring.application.name}:${server.port}

...

application.yml

Modify the file

for recommendations

MILAN 18/19.11.2015 - GIULIO SANTOLI

---applications:- name: giulio-recommendationsmemory: 256Minstances: 1path: build/libs/recommendations-0.0.1-SNAPSHOT.jarenv:

JAVA_OPTS: "-Djava.security.egd=file:/dev/./urandom"services:- giulio-eureka-service

manifest.yml

Create this file in

recommendations

Use a unique

Name!

C:\recommendations> gradlew bootRepackage

C:\recommendations> java -jar build\libs\recommendations-0.0.1-SNAPSHOT.jar

C:\recommendations> cf push

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\recommendations> cf appsname requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.netgiulio-membership started 1/1 256M 1G giulio-membership.mybluemix.netgiulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net

C:\recommendations> crul http://giulio-recommendations.mybluemix.net/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\recommendations> cf scale giulio-membership -i 2C:\recommendations> cf appsname requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.netgiulio-membership started 2/2 256M 1G giulio-membership.mybluemix.netgiulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net

MILAN 18/19.11.2015 - GIULIO SANTOLI

---applications:- name: giulio-hystrixmemory: 256Minstances: 1path: build/libs/hystrixdashboard-0.0.1-SNAPSHOT.jarenv:

JAVA_OPTS: "-Djava.security.egd=file:/dev/./urandom"

manifest.yml

Create this file in

hystrixdashboard

Use a unique

Name!

C:\hystrixdashboard> cf push

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\hystrixdashboard> cf appsname requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.netgiulio-hystrix started 1/1 256M 1G giulio-hystrix.mybluemix.netgiulio-membership started 2/2 256M 1G giulio-membership.mybluemix.netgiulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net

OPEN BROWSER AT: http://giulio-hystrix.mybluemix.net/hystrixINSERT: http://giulio-recommendations.mybluemix.net:80/hystrix.stream

MILAN 18/19.11.2015 - GIULIO SANTOLI

MEMBERSHIP

(80)

Scenario 11: Canary Deployment in Cloud Foundry

RECOMMENDATIONS

(80)MEMBERSHIP 1

(80)

EUREKA

(80)

EUREKA

SERVICEMEMBERSHIP

(80)MEMBERSHIP 2

(80)

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> cf stop giulio-hystrixC:\membership> cf scale giulio-membership -i 3C:\membership> cf appsname requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.netgiulio-hystrix stopped 0/1 256M 1G giulio-hystrix.mybluemix.netgiulio-membership started 3/3 256M 1G giulio-membership.mybluemix.netgiulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: giulio-recommendations.mybluemix.net

Server Port: 80

Document Path: /api/recommendations/Alfa

Document Length: 43 bytes

Concurrency Level: 30

Time taken for tests: 40.687 seconds

Complete requests: 200

Failed requests: 5 (Connect: 0, Receive: 0, Length: 5, Exceptions: 0)

Total transferred: 81594 bytes

HTML transferred: 8605 bytes

Requests per second: 4.92 [#/sec] (mean)

Time per request: 6103.125 [ms] (mean)

Time per request: 203.437 [ms] (mean, across all concurrent requests)

Transfer rate: 1.96 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 146 180 355.7 152 5183

Processing: 610 4436 1435.4 4448 9753

Waiting: 462 3066 1790.0 2799 9729

Total: 769 4616 1483.3 4599 9907

Percentage of the requests served within a certain time (ms)

50% 4599

66% 4646

75% 4654

80% 4675

90% 5210

95% 9642

98% 9890

99% 9901

100% 9907 (longest request)

C\:> ab -c 30 -n 200 http://giulio-recommendations.mybluemix.net/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

...

@RestController@RequestMapping("/api/member")class MembershipController {

@RequestMapping(method = RequestMethod.POST)public Member register(@RequestBody Member member) { … }

@RequestMapping("/{user}")Member login(@PathVariable String user) {

// delay();return memberStore.get(user);

}

private void delay() { … }}

...

MembershipApplication.java

Comment

this line

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> gradlew bootRepackage

C:\membership> cf scale giulio-membership -i 2

C:\membership> cf push giulio-membershipv2

C:\membership> cf appsname requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.netgiulio-hystrix started 1/1 256M 1G giulio-hystrix.mybluemix.netgiulio-membership started 2/2 256M 1G giulio-membership.mybluemix.netgiulio-membershipv2 started 1/1 256M 1G giulio-membershipv2.mybluemix.netgiulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: giulio-recommendations.mybluemix.net

Server Port: 80

Document Path: /api/recommendations/Alfa

Document Length: 43 bytes

Concurrency Level: 30

Time taken for tests: 33.151 seconds

Complete requests: 200

Failed requests: 0

Total transferred: 81589 bytes

HTML transferred: 8600 bytes

Requests per second: 6.03 [#/sec] (mean)

Time per request: 4972.644 [ms] (mean)

Time per request: 165.755 [ms] (mean, across all concurrent requests)

Transfer rate: 2.40 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 146 155 8.8 153 202

Processing: 178 4210 960.7 4502 6497

Waiting: 178 2735 1348.5 2768 6496

Total: 327 4365 959.7 4657 6649

Percentage of the requests served within a certain time (ms)

50% 4657

66% 4685

75% 4710

80% 4729

90% 4953

95% 5363

98% 5891

99% 6332

100% 6649 (longest request)

C\:> ab -c 30 -n 200 http://giulio-recommendations.mybluemix.net/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> cf scale giulio-membership -i 1

C:\membership> cf scale giulio-membershipv2 -i 2

C:\membership> cf appsname requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.netgiulio-hystrix started 1/1 256M 1G giulio-hystrix.mybluemix.netgiulio-membership started 1/1 256M 1G giulio-membership.mybluemix.netgiulio-membershipv2 started 2/2 256M 1G giulio-membershipv2.mybluemix.netgiulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: giulio-recommendations.mybluemix.net

Server Port: 80

Document Path: /api/recommendations/Alfa

Document Length: 43 bytes

Concurrency Level: 30

Time taken for tests: 34.895 seconds

Complete requests: 200

Failed requests: 0

Total transferred: 81590 bytes

HTML transferred: 8600 bytes

Requests per second: 5.73 [#/sec] (mean)

Time per request: 5234.177 [ms] (mean)

Time per request: 174.473 [ms] (mean, across all concurrent requests)

Transfer rate: 2.28 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 146 161 18.2 154 229

Processing: 178 4339 1066.0 4487 6084

Waiting: 176 2768 1427.3 2780 6083

Total: 335 4500 1071.1 4646 6308

Percentage of the requests served within a certain time (ms)

50% 4646

66% 4798

75% 4831

80% 4968

90% 5708

95% 5795

98% 5868

99% 6189

100% 6308 (longest request)

C\:> ab -c 30 -n 200 http://giulio-recommendations.mybluemix.net/api/recommendations/Alfa

MILAN 18/19.11.2015 - GIULIO SANTOLI

C:\membership> cf stop giulio-membership

C:\membership> cf scale giulio-membershipv2 -i 3

C:\membership> cf appsname requested state instances memory disk urlsgiulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.netgiulio-hystrix started 1/1 256M 1G giulio-hystrix.mybluemix.netgiulio-membership started 0/1 256M 1G giulio-membership.mybluemix.netgiulio-membershipv2 started 3/3 256M 1G giulio-membershipv2.mybluemix.netgiulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net

MILAN 18/19.11.2015 - GIULIO SANTOLI

Server Hostname: giulio-recommendations.mybluemix.net

Server Port: 80

Document Path: /api/recommendations/Alfa

Document Length: 43 bytes

Concurrency Level: 30

Time taken for tests: 30.898 seconds

Complete requests: 200

Failed requests: 0

Total transferred: 81591 bytes

HTML transferred: 8600 bytes

Requests per second: 6.47 [#/sec] (mean)

Time per request: 4634.710 [ms] (mean)

Time per request: 154.490 [ms] (mean, across all concurrent requests)

Transfer rate: 2.58 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 147 153 4.9 151 188

Processing: 215 4122 941.2 4449 4585

Waiting: 211 2344 1262.3 2324 4583

Total: 364 4274 941.1 4601 4738

Percentage of the requests served within a certain time (ms)

50% 4601

66% 4613

75% 4624

80% 4634

90% 4658

95% 4664

98% 4676

99% 4732

100% 4738 (longest request)

C\:> ab -c 30 -n 200 http://giulio-recommendations.mybluemix.net/api/recommendations/Alfa