Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tanzu Tuesday 14 September 2021

Tanzu Tuesday 14 September 2021

Kubernetes has become a de facto standard in the cloud-native software development. Because Spring 🖤 K8s, we have added significant features that make Spring work even better in the Kubernetes environment. The GraalVM project has introduced native images that allow to run Java apps in milliseconds with minimal memory footprint. Because Spring 🖤 native images, we have our own Spring Native project that lets you run Spring Boot apps blazingly fast with low memory consumption. Regardless of how you’re running your applications, production observability is a necessity to debug business problems and latency issues. Because Spring 🖤 observability, we help you add metrics to your processes with Micrometer and visualize latency thanks to distributed tracing with Spring Cloud Sleuth & Tanzu Observability.

In this presentation we will show you how to do all of that with Spring & Spring Cloud.

Olga Maciaszek-Sharma

September 17, 2021
Tweet

More Decks by Olga Maciaszek-Sharma

Other Decks in Technology

Transcript

  1. Olga Maciaszek-Sharma, Marcin Grzejszczak September 2021 New trends in software

    development with Spring Boot and Spring Cloud Copyright © 2020 VMware, Inc. or its affiliates.
  2. Cover w/ Image Agenda • Different systems, new needs •

    Spring Native • Spring & K8s • Debugging and optimising complex distributed systems
  3. GraalVM A high-performance polyglot runtime • 1 VM for all

    languages • Increased efficiency (memory, CPU, resources) • JIT && AOT Source: @thomaswue https://twitter.com/thomaswue/status/1145603781108928513?s=20
  4. Graal VM Native Images / AOT Application Libraries JDK Substrate

    VM Analysis Initializations Heap snapshotting Native Executable (pre-loaded classes, pre-loaded config) Reachable byte code Machine code Build phase: compilation, class-loading, pre-loading configuration Closed World Assumption - no classes being loaded at runtime
  5. GraalVM Native Images PROs • Instant startup • No JIT

    -> reduced memory footprint • Instant peak performance • Sustainable CONs • Peak throughput and max latency (although optimizations available) • Build time
  6. Spring Native Configuration java -agentlib:native-image-agent=config-output-dir=src/main/resources/M ETA-INF/native-image -jar target/appname-0.0.1-SNAPSHOT.jar { "name":"org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinde

    rAutoConfiguration", "allDeclaredFields":true, "allDeclaredMethods":true, "allDeclaredConstructors":true, "methods":[ {"name":"afterSingletonsInstantiated","parameterTypes":[] }, ] }
  7. Spring Native Configuration @NativeHint(trigger = EnableDiscoveryClientImportSelector. class, types = {@TypeHint(types

    = {AutoServiceRegistrationConfiguration. class, ConditionalOnReactiveDiscoveryEnabled .class }) }) @ResourceHint() @JdkProxyHint() @SerializationHint () @InitializationHint () @AotProxyHint()
  8. Changes Build time + 2050% Memory -75% Startup time -94%

    Measurements Source: Sébastien Deleuze, Andy Clement https://www.youtube.com/watch?v=Um9djPTtPe0
  9. Spring Cloud Native Image support Supported starters • Spring Cloud

    Config Client • Spring Cloud Config Server • Spring Cloud LoadBalancer • Spring Cloud Netflix Eureka Client • Spring Cloud Sleuth • Spring Cloud Function • Spring Cloud Stream • Spring Cloud Task • Spring Cloud Sleuth Zipkin
  10. Spring Cloud Native Image support Planned support • Spring Cloud

    Gateway • Spring Cloud OpenFeign • Spring Cloud CircuitBreaker • Spring Cloud Kubernetes
  11. Spring 🖤 K8s Agenda • Spring Boot & K8S -

    new and noteworthy • What is Spring Cloud Kubernetes and when to (not) use it
  12. Spring 🖤 K8s The problem • Need to read config

    values that the platform supplies? • Let’s inject them via environment variables! ◦ What if the value is supposed to be kept secret ?
  13. Spring 🖤 K8s The solution • Many cloud platforms now

    allow you to map configuration into mounted data volumes ◦ For example, Kubernetes can volume mount both ConfigMaps and Secrets • Two common volume mount patterns that can be used: ◦ A single file contains a complete set of properties (usually written as YAML) ◦ Multiple files are written to a directory tree ▪ Filename becoming the ‘key’ ▪ Contents becoming the ‘value’
  14. Spring 🖤 K8s A single file contains a complete set

    of properties • Import the YAML or Properties file directly using spring.config.import spring.config.import=/location/to/your/config/my.properties
  15. Spring 🖤 K8s Multiple files are written to a directory

    tree • Use the configtree: prefix to expose all the files as properties • Let’s assume the following Kubernetes configuration tree etc/ config/ myapp/ username password • Pass the following properties to load those entries spring.config.import=optional:configtree:/etc/config/
  16. Spring 🖤 K8s The problem • How to store multiple

    configurations in a single configuration file? • How to store configuration that is platform-specific?
  17. Spring 🖤 K8s The solution • Spring Boot allows you

    to split a single physical file into multiple logical documents • Documents are processed in order, from top to bottom. ◦ Later documents can override the properties defined in earlier ones.
  18. Spring 🖤 K8s The solution - YAML • For application.yml

    files, the standard YAML multi-document syntax is used. Three consecutive hyphens represent the end of one document, and the start of the next. spring.application.name: MyApp --- spring.config.activate.on-cloud-platform: kubernetes spring.application.name: MyCloudApp
  19. Spring 🖤 K8s The solution - properties • For application.properties

    files a special #--- comment is used to mark the document splits: spring.application.name=MyApp #--- spring.config.activate.on-cloud-platform=kubernetes spring.application.name=MyCloudApp
  20. Spring 🖤 K8s The problem • How to ensure that

    K8s liveness and readiness probing works fine?
  21. Spring 🖤 K8s Liveness • “Liveness” state ◦ Internal state

    allows it to work correctly? ◦ Can recover by itself if it’s currently failing? • A broken “Liveness” ◦ Cannot recover from, and the infrastructure should restart the application • "Liveness" state should not be based on external checks, such as Health checks ◦ A failing external system (a database, a Web API, an external cache) would trigger massive restarts and cascading failures across the platform
  22. Spring 🖤 K8s Readiness • The application is ready to

    handle traffic. • A failing “Readiness” state ◦ Tells the platform that it should not route traffic to the application for now. Typically happens ▪ During startup, while CommandLineRunner and ApplicationRunner components are being processed ▪ At any time if the application decides that it’s too busy for additional traffic • An application is considered ready as soon as application and command-line runners have been called
  23. Spring 🖤 K8s Kubernetes probes • Spring Boot manages your

    Application Availability State out-of-the-box • If deployed in a Kubernetes environment, actuator will gather the "Liveness" and "Readiness" information in dedicated Liveness and Readiness Health Indicators • These indicators will be shown on the global health endpoint ("/actuator/health" ) • They will also be exposed as separate HTTP Probes using Health Groups: "/actuator/health/liveness " and "/actuator/health/readiness "
  24. Spring 🖤 K8s Kubernetes probes • You can then configure

    your Kubernetes infrastructure with the following endpoint information livenessProbe: httpGet: path: /actuator/health/liveness port: <actuator-port> failureThreshold: ... periodSeconds: ... readinessProbe: httpGet: path: /actuator/health/readiness port: <actuator-port> failureThreshold: ... periodSeconds: ...
  25. Spring 🖤 K8s The solution - buildpacks • Transform your

    application source code to images that can run on any cloud ◦ Paketo Buildpacks provide language runtime support for applications ▪ They leverage the Cloud Native Buildpacks framework to make image builds easy, performant, and secure
  26. Spring Cloud & K8s Kubernetes → Cloud Native patterns handled

    on platform level Spring Cloud → Cloud Native patterns handled on application level Spring Cloud Kubernetes → Integrating Spring Cloud apps with Kubernetes components
  27. Spring Cloud & K8s Do you need Spring Cloud Kubernetes

    to use Kubernetes with Spring? → No When is Spring Boot directly with K8s most useful? • Creating new applications from scratch • Running your entire microservice ecosystem on Kubernetes
  28. Spring Cloud & K8s When is Spring Cloud Kubernetes most

    useful? • Migrating existing Spring Cloud - based applications to K8s • Running applications across multiple cloud platforms • More transparency and configuration options for load-balancing from developer’s point of view • Implementing Kubernetes controllers in Java Downside: • Uses Kubernetes API Server - apps need permissions to interact with it
  29. Spring Cloud Kubernetes Controllers Spring Cloud Configuration Watcher • Configuration

    refresh support for K8S ConfigMap/ Secret volumes • HTTP /refresh actuator endpoint support • Spring Cloud Bus support (with messaging) https://via.vmw.com/config-watcher https://via.vmw.com/config-watcher-docs
  30. TraceId: 123 2021-02-10 13:57:55.239 … HELLO FROM SERVICE1 123 123

    2021-02-10 13:58:10.239 … HELLO FROM SERVICE2 123 123 123 2021-02-10 13:58:20.239 … HELLO FROM SERVICE4 123 2021-02-10 13:58:30.239 … HELLO FROM SERVICE3 123
  31. [6dad9c7bd47f0e21c946a7a57d75e7c8] 2021-02-10 13:57:55.239 ERROR 274441 --- [nio-8082-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service()

    for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Meme overflow occurred] with root cause java.lang.IllegalStateException: Meme overflow occurred at io.memegenerator.MemeController.generateMeme(Application.java:93) at io.memegenerator.MemeController$$FastClassBySpringCGLIB$$d54a9db6.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) at io.memegenerator.MemeController$$EnhancerBySpringCGLIB$$e33f7fa1.memeOverflow(<generated>) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
  32. Service 1 Service 3 Service 4 Application Controller Application Service

    Service 2 Operation Operation? Operation Operation
  33. TraceId:123 T:123 T:123 T:123 S:234 S:456 S:345 SpanId:123 - Parent

    ID - Start time - Stop time - Duration - Meta-data SpanId: 456
  34. VMware Tanzu Observability Enterprise observability for multi-cloud environments Free Tanzu

    Observability for your Spring Boot applications - no sign-up needed
  35. Helpful Resources • Presentation demo code • The Path Towards

    Spring Boot Native Applications • Announcing Spring Native Beta! • Spring Native presentation from Spring One 2021 • Spring on Kubernetes! Workshop • Spring On Kubernetes with Ryan Baxter • Spring On Kubernetes Topical Guide • WIP: Kubernetes Discovery Controller