diff --git a/localbox/.env.local b/localbox/.env.local index 48ab087..bc34c34 100644 --- a/localbox/.env.local +++ b/localbox/.env.local @@ -318,6 +318,7 @@ LIKEI_REDIS_DATABASE=0 LIKEI_REDIS_HOST=redis LIKEI_REDIS_PORT=6379 LIKEI_ROCKETMQ_ACCESS_KEY=local +CHATAPP_VOICE_ROOM_ROCKET_MQ_ENABLED=true LIKEI_ROCKETMQ_ENDPOINT=rocketmq-proxy:8081 LIKEI_ROCKETMQ_LOCAL_DISABLE=false LIKEI_ROCKETMQ_SECRET_KEY=local diff --git a/localbox/README.md b/localbox/README.md index 68ecc24..5803a2b 100644 --- a/localbox/README.md +++ b/localbox/README.md @@ -36,7 +36,15 @@ localbox部署/ ./deploy.sh start ``` -如果只想启动、不重新构建本地 Java jar: +`start` 默认只在本地 Java jar 缺失时构建。已有 jar 时会直接启动本地环境。 + +如果想强制重新构建再启动: + +```bash +./deploy.sh start --rebuild +``` + +如果只想启动、不检查和构建本地 Java jar: ```bash ./deploy.sh start --skip-build @@ -101,11 +109,11 @@ docker compose --env-file ./.env.local -f ./local-infra.compose.yml up -d 默认启动流程如下: 1. 安装 `chatapp3-java/maven_private` 私有 Maven 包到本地 Maven 仓库。 -2. 当前终端为 `JDK 17` 时,使用 `local` profile 构建本地 Java jar。 +2. 本地 Java jar 缺失或显式传入 `--rebuild` 时,使用 `local` profile 构建本地 Java jar,默认 `JAVA_MAVEN_THREADS=1C` 开启 Maven reactor 并行。 3. 启动本地 MySQL、Redis、Mongo、Nacos、Zookeeper。 4. 当 `LIKEI_ROCKETMQ_LOCAL_DISABLE=false` 时,额外启动本地 RocketMQ。 -5. 发布本地 Nacos 配置。 -6. 启动全部 Java 服务和 `chatapp3-golang`。 +5. 并发等待基础设施就绪后,发布本地 Nacos 配置。 +6. 启动全部 Java 服务和 `chatapp3-golang`,并发等待端口就绪。 脚本会优先复用当前可用的 Docker Desktop daemon;如果 Docker Desktop 还没起来,会尝试自动拉起。 @@ -152,7 +160,6 @@ docker compose --env-file ./.env.local -f ./local-services.compose.yml logs -f g - `console`: `2700` - `external`: `3000` - `visual-monitor`: `8000` -- `game-fruit`: `8001` - `scheduling`: `2800` - `golang`: `2900` - `nacos`: `8848` diff --git a/localbox/build_local_backend.sh b/localbox/build_local_backend.sh index 71a78b3..3bfcee0 100755 --- a/localbox/build_local_backend.sh +++ b/localbox/build_local_backend.sh @@ -8,6 +8,7 @@ source "$SCRIPT_DIR/common.sh" load_local_env MAVEN_REPO_LOCAL="${MAVEN_REPO_LOCAL:-$ROOT_DIR/var/local-maven-repo}" +JAVA_MAVEN_THREADS="${JAVA_MAVEN_THREADS:-1C}" INSTALL_PRIVATE_SCRIPT="$SCRIPT_DIR/install_private_maven.py" usage() { @@ -23,7 +24,6 @@ all_java_services() { auth console external -game-fruit gateway live order @@ -46,7 +46,6 @@ module_for_service() { console) echo "rc-service/rc-service-console/console-start" ;; visual-monitor) echo "rc-visual/visual-monitor" ;; scheduling) echo "rc-scheduling" ;; - game-fruit) echo "rc-service-game/game-fruit" ;; *) return 1 ;; @@ -92,8 +91,10 @@ done MODULE_LIST="$(IFS=,; echo "${MODULES[*]}")" echo "building java services: ${SELECTED_SERVICES[*]}" +echo "maven reactor threads: $JAVA_MAVEN_THREADS" mvn \ + -T "$JAVA_MAVEN_THREADS" \ -P local \ -Dmaven.repo.local="$MAVEN_REPO_LOCAL" \ -DskipTests \ diff --git a/localbox/check_local_services.sh b/localbox/check_local_services.sh index 9b41396..b9a66cc 100755 --- a/localbox/check_local_services.sh +++ b/localbox/check_local_services.sh @@ -19,7 +19,6 @@ APP_SERVICES=( scheduling external visual-monitor - game-fruit golang ) @@ -44,7 +43,6 @@ FAILURES=0 container_name_for_service() { case "$1" in visual-monitor) printf '%s\n' "chatapp3-local-visual-monitor" ;; - game-fruit) printf '%s\n' "chatapp3-local-game-fruit" ;; rocketmq-namesrv) printf '%s\n' "chatapp3-local-rocketmq-namesrv" ;; rocketmq-broker) printf '%s\n' "chatapp3-local-rocketmq-broker" ;; rocketmq-proxy) printf '%s\n' "chatapp3-local-rocketmq-proxy" ;; diff --git a/localbox/common.sh b/localbox/common.sh index 4345178..b21ab8c 100644 --- a/localbox/common.sh +++ b/localbox/common.sh @@ -270,7 +270,7 @@ require_java_17() { is_java_service() { case "$1" in - gateway|auth|external|other|live|order|wallet|console|visual-monitor|scheduling|game-fruit) + gateway|auth|external|other|live|order|wallet|console|visual-monitor|scheduling) return 0 ;; *) @@ -291,7 +291,6 @@ java_artifact_path_for_service() { console) printf '%s\n' "$JAVA_REPO_DIR/rc-service/rc-service-console/console-start/target/rc-service-console-1.0.0-local.jar" ;; visual-monitor) printf '%s\n' "$JAVA_REPO_DIR/rc-visual/visual-monitor/target/visual-monitor-1.0.0-local.jar" ;; scheduling) printf '%s\n' "$JAVA_REPO_DIR/rc-scheduling/target/rc-scheduling-1.0.0-local.jar" ;; - game-fruit) printf '%s\n' "$JAVA_REPO_DIR/rc-service-game/game-fruit/target/game-fruit-1.0.0-local.jar" ;; *) return 1 ;; @@ -300,7 +299,7 @@ java_artifact_path_for_service() { all_local_java_jars_present() { local service artifact_path - for service in gateway auth external other live order wallet console visual-monitor scheduling game-fruit; do + for service in gateway auth external other live order wallet console visual-monitor scheduling; do artifact_path="$(java_artifact_path_for_service "$service")" || return 1 if [ ! -f "$artifact_path" ]; then echo "missing local jar: $artifact_path" >&2 @@ -323,7 +322,6 @@ service_port() { golang) env_key="LIKEI_LOCAL_GOLANG_PORT" ;; external) env_key="LIKEI_LOCAL_EXTERNAL_PORT" ;; visual-monitor) env_key="LIKEI_LOCAL_VISUAL_MONITOR_PORT" ;; - game-fruit) env_key="LIKEI_LOCAL_GAME_FRUIT_PORT" ;; *) return 1 ;; @@ -342,3 +340,29 @@ wait_service_port() { } wait_tcp_port 127.0.0.1 "$port" "$retries" } + +service_health_url() { + local service="$1" + case "$service" in + console) + printf 'http://127.0.0.1:%s/console/actuator/health\n' "$(service_port "$service")" + ;; + golang) + printf 'http://127.0.0.1:%s/health\n' "$(service_port "$service")" + ;; + *) + printf 'http://127.0.0.1:%s/actuator/health\n' "$(service_port "$service")" + ;; + esac +} + +wait_service_health() { + local service="$1" + local retries="${2:-120}" + local url + url="$(service_health_url "$service")" || { + echo "unknown app service health url: $service" >&2 + exit 1 + } + wait_http "$url" "$retries" +} diff --git a/localbox/deploy.sh b/localbox/deploy.sh index cdd081a..6ab8a58 100755 --- a/localbox/deploy.sh +++ b/localbox/deploy.sh @@ -7,7 +7,7 @@ LOCAL_DIR="$ROOT_DIR" usage() { cat <<'EOF' 用法: - ./deploy.sh start [--skip-build] [--infra-only] + ./deploy.sh start [--skip-build] [--infra-only] [--rebuild] ./deploy.sh build [service...] ./deploy.sh restart [--rebuild] ./deploy.sh check diff --git a/localbox/local-services.compose.yml b/localbox/local-services.compose.yml index 1435181..255ad74 100644 --- a/localbox/local-services.compose.yml +++ b/localbox/local-services.compose.yml @@ -320,20 +320,6 @@ services: volumes: - ${LIKEI_LOCAL_JAVA_REPO_DIR:-../../chatapp3/chatapp3-java}/rc-scheduling/target/rc-scheduling-1.0.0-local.jar:/app/app.jar:ro - game-fruit: - <<: *java-service - container_name: chatapp3-local-game-fruit - depends_on: - - nacos - environment: - <<: *java-environment - JAVA_OPTS: ${LIKEI_LOCAL_GAME_FRUIT_JAVA_OPTS:--Xms128m -Xmx384m} - SERVER_PORT: ${LIKEI_LOCAL_GAME_FRUIT_PORT} - ports: - - "${LIKEI_LOCAL_GAME_FRUIT_PORT}:8001" - volumes: - - ${LIKEI_LOCAL_JAVA_REPO_DIR:-../../chatapp3/chatapp3-java}/rc-service-game/game-fruit/target/game-fruit-1.0.0-local.jar:/app/app.jar:ro - golang: <<: *env-file image: golang:1.24 diff --git a/localbox/publish_local_nacos_configs.sh b/localbox/publish_local_nacos_configs.sh index f7e2782..7b6dbe8 100755 --- a/localbox/publish_local_nacos_configs.sh +++ b/localbox/publish_local_nacos_configs.sh @@ -24,6 +24,10 @@ cp -R "$NACOS_SOURCE_DIR/." "$TMP_DIR/" if [ -f "$TMP_DIR/common/external.yml" ]; then cp "$TMP_DIR/common/external.yml" "$TMP_DIR/common/external-config.yml" fi +if [ -f "$TMP_DIR/common/framework-config.yml" ]; then + sed -i.bak '/^[[:space:]]*- game-fruit[[:space:]]*$/d' "$TMP_DIR/common/framework-config.yml" + rm -f "$TMP_DIR/common/framework-config.yml.bak" +fi if [ "$NAMESPACE_ID" != "public" ]; then for _ in $(seq 1 60); do diff --git a/localbox/restart_local_service.sh b/localbox/restart_local_service.sh index e409498..83b79f4 100755 --- a/localbox/restart_local_service.sh +++ b/localbox/restart_local_service.sh @@ -18,7 +18,7 @@ usage() { ./restart_local_service.sh golang 支持的服务: - gateway auth external other live order wallet console visual-monitor scheduling game-fruit golang + gateway auth external other live order wallet console visual-monitor scheduling golang mysql redis mongo nacos zookeeper rocketmq rocketmq-namesrv rocketmq-broker rocketmq-proxy EOF @@ -52,7 +52,7 @@ if [ "$SERVICE" = "rocketmq-proxy" ]; then fi case "$SERVICE" in - gateway|auth|external|other|live|order|wallet|console|visual-monitor|scheduling|game-fruit|golang|mysql|redis|mongo|nacos|zookeeper|rocketmq|rocketmq-namesrv|rocketmq-broker|rocketmq-proxy) + gateway|auth|external|other|live|order|wallet|console|visual-monitor|scheduling|golang|mysql|redis|mongo|nacos|zookeeper|rocketmq|rocketmq-namesrv|rocketmq-broker|rocketmq-proxy) ;; *) echo "unknown service: $SERVICE" >&2 @@ -80,8 +80,8 @@ else fi case "$SERVICE" in - gateway|auth|external|other|live|order|wallet|console|visual-monitor|scheduling|game-fruit|golang) - wait_service_port "$SERVICE" 120 + gateway|auth|external|other|live|order|wallet|console|visual-monitor|scheduling|golang) + wait_service_health "$SERVICE" 180 ;; mysql) wait_container_healthy chatapp3-local-mysql 120 diff --git a/localbox/start_local_services.sh b/localbox/start_local_services.sh index 3f86e30..743805e 100755 --- a/localbox/start_local_services.sh +++ b/localbox/start_local_services.sh @@ -10,6 +10,63 @@ PUBLISH_SCRIPT="$SCRIPT_DIR/publish_local_nacos_configs.sh" SKIP_BUILD=false INFRA_ONLY=false +FORCE_BUILD=false + +PARALLEL_PIDS=() +PARALLEL_LABELS=() + +reset_parallel_jobs() { + PARALLEL_PIDS=() + PARALLEL_LABELS=() +} + +start_parallel_job() { + local label="$1" + shift + + "$@" & + PARALLEL_PIDS+=("$!") + PARALLEL_LABELS+=("$label") +} + +wait_parallel_jobs() { + local failed=0 index + + for index in "${!PARALLEL_PIDS[@]}"; do + if ! wait "${PARALLEL_PIDS[$index]}"; then + echo "parallel wait failed: ${PARALLEL_LABELS[$index]}" >&2 + failed=1 + fi + done + + if [ "$failed" -ne 0 ]; then + exit 1 + fi +} + +wait_infra_ready() { + reset_parallel_jobs + start_parallel_job mysql wait_container_healthy chatapp3-local-mysql 120 + start_parallel_job redis wait_container_healthy chatapp3-local-redis 120 + start_parallel_job mongo wait_container_healthy chatapp3-local-mongo 120 + start_parallel_job nacos wait_http "http://127.0.0.1:${LIKEI_LOCAL_NACOS_PORT}/nacos/" 120 + + if ! local_rocketmq_disabled; then + start_parallel_job rocketmq wait_local_rocketmq + fi + + wait_parallel_jobs +} + +wait_app_services_ready() { + local service + + reset_parallel_jobs + for service in gateway auth other live order wallet console external visual-monitor scheduling golang; do + start_parallel_job "$service" wait_service_health "$service" 180 + done + wait_parallel_jobs +} usage() { cat <<'EOF' @@ -17,6 +74,7 @@ usage() { ./start_local_services.sh ./start_local_services.sh --skip-build ./start_local_services.sh --infra-only + ./start_local_services.sh --rebuild EOF } @@ -28,6 +86,9 @@ while [ "$#" -gt 0 ]; do --infra-only) INFRA_ONLY=true ;; + --rebuild) + FORCE_BUILD=true + ;; -h|--help) usage exit 0 @@ -45,44 +106,41 @@ load_local_env wait_for_docker if [ "$SKIP_BUILD" = false ] && [ "$INFRA_ONLY" = false ]; then - java_major="$(java_major_version || true)" - if [ "$java_major" = "17" ]; then - "$BUILD_SCRIPT" - else - if all_local_java_jars_present; then - echo "detected Java ${java_major:-unknown}; local rebuild requires JDK 17" >&2 - echo "to intentionally reuse the current jars, rerun ./start_local_services.sh --skip-build" >&2 + if [ "$FORCE_BUILD" = true ] || ! all_local_java_jars_present; then + java_major="$(java_major_version || true)" + if [ "$java_major" = "17" ]; then + "$BUILD_SCRIPT" else - echo "local Java jars are missing and the current machine is not using JDK 17" >&2 - echo "please switch to JDK 17 and rerun ./start_local_services.sh, or prebuild the jars first" >&2 + if [ "$FORCE_BUILD" = true ]; then + echo "rebuilding local Java services requires JDK 17; current java major version is ${java_major:-unknown}" >&2 + else + echo "local Java jars are missing and the current machine is not using JDK 17" >&2 + echo "please switch to JDK 17 and rerun ./start_local_services.sh, or prebuild the jars first" >&2 + fi + exit 1 fi - exit 1 + else + echo "local Java jars already exist; skipping build" fi fi -compose up -d mysql redis mongo nacos zookeeper +compose up -d --remove-orphans mysql redis mongo nacos zookeeper if ! local_rocketmq_disabled; then compose up -d --remove-orphans rocketmq-namesrv rocketmq-init rocketmq-broker rocketmq-proxy fi -wait_container_healthy chatapp3-local-mysql 120 -wait_container_healthy chatapp3-local-redis 120 -wait_container_healthy chatapp3-local-mongo 120 -echo "waiting for nacos..." +echo "waiting for local infra..." require_env LIKEI_LOCAL_NACOS_PORT -wait_http "http://127.0.0.1:${LIKEI_LOCAL_NACOS_PORT}/nacos/" 120 -wait_local_rocketmq +wait_infra_ready "$PUBLISH_SCRIPT" if [ "$INFRA_ONLY" = false ]; then - compose up -d --force-recreate \ - gateway auth external other live order wallet console visual-monitor scheduling game-fruit golang + compose up -d --remove-orphans --force-recreate \ + gateway auth external other live order wallet console visual-monitor scheduling golang - for service in gateway auth other live order wallet console external visual-monitor scheduling game-fruit golang; do - wait_service_port "$service" 120 - done + wait_app_services_ready fi compose ps