#!/usr/bin/env bash # # Собирает (опционально) и складывает bootJar всех Spring-сервисов в одну папку # serviceAllBuild/ в корне проекта, рядом кладёт config-repo и хелпер запуска run.sh. # # Использование: # ./serviceAllBuild.sh # только собрать jar-ы в одно место (сервисы уже собраны) # ./serviceAllBuild.sh --build # сначала ./gradlew bootJar, потом собрать в одно место # set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" OUT="$ROOT/serviceAllBuild" SERVICES_DIR="$ROOT/services" DO_BUILD=0 [[ "${1:-}" == "--build" ]] && DO_BUILD=1 if [[ $DO_BUILD -eq 1 ]]; then echo "==> Сборка bootJar всех сервисов (./gradlew bootJar)..." "$ROOT/gradlew" bootJar fi mkdir -p "$OUT" echo "==> Сбор jar-ов в $OUT" count=0 for dir in "$SERVICES_DIR"/*/; do name="$(basename "$dir")" libs="$dir/build/libs" [[ -d "$libs" ]] || { echo " - $name: нет build/libs (не Spring-сервис или не собран), пропуск"; continue; } # bootJar = единственный *.jar без суффикса -plain.jar; берём самый свежий по имени jar="$(find "$libs" -maxdepth 1 -name '*.jar' ! -name '*-plain.jar' | sort | tail -n1)" [[ -n "$jar" ]] || { echo " - $name: bootJar не найден, пропуск"; continue; } cp -f "$jar" "$OUT/$name.jar" echo " + $name.jar <- $(basename "$jar")" count=$((count + 1)) done echo "==> Копирую config-repo в $OUT/config-repo (самодостаточная папка)" rm -rf "$OUT/config-repo" cp -r "$ROOT/config-repo" "$OUT/config-repo" echo "==> Генерирую $OUT/run.sh" cat > "$OUT/run.sh" <<'RUNEOF' #!/usr/bin/env bash # # Запуск одного сервиса из собранной папки через java -jar. # # ./run.sh # список доступных сервисов # ./run.sh spring-cloud-config-server # ПЕРВЫМ всегда поднимаем config server # ./run.sh pcp-tgu-service # затем нужные сервисы (в отдельных терминалах) # # Память не ограничена. Задать лимит при необходимости: # JAVA_OPTS="-Xmx384m" ./run.sh pcp-tgu-service # set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_REPO="$HERE/config-repo" JAVA_OPTS="${JAVA_OPTS:-}" name="${1:-}" if [[ -z "$name" ]]; then echo "Использование: ./run.sh <имя-сервиса>" echo echo "Сначала запусти config server: ./run.sh spring-cloud-config-server" echo echo "Доступные сервисы:" for j in "$HERE"/*.jar; do basename "$j" .jar; done | sed 's/^/ /' exit 1 fi jar="$HERE/$name.jar" [[ -f "$jar" ]] || { echo "Нет файла: $jar"; exit 1; } if [[ "$name" == "spring-cloud-config-server" ]]; then # config server в профиле local работает в native-режиме и читает yaml отсюда export SPRING_PROFILES_ACTIVE="${SPRING_PROFILES_ACTIVE:-local}" export CONFIG_NATIVE_SEARCH_LOCATIONS="${CONFIG_NATIVE_SEARCH_LOCATIONS:-optional:file:$CONFIG_REPO}" echo "==> config-repo: $CONFIG_REPO" fi echo "==> java $JAVA_OPTS -jar $name.jar" exec java $JAVA_OPTS -jar "$jar" RUNEOF chmod +x "$OUT/run.sh" echo "==> Генерирую $OUT/up.sh" cat > "$OUT/up.sh" <<'UPEOF' #!/usr/bin/env bash # # Поднять сразу несколько сервисов в фоне (config server — всегда первым). # # ./up.sh # запустить ВСЕ сервисы # ./up.sh pcp-tgu-service slots-service # config server + перечисленные # # Имя сервиса = имя jar-файла без .jar. Логи: logs/.log, pid: logs/.pid. # Погасить всё: ./down.sh # set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_REPO="$HERE/config-repo" LOGS="$HERE/logs" mkdir -p "$LOGS" JAVA_OPTS="${JAVA_OPTS:-}" CFG="spring-cloud-config-server" running() { local p="$LOGS/$1.pid"; [[ -f "$p" ]] && kill -0 "$(cat "$p")" 2>/dev/null; } start_one() { local name="$1" jar="$HERE/$1.jar" [[ -f "$jar" ]] || { echo " ! нет $name.jar, пропуск"; return; } if running "$name"; then echo " = $name уже запущен (pid $(cat "$LOGS/$name.pid"))"; return; fi if [[ "$name" == "$CFG" ]]; then SPRING_PROFILES_ACTIVE="${SPRING_PROFILES_ACTIVE:-local}" \ CONFIG_NATIVE_SEARCH_LOCATIONS="${CONFIG_NATIVE_SEARCH_LOCATIONS:-optional:file:$CONFIG_REPO}" \ nohup java $JAVA_OPTS -jar "$jar" > "$LOGS/$name.log" 2>&1 & else nohup java $JAVA_OPTS -jar "$jar" > "$LOGS/$name.log" 2>&1 & fi echo $! > "$LOGS/$name.pid" echo " + $name (pid $!) -> logs/$name.log" } wait_config_server() { printf "==> жду config server на :8888" for _ in $(seq 1 60); do if curl -sf http://localhost:8888/actuator/health >/dev/null 2>&1; then echo " — UP"; return 0; fi printf "."; sleep 2 done echo " — не дождался; смотри logs/$CFG.log"; exit 1 } targets=("$@") if [[ ${#targets[@]} -eq 0 ]]; then for j in "$HERE"/*.jar; do targets+=("$(basename "$j" .jar)"); done fi echo "==> config server" start_one "$CFG" running "$CFG" && wait_config_server echo "==> остальные сервисы" for name in "${targets[@]}"; do [[ "$name" == "$CFG" ]] && continue start_one "$name" done echo "Готово. Логи: tail -f logs/.log Стоп: ./down.sh" UPEOF chmod +x "$OUT/up.sh" echo "==> Генерирую $OUT/down.sh" cat > "$OUT/down.sh" <<'DOWNEOF' #!/usr/bin/env bash # # Погасить сервисы, запущенные через up.sh. # ./down.sh # погасить все # ./down.sh pcp-tgu-service ... # погасить только перечисленные # set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" LOGS="$HERE/logs" names=("$@") if [[ ${#names[@]} -eq 0 ]]; then shopt -s nullglob for p in "$LOGS"/*.pid; do names+=("$(basename "$p" .pid)"); done fi for name in "${names[@]}"; do p="$LOGS/$name.pid" [[ -f "$p" ]] || { echo " - $name: pid-файла нет"; continue; } pid="$(cat "$p")" if kill -0 "$pid" 2>/dev/null; then kill "$pid"; echo " x $name (pid $pid) остановлен"; else echo " - $name (pid $pid) уже не жив"; fi rm -f "$p" done DOWNEOF chmod +x "$OUT/down.sh" echo "==> Генерирую $OUT/README.md" cat > "$OUT/README.md" <<'MDEOF' # serviceAllBuild — локальный запуск сервисов через `java -jar` Папку формирует скрипт `../serviceAllBuild.sh`. Здесь лежат bootJar всех Spring-сервисов, копия `config-repo` и хелпер `run.sh`. ## Куда класть config-repo `spring-cloud-config-server` в профиле `local` работает в **native**-режиме и читает yaml-файлы из локальной папки (а не из git). Папка `config-repo` **уже скопирована сюда** скриптом сборки, и `run.sh` сам передаёт в config server абсолютный путь к ней через `CONFIG_NATIVE_SEARCH_LOCATIONS`. То есть ничего вручную раскладывать не нужно — достаточно запускать config server через `./run.sh spring-cloud-config-server`. Если правишь конфиги — правь `serviceAllBuild/config-repo/*.yaml` (или пересобери скриптом, чтобы подтянуть изменения из корневого `config-repo`). ## Перед запуском: инфраструктура Сервисам нужны (см. `config-repo/application-local.yaml`): - PostgreSQL на `localhost:5432` - Kafka на `localhost:29092` Подними их (например, через docker-compose проекта) и создай БД скриптами из корня (`create-service-dbs.sh` / `create_pcp_databases.sh`). ## Порядок запуска Config server слушает порт **8888** — остальные сервисы ходят за конфигом именно туда, поэтому он всегда первый. Имя сервиса = имя jar-файла без `.jar`. ### Несколько сервисов сразу (в фоне) ```bash ./up.sh # ВСЕ сервисы ./up.sh pcp-tgu-service slots-service # config server + перечисленные ``` `up.sh` сам поднимает config server первым, ждёт его готовности на :8888, затем запускает остальные в фоне. Логи — в `logs/.log`, pid — в `logs/.pid`. ```bash tail -f logs/pcp-tgu-service.log # смотреть лог ./down.sh # погасить все ./down.sh slots-service # погасить один ``` ### По одному (на переднем плане, каждый в своём терминале) ```bash # терминал 1 ./run.sh spring-cloud-config-server # терминал 2 (после того как config server поднялся) ./run.sh pcp-tgu-service ``` Порты сервисов заданы в `config-repo/application-local.yaml` (`pcp.ports.*`): tgu=7011, slots=7006, ui=7008, gateway=7080, request=7005, mission=7010 и т.д. ## Память Лимит heap не задан — JVM сама возьмёт до 25% физической RAM на каждый процесс. Запускай только то, что нужно прямо сейчас. При нехватке памяти можно ограничить конкретный сервис: ```bash JAVA_OPTS="-Xmx384m" ./run.sh pcp-mission-planing-service ``` MDEOF echo echo "Готово: $count сервисов в $OUT" echo "Запуск: cd serviceAllBuild && ./run.sh spring-cloud-config-server"