A Spring Boot 4.1.1 order service started 12 ways (plain and extracted jar, Spring AOT output, AppCDS, AOT cache trained with and without traffic, JDK 27, native image), ten interleaved rounds each, with first-request latency; 24 cache-mismatch cases; Docker layer arithmetic. Transcripts are in output/ (no docs/ folder). Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
35 lines
2.3 KiB
Bash
Executable File
35 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Docker layer arithmetic without a Docker daemon: which layers of the extracted application change when one line of
|
|
# code changes, how big each layer is (uncompressed, and gzipped as a registry would store it), and where the AOT
|
|
# cache falls. A layer is "a directory tree"; two builds share a layer when the tree is byte-identical.
|
|
source "$(dirname "$0")/env.sh"
|
|
cd "$ROOT"
|
|
|
|
layer_sum() { # dir -> one hash over every file's path and contents
|
|
( cd "$1" && find . -type f | LC_ALL=C sort | xargs sha256sum | sha256sum | cut -c1-12 )
|
|
}
|
|
gz_kb() { tar -C "$1" -cf - . 2>/dev/null | gzip -6 | wc -c | awk '{printf "%d", $1/1024}'; }
|
|
kb() { find "$1" -type f -printf '%s\n' | awk '{s+=$1} END{printf "%d", s/1024}'; }
|
|
|
|
echo "# java -Djarmode=tools -jar app.jar extract --layers (the layer order Spring Boot's Dockerfile support uses)"
|
|
rm -rf "$WORK/layers-a" "$WORK/layers-b"
|
|
"$JDK25/bin/java" -Djarmode=tools -jar "$WORK/app.jar" extract --layers --destination "$WORK/layers-a" >/dev/null
|
|
printf '%-22s %10s %10s %s\n' layer "KB" "gzip KB" "files"
|
|
for d in dependencies spring-boot-loader snapshot-dependencies application; do
|
|
printf '%-22s %10s %10s %s\n' "$d" "$(kb "$WORK/layers-a/$d")" "$(gz_kb "$WORK/layers-a/$d")" "$(find "$WORK/layers-a/$d" -type f | wc -l)"
|
|
done
|
|
|
|
echo
|
|
echo "# the AOT cache from the training run (context-only), for scale"
|
|
printf '%-22s %10s %10s\n' "refresh.aot" "$(( $(stat -c %s "$WORK/refresh.aot") / 1024 ))" "$(gzip -6 -c "$WORK/refresh.aot" | wc -c | awk '{printf "%d", $1/1024}')"
|
|
|
|
echo
|
|
echo "# change one line of application code (the unit price in OrderService, built by prepare.sh), extract again"
|
|
"$JDK25/bin/java" -Djarmode=tools -jar "$WORK/app-changed.jar" extract --layers --destination "$WORK/layers-b" >/dev/null
|
|
printf '%-22s %-14s %-14s %s\n' layer "before" "after" "verdict"
|
|
for d in dependencies spring-boot-loader snapshot-dependencies application; do
|
|
a=$(layer_sum "$WORK/layers-a/$d"); b=$(layer_sum "$WORK/layers-b/$d")
|
|
printf '%-22s %-14s %-14s %s\n' "$d" "$a" "$b" "$([ "$a" = "$b" ] && echo "identical: reused from cache/registry" || echo "CHANGED: rebuilt and pushed")"
|
|
done
|
|
echo "AOT cache: trained against the previous jar, so it is stale for the new one (see output/04-mismatch.txt); it must be regenerated after the application layer"
|