# k8s native java spring app
<!-- Put the link to this slide here so people can follow -->
slide: https://hackmd.io/@hmoniaga/k8s-native-spring
---
## Why?
- JVM Apps consumes a lot of memory
- Not cost effective (https://learnk8s.io/kubernetes-instance-calculator)
- Not k8s native or container aware by default
- Non-optimized memory management
- Slow startup time
---
## Spring Native
- AOT Framework
- Compiled via GraalVM
---
### GraalVM
- OpenJDK distribution with extra components
- Native image builder
- Does static analysis on compile time, and throw away anything not being used (JRE, other stuff not being used in classpath)
- Other competing GraalVM based frameworks
- micronaut
- quarkus
---
### GraalVM Limitations
- No more dynamic Java behavior
- No reflection, serialization, proxies, JNI
- Not recommended for large monolith or latency sensitive apps due to limited [Garbage collection](https://www.graalvm.org/reference-manual/native-image/MemoryManagement/) options
- Serial GC - stop the world
- G1 GC - concurrent, enterprise version
- Epsilon GC - no op GC
---
### Spring JVM vs Spring Native Comparison
- spring-petclinic
- build size: 261MB vs 143MB
- memory size: 508MB vs 57MB
- startup time: 8s vs 0.
- potential saving in AWS:
- t4g.small 2CPU 2 GB 0,0168$/h = 147.168$/year
- t4g.micro 2CPU 1 GB 0,0084$/h = 73.584$/year
---
### Spring Native Cons
- Slow build time
- May be mitigated by Spring JVM during development, and Spring Native in CI/CD
- Still in beta (0.1 released in June 2021)
- list of supported spring boot: https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#support-spring-boot
- May require some code change, e.g. additional annotations due AOT
---
### Recommended changes
- Use [buildpacks](https://buildpacks.io/) to build container images
- Use Spring Boot Actuator
- Recommended server config:
```properties
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s
```
- k8s pod recommended properties
```yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: app-image
terminationGracePeriodSeconds: 60
```
---
### Health endpoint
- By default, spring actuator's health endpoint includes DB or external components health check
- The “liveness” Probe should not depend on health checks for external systems. Can cause service to trigger restart (and stuck in restart loop) if there is intermittent issues.
- Recommended to turn off external components check
- In newer spring actuator versions, liveness/readiness endpoints are provided by default
```yaml
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: <actuator-port>
failureThreshold: ...
periodSeconds: ...
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: <actuator-port>
failureThreshold: ...
periodSeconds: ...
```
---
### Service Discovery
- In traditional environment, you'd use Spring Discovery / Eureka
- In k8s, it's provided out of the box via DNS
---
### Application configuration
- Storing application.yaml in k8s
- configmap to store configuration
- secret to store sensitive information
- Why not external config server?
- Startup dependency and coupling
- Auto reload provided via Spring Cloud Kubernetes Configuration
---
### Circuit breaking
- Traditional approach would be to use Spring Cloud Hystrix on each service
- If istio or service mesh is installed, this is no longer needed
---
### Thank you! :sheep:
{"metaMigratedAt":"2023-06-16T11:37:45.933Z","metaMigratedFrom":"YAML","title":"k8s native spring application","breaks":true,"description":"lightning talk","contributors":"[{\"id\":\"59159191-cc4b-4810-ac2d-1e3f4e92f52a\",\"add\":7402,\"del\":3750}]"}