Companion code for "Deploying Spring Boot 4 on Kubernetes: Probes, Graceful Shutdown, Limits and JVM Ergonomics". A dependency outage under three probe-group setups, a rolling restart under load four ways (three runs each), the JVM's ergonomic choices for nine pod shapes, one GC-heavy load under five CPU limits with throttling counters, and an HPA driven by a Micrometer gauge through prometheus-adapter. Measured on k3s v1.36.4. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01C3TETMrqVUWeFkNtz3Jbo3
28 lines
1.4 KiB
Python
28 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
"""From the raw GC logs of demo-gc-throttling.sh: CPU time the collector got during pauses vs the
|
|
pauses' wall time (-Xlog:gc+cpu prints User/Sys/Real per collection, at 10 ms resolution).
|
|
A single GC thread that is never descheduled gives a ratio near 1.0; N parallel threads near N.
|
|
Well below that means the collector was waiting for CPU - throttled - inside its own pauses.
|
|
-> docs/output/gc-cpu-ratio.txt"""
|
|
import os, re, sys
|
|
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "docs", "output")
|
|
rows = []
|
|
for v in "ABCDE":
|
|
path = os.path.join(out, f"gc-throttling-{v}-gclog.txt")
|
|
if not os.path.exists(path):
|
|
continue
|
|
cpu = real = 0.0
|
|
n = 0
|
|
for m in re.finditer(r"User=(\d+\.\d+)s Sys=(\d+\.\d+)s Real=(\d+\.\d+)s", open(path).read()):
|
|
u, s, r = map(float, m.groups())
|
|
cpu += u + s
|
|
real += r
|
|
n += 1
|
|
rows.append((v, n, cpu, real, cpu / real if real else 0))
|
|
with open(os.path.join(out, "gc-cpu-ratio.txt"), "w") as f:
|
|
f.write("# CPU the collector received during its pauses, from -Xlog:gc+cpu (sum over every collection)\n\n")
|
|
f.write("%-2s %12s %12s %12s %10s\n" % ("", "collections", "user+sys", "real", "cpu/real"))
|
|
for v, n, cpu, real, ratio in rows:
|
|
f.write("%-2s %12d %11.2fs %11.2fs %10.2f\n" % (v, n, cpu, real, ratio))
|
|
print(open(os.path.join(out, "gc-cpu-ratio.txt")).read())
|