- run.sh: start/stop/restart/status/logs for the whole stack, JAVA_BIN override, pinned to /usr/lib/jvm/java-21-openjdk (Java 25 breaks logback ThrowableProxy inside fat jars and kills Tomcat threads) - -Xmx320m per service, health-gated startup, logs/ dir (gitignored) - README: requirements, run.sh workflow, full current feature list - verified: 25-round load test across all pages under JDK 21 — 0 failures
84 lines
2.6 KiB
Bash
Executable File
84 lines
2.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# Start/stop the full LMS stack.
|
|
# Usage: ./run.sh [start|stop|restart]
|
|
# Java version is pinned via JAVA_BIN (JDK 21 LTS — avoids Java 25 + Logback
|
|
# thread-crash issue). Override with: JAVA_BIN=/path/to/java ./run.sh start
|
|
|
|
set -u
|
|
cd "$(dirname "$0")"
|
|
|
|
JAVA="${JAVA_BIN:-/usr/lib/jvm/java-21-openjdk/bin/java}"
|
|
if [[ ! -x "$JAVA" ]]; then
|
|
echo "JAVA_BIN not found: $JAVA" >&2
|
|
exit 1
|
|
fi
|
|
|
|
LOG_DIR="${LOG_DIR:-logs}"
|
|
mkdir -p "$LOG_DIR"
|
|
|
|
SERVICES=(
|
|
"services/identity-service/build/libs/identity-service-0.1.0-SNAPSHOT.jar:identity:8081"
|
|
"services/academic-service/build/libs/academic-service-0.1.0-SNAPSHOT.jar:academic:8082"
|
|
"services/progress-service/build/libs/progress-service-0.1.0-SNAPSHOT.jar:progress:8083"
|
|
"services/gateway/build/libs/gateway-0.1.0-SNAPSHOT.jar:gateway:8080"
|
|
"web/build/libs/web-0.1.0-SNAPSHOT.jar:web:8090"
|
|
)
|
|
|
|
stop_all() {
|
|
echo "stopping stack..."
|
|
pkill -f 'LMS.*\.jar' 2>/dev/null
|
|
# fallback: kill our own service jars by path
|
|
for entry in "${SERVICES[@]}"; do
|
|
jar="${entry%%:*}"
|
|
pkill -f "$jar" 2>/dev/null
|
|
done
|
|
sleep 3
|
|
echo "stopped"
|
|
}
|
|
|
|
wait_healthy() {
|
|
local port=$1 name=$2
|
|
for _ in $(seq 1 40); do
|
|
[[ "$(curl -s -m 3 "http://localhost:$port/actuator/health" 2>/dev/null)" == *"UP"* ]] && return 0
|
|
sleep 2
|
|
done
|
|
echo "TIMEOUT waiting for $name ($port)" >&2
|
|
return 1
|
|
}
|
|
|
|
start_all() {
|
|
echo "starting with: $("$JAVA" -version 2>&1 | head -1)"
|
|
docker compose up -d postgres >/dev/null 2>&1 || true
|
|
|
|
# identity first: others fetch its JWKS lazily, but ordering keeps logs clean
|
|
for entry in "${SERVICES[@]}"; do
|
|
IFS=: read -r jar name port <<< "$entry"
|
|
if [[ ! -f "$jar" ]]; then
|
|
echo "missing jar: $jar (run ./gradlew bootJar first)" >&2
|
|
exit 1
|
|
fi
|
|
# pidfile per service
|
|
nohup "$JAVA" -Xmx320m -jar "$jar" > "$LOG_DIR/$name.log" 2>&1 &
|
|
echo $! > "$LOG_DIR/$name.pid"
|
|
echo " $name :$port pid=$(cat "$LOG_DIR/$name.pid")"
|
|
done
|
|
|
|
# wait for all health endpoints
|
|
for entry in "${SERVICES[@]}"; do
|
|
IFS=: read -r jar name port <<< "$entry"
|
|
wait_healthy "$port" "$name" && echo " ✓ $name healthy"
|
|
done
|
|
}
|
|
|
|
case "${1:-start}" in
|
|
start) start_all ;;
|
|
stop) stop_all ;;
|
|
restart) stop_all; start_all ;;
|
|
status) for entry in "${SERVICES[@]}"; do
|
|
IFS=: read -r jar name port <<< "$entry"
|
|
printf "%-9s=%s\n" "$name" "$(curl -s -m 3 -o /dev/null -w '%{http_code}' http://localhost:$port/actuator/health 2>/dev/null)"
|
|
done ;;
|
|
logs) tail -n 60 "$LOG_DIR/${2:-all}.log" ;;
|
|
*) echo "usage: $0 [start|stop|restart|status|logs <name>]" >&2; exit 1 ;;
|
|
esac
|