Slide 1

Slide 1 text

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.

Slide 2

Slide 2 text

Cover w/ Image Agenda ● Different systems, new needs ● Spring Native ● Spring & K8s ● Debugging and optimising complex distributed systems

Slide 3

Slide 3 text

Different Systems, New Needs

Slide 4

Slide 4 text

Microservices Serverless Complex Distributed Systems

Slide 5

Slide 5 text

Scalability Resilience Managing a fleet of instances for each service IAAS

Slide 6

Slide 6 text

Quick startup Low memory footprint Instant peak performance

Slide 7

Slide 7 text

Debugging and optimising complex distributed systems

Slide 8

Slide 8 text

Spring Native

Slide 9

Slide 9 text

Based on GraalVM native images

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Spring Native Image support

Slide 14

Slide 14 text

Native Image Configuration Reflection Proxies Resources

Slide 15

Slide 15 text

Native Image Configuration META-INF/native-image/resource-config.json META-INF/native-image/reflect-config.json META-INF/native-image/proxy-config.json

Slide 16

Slide 16 text

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":[] }, ] }

Slide 17

Slide 17 text

Spring Native Configuration @NativeHint(trigger = EnableDiscoveryClientImportSelector. class, types = {@TypeHint(types = {AutoServiceRegistrationConfiguration. class, ConditionalOnReactiveDiscoveryEnabled .class }) }) @ResourceHint() @JdkProxyHint() @SerializationHint () @InitializationHint () @AotProxyHint()

Slide 18

Slide 18 text

Ahead of Time Transformations Spring AOT plugin* * New: 0.11

Slide 19

Slide 19 text

Changes Build time + 2050% Memory -75% Startup time -94% Measurements Source: Sébastien Deleuze, Andy Clement https://www.youtube.com/watch?v=Um9djPTtPe0

Slide 20

Slide 20 text

Changes https://via.vmw.com/native-samples

Slide 21

Slide 21 text

Native Image Configuration Compatibility Optimization Agent support for tests

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Spring Cloud Native Image support Planned support ● Spring Cloud Gateway ● Spring Cloud OpenFeign ● Spring Cloud CircuitBreaker ● Spring Cloud Kubernetes

Slide 24

Slide 24 text

DEMO

Slide 25

Slide 25 text

Spring & K8S

Slide 26

Slide 26 text

Spring 🖤 K8s Agenda ● Spring Boot & K8S - new and noteworthy ● What is Spring Cloud Kubernetes and when to (not) use it

Slide 27

Slide 27 text

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 ?

Slide 28

Slide 28 text

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’

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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/

Slide 31

Slide 31 text

Spring 🖤 K8s The problem ● How to store multiple configurations in a single configuration file? ● How to store configuration that is platform-specific?

Slide 32

Slide 32 text

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.

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

Spring 🖤 K8s The problem ● How to ensure that K8s liveness and readiness probing works fine?

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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 "

Slide 39

Slide 39 text

Spring 🖤 K8s Kubernetes probes ● You can then configure your Kubernetes infrastructure with the following endpoint information livenessProbe: httpGet: path: /actuator/health/liveness port: failureThreshold: ... periodSeconds: ... readinessProbe: httpGet: path: /actuator/health/readiness port: failureThreshold: ... periodSeconds: ...

Slide 40

Slide 40 text

Spring 🖤 K8s The problem ● How to create a proper Docker image?

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

Spring Cloud & K8S

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

Spring Cloud Kubernetes Controllers Roadmap ● Service Discovery

Slide 48

Slide 48 text

DOCKER IMAGE BUILDING DEMO

Slide 49

Slide 49 text

Debugging and optimising complex distributed systems

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

What if the apps produced metrics about their state? Is there a way to correlate logs?

Slide 54

Slide 54 text

Let’s Address The Metrics Problem

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

Metrics Store

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

What are metrics good for?

Slide 60

Slide 60 text

What About The Log Correlation?

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

Logs Store

Slide 65

Slide 65 text

[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() 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() 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)

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

What If The System Is Slow?

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

Service 1 Service 3 Service 4 Application Controller Application Service Service 2

Slide 70

Slide 70 text

Service 1 Service 3 Service 4 Application Controller Application Service Service 2 Operation Operation? Operation Operation

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

Service 1 Service 3 Service 4 Application Controller Application Service Service 2 Span Span Span Single trace

Slide 73

Slide 73 text

Span Store

Slide 74

Slide 74 text

Span Whole trace Production dependency graph

Slide 75

Slide 75 text

METRICS: Micrometer Spring Boot Actuator

Slide 76

Slide 76 text

TRACING: Spring Cloud Sleuth

Slide 77

Slide 77 text

VMware Tanzu Observability Enterprise observability for multi-cloud environments Free Tanzu Observability for your Spring Boot applications - no sign-up needed

Slide 78

Slide 78 text

presentation-service

Slide 79

Slide 79 text

DEMO

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

Thank you @olga_maciaszek @mgrzejszczak © 2020 Spring. A VMware-backed project. 81