Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Microservices Architecture: Labs

534 views

Published on

Labs for the Microservices Architecture full day workshop, using technologies like Spring Cloud Netflix, Docker, Cloud Foundry, ELK.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Microservices Architecture: Labs

  1. 1. MILAN 18/19.11.2015 Microservices architecture labs GIULIO SANTOLI - @gjuljo
  2. 2. MILAN 18/19.11.2015 - GIULIO SANTOLI RECOMMENDATIONS SERVICE (9002) MEMBERSHIP SERVICE (9001) Scenario 1: Naive Implementation
  3. 3. 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
  4. 4. 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 @RestController public 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
  5. 5. 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:Bluemixworkshopmembershipbuildclassesmain started by Giulio in C:Bluemixworkshopmembership) 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 con text 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$Whitelabel ErrorViewConfig uration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path res ource [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; ini tMethodName=nul l; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfigu ration$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 CE T 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()
  6. 6. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership>curl localhost:8080 Hello world
  7. 7. 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
  8. 8. 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
  9. 9. 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"
  10. 10. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership> gradlew bootRun C:membership> curl localhost:9001/api/member/Alfa C:membership> curl localhost:9001/api/member/Beta
  11. 11. 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
  12. 12. 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; @SpringBootApplication public class RecommendationsApplication { public static void main(String[] args) { SpringApplication.run(RecommendationsApplication.class, args); } @Bean public RestTemplate restTemplate() { return new RestTemplate(); } } RecommendationsApplication.java Add this method
  13. 13. 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
  14. 14. MILAN 18/19.11.2015 - GIULIO SANTOLI ... @RestController @RequestMapping("/api/recommendations") class RecommendationController { @Autowired RestTemplate 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
  15. 15. MILAN 18/19.11.2015 - GIULIO SANTOLI server: port: ${PORT:9002} application.yml Create this file in "resources"
  16. 16. MILAN 18/19.11.2015 - GIULIO SANTOLI C:recommendations> gradlew bootRun C:recommendations> curl http://localhost:9002/api/recommendations/Alfa C:recommendations> curl http://localhost:9002/api/recommendations/Beta
  17. 17. 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
  18. 18. 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
  19. 19. 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
  20. 20. 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
  21. 21. 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 @EnableEurekaServer public class EurekaserverApplication { public static void main(String[] args) { SpringApplication.run(EurekaserverApplication.class, args); } } EurekaserverApplication.java Add this annotation
  22. 22. MILAN 18/19.11.2015 - GIULIO SANTOLI server: port: ${PORT:9000} eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ application.yml Create this file in "resources"
  23. 23. MILAN 18/19.11.2015 - GIULIO SANTOLI C:eurekaserver> gradlew bootRun C:> curl -s -H "Accept: application/json" http://localhost:9000/eureka/apps
  24. 24. MILAN 18/19.11.2015 - GIULIO SANTOLI package com.microservices; import … @SpringBootApplication @RestController @EnableEurekaClient public class MembershipApplication { … } ... MembershipApplication.java Add this annotation
  25. 25. MILAN 18/19.11.2015 - GIULIO SANTOLI server: port: ${PORT:9001} spring: application.name: membership security: basic: enabled: false eureka: leaseRenewalIntervalInSeconds: 3 client: registryFetchIntervalSeconds: 5 instanceInfoReplicationIntervalSeconds: 5 initialInstanceInfoReplicationIntervalSeconds: 5 serviceUrl: defaultZone: http://localhost:9000/eureka/ instance: metadataMap: instanceId: ${spring.application.name}:${server.port} application.yml Add these lines
  26. 26. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership> gradlew bootRun C:membership> curl http://localhost:9001/api/member/Alfa C:> curl -s -H "Accept: application/json" http://localhost:9000/eureka/apps
  27. 27. MILAN 18/19.11.2015 - GIULIO SANTOLI package com.microservices; import ... @EnableEurekaClient public class RecommendationsApplication { public static void main(String[] args) { ... } /* @Bean public 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
  28. 28. MILAN 18/19.11.2015 - GIULIO SANTOLI server: port: ${PORT:9002} spring: application.name: recommendations security: basic: enabled: false eureka: leaseRenewalIntervalInSeconds: 3 client: registryFetchIntervalSeconds: 5 instanceInfoReplicationIntervalSeconds: 5 initialInstanceInfoReplicationIntervalSeconds: 5 serviceUrl: defaultZone: http://localhost:9000/eureka/ instance: metadataMap: instanceId: ${spring.application.name}:${server.port} application.yml Add these lines
  29. 29. MILAN 18/19.11.2015 - GIULIO SANTOLI C:recommendations> gradlew bootRun C:recommendations> curl http://localhost:9002/api/recommendations/Alfa C:> curl -s -H "Accept: application/json" http://localhost:9000/eureka/apps
  30. 30. 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
  31. 31. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership> set PORT=9003 && gradlew bootRun C:recommendations> curl http://localhost:9002/api/recommendations/Alfa C:> curl -s -H "Accept: application/json" http://localhost:9000/eureka/apps
  32. 32. 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
  33. 33. 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
  34. 34. 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
  35. 35. 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
  36. 36. MILAN 18/19.11.2015 - GIULIO SANTOLI C:recommendations> gradlew bootRun C: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"}]
  37. 37. 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
  38. 38. 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
  39. 39. 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)
  40. 40. 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
  41. 41. 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 @EnableHystrixDashboard public 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-dash security.basic.enabled: false application.yml Create this file in "resources"
  42. 42. MILAN 18/19.11.2015 - GIULIO SANTOLI C:hystrixdashboard> gradlew bootRun OPEN THE BROWSER AT: http://localhost:8888/hystrix INSERT THE FOLLOWING LINK: http://localhost:9002/hystrix.stream
  43. 43. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> ab -c 100 -n 1000 http://localhost:9002/api/recommendations/Alfa
  44. 44. 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)
  45. 45. 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
  46. 46. 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 @EnableZuulProxy public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class, args); } } ZuulApplication.java Add this annotation
  47. 47. MILAN 18/19.11.2015 - GIULIO SANTOLI server.port: ${PORT:7777} spring.application.name: edgeserver security.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"
  48. 48. MILAN 18/19.11.2015 - GIULIO SANTOLI C:zuul> curl http://localhost:7777/api/recommendations/Alfa C:zuul> curl http://localhost:7777/api/recommendations/Beta
  49. 49. 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
  50. 50. 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 @EnableTurbine public class TurbineApplication { public static void main(String[] args) { SpringApplication.run(TurbineApplication.class, args); } } TurbineApplication.java Add this annotation
  51. 51. MILAN 18/19.11.2015 - GIULIO SANTOLI server.port: ${PORT:7777} spring.application.name: edgeserver security.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"
  52. 52. MILAN 18/19.11.2015 - GIULIO SANTOLI C:turbine> gradlew bootRun OPEN THE BROWSER AT: http://localhost:8888/hystrix INSERT THE FOLLOWING LINKS: http://localhost:7777/hystrix.stream http://localhost:9999/turbine.stream?cluster=EDGESERVER http://localhost:9999/turbine.stream?cluster=RECOMMENDATIONS
  53. 53. MILAN 18/19.11.2015 - GIULIO SANTOLI
  54. 54. 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
  55. 55. MILAN 18/19.11.2015 - GIULIO SANTOLI server: port: ${PORT:9000} eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ --- # Eureka instance when used on Docker spring: profiles: docker eureka: instance: hostname: eurekasrv application.yml Modify the file for eureka
  56. 56. MILAN 18/19.11.2015 - GIULIO SANTOLI C:eurekaserver> gradlew bootRepackage C:eurekaserver> java -jar buildlibseurekaserver-0.0.1-SNAPSHOT.jar FROM java:8 VOLUME /tmp ENV SPRING_PROFILES_ACTIVE docker COPY build/libs/eurekaserver-0.0.1-SNAPSHOT.jar app.jar RUN bash -c 'touch /app.jar' EXPOSE 9000 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] Dockerfile Create this file in "eurekaserver"
  57. 57. MILAN 18/19.11.2015 - GIULIO SANTOLI eureka: build: eurekaserver restart: always ports: - "5000:9000" docker-compose.yml Create this file In the main directory
  58. 58. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> docker-compose build C:> docker-compose up -d eureka C:> docker-compose ps Name 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 docker 192.168.99.100 OPEN THE BROWSER AT: http://192.168.99.100:5000/
  59. 59. MILAN 18/19.11.2015 - GIULIO SANTOLI
  60. 60. MILAN 18/19.11.2015 - GIULIO SANTOLI ... --- spring: profiles: docker logging.file: /tmp/membership.log eureka: instance: preferIpAddress : true client: serviceUrl: defaultZone: http://eurekasrv:9000/eureka/ application.yml Modify the file for membership
  61. 61. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership> gradlew bootRepackage C:membership> java -jar buildlibsmemberhip-0.0.1-SNAPSHOT.jar FROM java:8 VOLUME /tmp ENV SPRING_PROFILES_ACTIVE docker ADD build/libs/membership-0.0.1-SNAPSHOT.jar app.jar RUN bash -c 'touch /app.jar' EXPOSE 9001 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] Dockerfile Create this file in memberhip
  62. 62. MILAN 18/19.11.2015 - GIULIO SANTOLI eureka: build: eurekaserver restart: always ports: - "5000:9000" membership: build: membership restart: always links: - eureka:eurekasrv ports: - "5001:9001" docker-compose.yml Add the following statements
  63. 63. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> docker-compose build membership C:> docker-compose up -d memberhip C:> docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------------- workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcp workshop_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/
  64. 64. MILAN 18/19.11.2015 - GIULIO SANTOLI
  65. 65. MILAN 18/19.11.2015 - GIULIO SANTOLI ... --- spring: profiles: docker logging.file: /tmp/recommendations.log eureka: instance: preferIpAddress : true client: serviceUrl: defaultZone: http://eurekasrv:9000/eureka/ application.yml Modify the file for recommendations
  66. 66. MILAN 18/19.11.2015 - GIULIO SANTOLI C:recommendations> gradlew bootRepackage C:recommendations> java -jar buildlibsrecommendations-0.0.1-SNAPSHOT.jar FROM java:8 VOLUME /tmp ENV SPRING_PROFILES_ACTIVE docker ADD build/libs/recommendations-0.0.1-SNAPSHOT.jar app.jar RUN bash -c 'touch /app.jar' EXPOSE 9002 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] Dockerfile Create this file in recommendations
  67. 67. MILAN 18/19.11.2015 - GIULIO SANTOLI eureka: build: eurekaserver restart: always ports: - "5000:9000" membership: build: membership restart: always links: - eureka:eurekasrv ports: - "5001:9001" recommendations: build: recommendations restart: always ports: - "5002:9002" links: - eureka:eurekasrv docker-compose.yml Add the following statements
  68. 68. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> docker-compose build recommendations C:> docker-compose up -d recommendations C:> docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------------------------------------------------- workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcp workshop_membership_1 java -Djava.security.egd=f ... Up 0.0.0.0:5001->9001/tcp workshop_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/Alfa C:> curl http://192.168.99.100:5002/api/recommendations/Beta OPEN THE BROWSER AT: http://192.168.99.100:5000/
  69. 69. MILAN 18/19.11.2015 - GIULIO SANTOLI
  70. 70. 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)
  71. 71. MILAN 18/19.11.2015 - GIULIO SANTOLI C:hystrixdashboard> gradlew bootRepackage C:hystrixdashboard> java -jar buildlibshystrixdashboard-0.0.1-SNAPSHOT.jar FROM java:8 VOLUME /tmp COPY build/libs/hystrixdashboard-0.0.1-SNAPSHOT.jar app.jar RUN bash -c 'touch /app.jar' EXPOSE 8888 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] Dockerfile Create this file in hystrixdashboard
  72. 72. MILAN 18/19.11.2015 - GIULIO SANTOLI ... hystrix: build: hystrixdashboard restart: always ports: - “5555:8888" docker-compose.yml Add the following statements
  73. 73. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> docker-compose build hystrix C:> docker-compose up -d hystrix C:> docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------------------------------------------------- workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcp workshop_hystrix_1 java -Djava.security.egd=f ... Up 0.0.0.0:5555->8888/tcp workshop_membership_1 java -Djava.security.egd=f ... Up 0.0.0.0:5001->9001/tcp workshop_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/Alfa C:> curl http://192.168.99.100:5002/api/recommendations/Beta
  74. 74. MILAN 18/19.11.2015 - GIULIO SANTOLI OPEN THE BROWSER AT: http://192.168.99.100:5555/hystrix INSERT THE FOLLOWING LINK: http://172.17.0.5:9002/hystrix.stream
  75. 75. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> ab -c 100 -n 3000 http://192.168.99.100:5002/api/recommendations/Alfa
  76. 76. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership> docker-compose stop membership C:membership> docker-compose rm -f –v membership ... membership: build: membership restart: always links: - eureka:eurekasrv ports: - "5001:9001" ... docker-compose.yml Remove these lines
  77. 77. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> docker-compose up -d membership C:> docker-compose scale membership=2 C:> docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------------------------------------------------- workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcp workshop_hystrix_1 java -Djava.security.egd=f ... Up 0.0.0.0:5555->8888/tcp workshop_membership_1 java -Djava.security.egd=f ... Up 9001/tcp workshop_membership_2 java -Djava.security.egd=f ... Up 9001/tcp workshop_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/Alfa C:> curl http://192.168.99.100:5002/api/recommendations/Beta
  78. 78. MILAN 18/19.11.2015 - GIULIO SANTOLI
  79. 79. 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
  80. 80. 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
  81. 81. 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
  82. 82. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> docker-compose stop C:> docker-compose rm -f -v C:> docker-compose ps Name Command State Ports ------------------------------ FROM logstash COPY conf/logstash-spring-boot.conf /conf/logstash-spring-boot.conf COPY conf/custompatterns /opt/logstash/patterns/custompatterns Dockerfile Create this file in logstash
  83. 83. MILAN 18/19.11.2015 - GIULIO SANTOLI input { file { path => [ "/tmp/*.log" ] } } filter { multiline { pattern => "^(%{TIMESTAMP_ISO8601})" negate => true what => "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
  84. 84. MILAN 18/19.11.2015 - GIULIO SANTOLI ... elasticsearch: image: elasticsearch command: elasticsearch -Des.network.host=::0 kibana: image: kibana ports: - "5601:5601" links: - elasticsearch logstash: build: logstash command: logstash -f /conf/logstash-spring-boot.conf links: - elasticsearch volumes: - /tmp/ docker-compose.yml Add the following statements
  85. 85. MILAN 18/19.11.2015 - GIULIO SANTOLI ... membership: build: membership restart: always links: - eureka:eurekasrv volumes_from: - logstash recommendations: build: recommendations restart: always ports: - "5002:9002" links: - eureka:eurekasrv volumes_from: - logstash ... docker-compose.yml Add these statements
  86. 86. MILAN 18/19.11.2015 - GIULIO SANTOLI C:logstash> docker-compose build logstash C:logstash> docker-compose up -d elasticsearch eureka C:logstash> docker-compose up -d kibana logstash C:logstash> docker-compose up -d membership C:logstash> docker-compose up -d recommendations C:>docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------------------------ workshop_elasticsearch_1 /docker-entrypoint.sh elas ... Up 9200/tcp, 9300/tcp workshop_eureka_1 java -Djava.security.egd=f ... Up 0.0.0.0:5000->9000/tcp workshop_kibana_1 /docker-entrypoint.sh kibana Up 0.0.0.0:5601->5601/tcp workshop_logstash_1 /docker-entrypoint.sh logs ... Up workshop_membership_1 java -Djava.security.egd=f ... Up 9001/tcp workshop_recommendations_1 java -Djava.security.egd=f ... Up 0.0.0.0:5002->9002/tcp
  87. 87. MILAN 18/19.11.2015 - GIULIO SANTOLI
  88. 88. MILAN 18/19.11.2015 - GIULIO SANTOLI C:logstash> curl http://192.168.99.100:5002/api/recommendations/Alfa
  89. 89. MILAN 18/19.11.2015 - GIULIO SANTOLI MEMBERSHIP (80) Scenario 10: Cloud Foundry RECOMMENDATIONS (80) MEMBERSHIP (80) EUREKA (80) HYSTRIX (80) EUREKA SERVICE
  90. 90. MILAN 18/19.11.2015 - GIULIO SANTOLI server: port: ${PORT:9000} eureka: instance: hostname: ${vcap.application.uris[0]:localhost} client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ --- spring: profiles: docker eureka: instance: hostname: eurekasrv application.yml Modify the file for eureka
  91. 91. MILAN 18/19.11.2015 - GIULIO SANTOLI --- applications: - name: giulio-eureka memory: 256M instances: 1 path: build/libs/eurekaserver-0.0.1-SNAPSHOT.jar env: 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 buildlibseurekaserver-0.0.1-SNAPSHOT.jar C:eurekaserver> cf push
  92. 92. MILAN 18/19.11.2015 - GIULIO SANTOLI C:eurekaserver> cf apps Getting apps in org giulio_santoli@it.ibm.com / space demo as giulio_santoli@it.ibm.com... OK name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net
  93. 93. MILAN 18/19.11.2015 - GIULIO SANTOLI C:> cf cups giulio-eureka-service -p "{"uri": "http://giulio-eureka.mybluemix.net/eureka/"}« C:> cf services Getting services in org giulio_santoli@it.ibm.com / space demo as giulio_santoli@it.ibm.com... OK name service plan bound apps last operation giulio-eureka-service user-provided Define a custom service
  94. 94. MILAN 18/19.11.2015 - GIULIO SANTOLI server.port: ${PORT:9001} spring.application.name: membership security.basic.enabled: false eureka: leaseRenewalIntervalInSeconds: 3 client: registryFetchIntervalSeconds: 5 instanceInfoReplicationIntervalSeconds: 5 initialInstanceInfoReplicationIntervalSeconds: 5 serviceUrl: 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
  95. 95. MILAN 18/19.11.2015 - GIULIO SANTOLI --- applications: - name: giulio-membership memory: 256M instances: 1 path: build/libs/membership-0.0.1-SNAPSHOT.jar env: 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 buildlibsmembership-0.0.1-SNAPSHOT.jar C:membership> cf push
  96. 96. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership> cf apps name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net giulio-membership started 1/1 256M 1G giulio-membership.mybluemix.net C:membership> curl http://giulio-membership.mybluemix.net/api/member/Alfa
  97. 97. MILAN 18/19.11.2015 - GIULIO SANTOLI server.port: ${PORT:9002} spring.application.name: recommendations security.basic.enabled: false eureka: leaseRenewalIntervalInSeconds: 3 client: registryFetchIntervalSeconds: 5 instanceInfoReplicationIntervalSeconds: 5 initialInstanceInfoReplicationIntervalSeconds: 5 serviceUrl: 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
  98. 98. MILAN 18/19.11.2015 - GIULIO SANTOLI --- applications: - name: giulio-recommendations memory: 256M instances: 1 path: build/libs/recommendations-0.0.1-SNAPSHOT.jar env: 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 buildlibsrecommendations-0.0.1-SNAPSHOT.jar C:recommendations> cf push
  99. 99. MILAN 18/19.11.2015 - GIULIO SANTOLI C:recommendations> cf apps name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net giulio-membership started 1/1 256M 1G giulio-membership.mybluemix.net giulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net C:recommendations> crul http://giulio-recommendations.mybluemix.net/api/recommendations/Alfa
  100. 100. MILAN 18/19.11.2015 - GIULIO SANTOLI C:recommendations> cf scale giulio-membership -i 2 C:recommendations> cf apps name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net giulio-membership started 2/2 256M 1G giulio-membership.mybluemix.net giulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net
  101. 101. MILAN 18/19.11.2015 - GIULIO SANTOLI --- applications: - name: giulio-hystrix memory: 256M instances: 1 path: build/libs/hystrixdashboard-0.0.1-SNAPSHOT.jar env: JAVA_OPTS: "-Djava.security.egd=file:/dev/./urandom" manifest.yml Create this file in hystrixdashboard Use a unique Name! C:hystrixdashboard> cf push
  102. 102. MILAN 18/19.11.2015 - GIULIO SANTOLI C:hystrixdashboard> cf apps name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net giulio-hystrix started 1/1 256M 1G giulio-hystrix.mybluemix.net giulio-membership started 2/2 256M 1G giulio-membership.mybluemix.net giulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net OPEN BROWSER AT: http://giulio-hystrix.mybluemix.net/hystrix INSERT: http://giulio-recommendations.mybluemix.net:80/hystrix.stream
  103. 103. MILAN 18/19.11.2015 - GIULIO SANTOLI MEMBERSHIP (80) Scenario 11: Canary Deployment in Cloud Foundry RECOMMENDATIONS (80) MEMBERSHIP 1 (80) EUREKA (80) EUREKA SERVICE MEMBERSHIP (80) MEMBERSHIP 2 (80)
  104. 104. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership> cf stop giulio-hystrix C:membership> cf scale giulio-membership -i 3 C:membership> cf apps name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net giulio-hystrix stopped 0/1 256M 1G giulio-hystrix.mybluemix.net giulio-membership started 3/3 256M 1G giulio-membership.mybluemix.net giulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net
  105. 105. 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
  106. 106. 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
  107. 107. 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 apps name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net giulio-hystrix started 1/1 256M 1G giulio-hystrix.mybluemix.net giulio-membership started 2/2 256M 1G giulio-membership.mybluemix.net giulio-membershipv2 started 1/1 256M 1G giulio-membershipv2.mybluemix.net giulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net
  108. 108. 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
  109. 109. 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 apps name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net giulio-hystrix started 1/1 256M 1G giulio-hystrix.mybluemix.net giulio-membership started 1/1 256M 1G giulio-membership.mybluemix.net giulio-membershipv2 started 2/2 256M 1G giulio-membershipv2.mybluemix.net giulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net
  110. 110. 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
  111. 111. MILAN 18/19.11.2015 - GIULIO SANTOLI C:membership> cf stop giulio-membership C:membership> cf scale giulio-membershipv2 -i 3 C:membership> cf apps name requested state instances memory disk urls giulio-eureka started 1/1 256M 1G giulio-eureka.mybluemix.net giulio-hystrix started 1/1 256M 1G giulio-hystrix.mybluemix.net giulio-membership started 0/1 256M 1G giulio-membership.mybluemix.net giulio-membershipv2 started 3/3 256M 1G giulio-membershipv2.mybluemix.net giulio-recommendations started 1/1 256M 1G giulio-recommendations.mybluemix.net
  112. 112. 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

×