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.

Implementing Cloud-Native Architectural Patterns with Micronaut

176 views

Published on

Slides from my presentation at Software Architects Bangalore meetup help on October 12, 2019. Covers externalised configuration, runtime reconfiguration, fault tolerance, and API versioning.

Published in: Software
  • Be the first to comment

Implementing Cloud-Native Architectural Patterns with Micronaut

  1. 1. Implementing Cloud-Native Architectural Patterns with Micronaut Naresha K @naresha_k https://blog.nareshak.com/
  2. 2. About me Developer, Coach, Consultant Founder & Organiser Bangalore Groovy User Group
  3. 3. https://github.com/cncf/toc/blob/master/DEFINITION.md
  4. 4. https://www.redhat.com/en/topics/cloud-native-apps#
  5. 5. https://www.redhat.com/en/topics/cloud-native-apps#
  6. 6. Externalised Configuration
  7. 7. Configuration coupled with code https://blog.nareshak.com/if-you-are-building-your-artifacts-per-environment-you-are-doing-it-wrong/
  8. 8. “Configuration should be version controlled”
  9. 9. Configuration coupled with code
  10. 10. Externalising the configuration
  11. 11. @Controller("/hello") public class HelloController { @Value("${greeting.message}") private String message; @Get("/") @Produces(MediaType.TEXT_PLAIN) public String index() { return message; } }
  12. 12. micronaut: application: name: hello-service greeting: message: Hello from Micronaut
  13. 13. java -Dmicronaut.environments=uat -jar hello-service-0.1.jar
  14. 14. Configuration Injection
  15. 15. java -Dgreeting.message="Hello from External Config” -jar hello-service-0.1.jar java -Dmicronaut.config.files=“/tmp/external-config.yml" -jar hello-service-0.1.jar
  16. 16. Is this not enough?
  17. 17. Config Server
  18. 18. Config Server Application Application Application
  19. 19. docker run -p 8500:8500 consul
  20. 20. bootstrap.yml
  21. 21. curl -X PUT -d @- localhost:8500/v1/kv/config/greet-service/greeting.message <<< "Hello from Consul"
  22. 22. ~ curl http://localhost:8080/greet Hello from Consul
  23. 23. Service Discovery
  24. 24. Cloud Infrastructure
  25. 25. Microservices
  26. 26. Service Registry Service X Service A
  27. 27. Service Registry Service X Service A Register
  28. 28. Service Registry Service X Service A Register
  29. 29. Service Registry Service X Service A Get routing information
  30. 30. Service Registry Service X Service A REST call
  31. 31. --- consul: client: registration: enabled: true defaultZone: "${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}" application.yml
  32. 32. sample-service ./gradlew run > Task :run 05:12:07.121 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 1260ms. Server Running: http://localhost:8080 05:12:07.251 [nioEventLoopGroup-1-3] INFO i.m.d.registration.AutoRegistration - Registered service [sample-service] with Consul
  33. 33. http://localhost:8080/greet
  34. 34. @Controller("/hello") class HelloController { @Inject GreetClient greetClient @Get("/") String index() { greetClient.index() } }
  35. 35. Resilience / Fault Tolerance
  36. 36. https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing
  37. 37. 07:19:19.838 [pool-1-thread-2] ERROR i.m.r.intercept.RecoveryInterceptor - Type [com.nareshak.demo.GreetClient$Intercepted] attempting to resolve fallback for unavailable service [sample-service] 07:19:19.843 [pool-1-thread-2] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: No available services for ID: sample-service io.micronaut.discovery.exceptions.NoAvailableServiceException: No available services for ID: sample- service at io.micronaut.http.client.loadbalance.AbstractRoundRobinLoadBalancer.getNextAvailable(AbstractRoundRo binLoadBalancer.java:50)
  38. 38. Timeout
  39. 39. 07:33:47.976 [pool-1-thread-3] ERROR i.m.r.intercept.RecoveryInterceptor - Type [com.nareshak.demo.GreetClient$Intercepted] executed with error: Read Timeout io.micronaut.http.client.exceptions.ReadTimeoutException: Read Timeout
  40. 40. Retry
  41. 41. @Retryable String callExtService(){ } @Retryable(attempts = "3", delay = "5s") String callExtService(){ }
  42. 42. 07:26:27.347 [pool-1-thread-2] ERROR i.m.r.intercept.RecoveryInterceptor - Type [com.nareshak.demo.GreetClient$Intercepted] attempting to resolve fallback for unavailable service [sample-service] 07:26:37.355 [pool-1-thread-2] ERROR i.m.r.intercept.RecoveryInterceptor - Type [com.nareshak.demo.GreetClient$Intercepted] attempting to resolve fallback for unavailable service [sample-service] 07:26:52.361 [pool-1-thread-2] ERROR i.m.r.intercept.RecoveryInterceptor - Type [com.nareshak.demo.GreetClient$Intercepted] attempting to resolve fallback for unavailable service [sample-service] 07:27:12.373 [pool-1-thread-2] ERROR i.m.r.intercept.RecoveryInterceptor - Type [com.nareshak.demo.GreetClient$Intercepted] attempting to resolve fallback for unavailable service [sample-service] 07:27:12.378 [pool-1-thread-2] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: No available services for ID: sample-service io.micronaut.discovery.exceptions.NoAvailableServiceException: No available services for ID: sample-service at io.micronaut.http.client.loadbalance.AbstractRoundRobinLoadBalancer.getNextAvailable(AbstractRoundRobinLoadBalancer.java:50)
  43. 43. Circuit Breakers
  44. 44. @CircuitBreaker String callExtService(){ } @CircuitBreaker(reset = "40s") String callExtService(){ }
  45. 45. Fallback
  46. 46. @Fallback class FallbackClient implements GreetClient{ @Override String index() { return "Default Message" } }
  47. 47. API Versioning
  48. 48. @Get(“/greet") String index() { "Hello" } @Get(“/greet") Single<String> indexV2() { Single.just("Hello V2") }
  49. 49. @Get(“/greet") @Version("1") String index() { "Hello" } @Get(“/greet") @Version("2") Single<String> indexV2() { Single.just("Hello V2") }
  50. 50. router: versioning: enabled: true header: enabled: true names: - 'X-API-VERSION' - 'Accept-Version' application.yml
  51. 51. ~curl http://localhost:8080/greet -H "X-API-VERSION: 1" Hello% ~ curl http://localhost:8080/greet -H "X-API-VERSION: 2" Hello V2%
  52. 52. @Client("sample-service") @Version("1") interface GreetClient { @Get("/greet") String index() @Version("2") @Get("/greet") Single<String> indexV2() }
  53. 53. When you in are in cloud-native world, features like fault tolerance, service discovery, externalised configuration are necessary Micronaut makes it easier to implement these patterns with its built-in support Conclusion
  54. 54. Thank You

×