COMPOSE_SERVICES := mysql redis rocketmq-namesrv rocketmq-broker gateway-service room-service wallet-service user-service activity-service cron-service robot-service game-service notice-service statistics-service GO_RUN_SERVICES := gateway-service room-service wallet-service user-service activity-service cron-service robot-service game-service notice-service statistics-service SERVICE_ALIASES := gs gateway rs room ws wallet us user as activity cs cron robot robots rb game games ns notice stats statistics mq namesrv broker mysql redis rocketmq-namesrv rocketmq-broker gateway-service room-service wallet-service user-service activity-service cron-service robot-service game-service notice-service statistics-service SERVICE_TOKEN := $(firstword $(filter $(SERVICE_ALIASES),$(MAKECMDGOALS))) SERVICE_ID := $(strip $(or $(SERVICE),$(if $(filter gs gateway,$(SERVICE_TOKEN)),gateway-service,$(if $(filter rs room,$(SERVICE_TOKEN)),room-service,$(if $(filter ws wallet,$(SERVICE_TOKEN)),wallet-service,$(if $(filter us user,$(SERVICE_TOKEN)),user-service,$(if $(filter as activity,$(SERVICE_TOKEN)),activity-service,$(if $(filter cs cron,$(SERVICE_TOKEN)),cron-service,$(if $(filter robot robots rb,$(SERVICE_TOKEN)),robot-service,$(if $(filter game games,$(SERVICE_TOKEN)),game-service,$(if $(filter ns notice,$(SERVICE_TOKEN)),notice-service,$(if $(filter stats statistics,$(SERVICE_TOKEN)),statistics-service,$(if $(filter namesrv,$(SERVICE_TOKEN)),rocketmq-namesrv,$(if $(filter mq broker,$(SERVICE_TOKEN)),rocketmq-broker,$(SERVICE_TOKEN))))))))))))))) ADMIN_CONFIG ?= configs/config.yaml DEV_RUN_SERVICES ?= all DEV_RUN_SERVICE_LIST := $(strip $(if $(filter mysql redis,$(SERVICE_ID)),,$(if $(SERVICE_ID),$(SERVICE_ID),$(DEV_RUN_SERVICES)))) .PHONY: proto vet test build run admin admin-up admin-deps admin-bootstrap admin-test admin-build up db-init databi-real-flow-check rebuild restart stop logs ps addr down up-service check-service resolve-compose-conflicts $(SERVICE_ALIASES) # `proto` 负责把独立 api module 内的 .proto 重新生成成 Go 代码。 proto: cd api && protoc \ -I . \ --go_out=. \ --go_opt=paths=source_relative \ --go-grpc_out=. \ --go-grpc_opt=paths=source_relative \ proto/user/v1/user.proto \ proto/user/v1/auth.proto \ proto/user/v1/host.proto \ proto/activity/v1/activity.proto \ proto/room/v1/room.proto \ proto/game/v1/game.proto \ proto/robot/v1/robot.proto \ proto/wallet/v1/wallet.proto \ proto/events/room/v1/events.proto # `vet` 使用当前 Go 工具链检查 workspace 内所有后端模块,升级 Go 版本时先暴露静态风险。 vet: go vet ./... go vet ./api/... go vet ./server/admin/... # `test` 统一跑 workspace 内的 app 后端、api 契约和后台管理服务测试。 test: vet go test ./... go test ./api/... go test ./server/admin/... # `build` 验证 app 后端和后台管理服务命令入口都能编译。 build: go build ./... go build ./server/admin/... # `run` 拉起 MySQL/Redis 后在本机用 go run 启动所有 Go 服务,不做源码监听或热重启。 # 可用 `make run rs`、`make run SERVICE=room-service` 或 `make run DEV_RUN_SERVICES=user-service,gateway-service` 只跑子集。 run: ./scripts/resolve-compose-container-conflicts.sh ./scripts/prepare-local-mysql-initdb.sh ./scripts/prepare-local-rocketmq-config.sh ROCKETMQ_BROKER_CONFIG=./tmp/rocketmq/broker.local.conf docker compose up -d mysql redis rocketmq-namesrv rocketmq-broker ./scripts/apply-local-mysql-initdb.sh ./scripts/apply-local-rocketmq-topics.sh docker compose stop $(GO_RUN_SERVICES) >/dev/null 2>&1 || true ./scripts/print-compose-addresses.sh TZ=UTC go run ./cmd/dev-run -services "$(DEV_RUN_SERVICE_LIST)" # `admin` 在本机直接启动后台管理后端;依赖默认从 server/admin/configs/config.yaml 读取。 # 启动前自动杀掉占用 13100 端口的旧进程,避免 bind: address already in use。 ADMIN_PORT ?= 13100 admin: @pids=$$(lsof -ti tcp:$(ADMIN_PORT)) && [ -n "$$pids" ] && kill -9 $$pids 2>/dev/null || true cd server/admin && go run ./cmd/server -config $(ADMIN_CONFIG) # `admin-up` 先拉起后台本地依赖,再在本机启动后台管理后端。 admin-up: admin-deps admin # `admin-deps` 拉起后台本地运行所需的 MySQL、Redis 和 user-service。 admin-deps: ./scripts/resolve-compose-container-conflicts.sh ./scripts/prepare-local-mysql-initdb.sh docker compose up -d mysql redis ./scripts/apply-local-mysql-initdb.sh ./scripts/apply-local-rocketmq-topics.sh docker compose up --build -d user-service ./scripts/print-compose-addresses.sh # `admin-bootstrap` 显式执行后台初始化种子后启动服务。 admin-bootstrap: @pids=$$(lsof -ti tcp:$(ADMIN_PORT)) && [ -n "$$pids" ] && kill -9 $$pids 2>/dev/null || true cd server/admin && go run ./cmd/server -config $(ADMIN_CONFIG) -bootstrap # `admin-test` 只跑后台管理后端测试。 admin-test: go test ./server/admin/... # `admin-build` 只验证后台管理后端能编译。 admin-build: go build ./server/admin/... # `up` 后台拉起本地服务;带 SERVICE 时只启动单个服务。 # 完整 up 结束后自动启动 admin 前台进程。 up: ./scripts/resolve-compose-container-conflicts.sh ./scripts/prepare-local-mysql-initdb.sh @if [ -z "$(SERVICE_ID)" ]; then \ docker compose up -d mysql redis; \ ./scripts/apply-local-mysql-initdb.sh; \ ./scripts/apply-local-rocketmq-topics.sh; \ docker compose up --build -d gateway-service room-service wallet-service user-service activity-service cron-service robot-service game-service notice-service statistics-service; \ elif [ "$(SERVICE_ID)" = "mysql" ] || [ "$(SERVICE_ID)" = "redis" ]; then \ docker compose up -d $(SERVICE_ID); \ else \ ./scripts/apply-local-mysql-initdb.sh; \ ./scripts/apply-local-rocketmq-topics.sh; \ docker compose up -d $(SERVICE_ID); \ fi ./scripts/print-compose-addresses.sh @if [ -z "$(SERVICE_ID)" ]; then \ $(MAKE) admin; \ fi # `db-init` 对当前 compose MySQL 补齐所有服务 schema 和本地授权。 db-init: ./scripts/resolve-compose-container-conflicts.sh mysql ./scripts/apply-local-mysql-initdb.sh # `databi-real-flow-check` 用真实 owner outbox 重放并审计 Databi 口径;充值允许走本地模拟回调,其余必须先通过真实业务流程产生事实。 databi-real-flow-check: ./scripts/databi-real-flow-check.sh # `rebuild` 重新构建并启动单个本地服务。 rebuild: check-service ./scripts/resolve-compose-container-conflicts.sh ./scripts/prepare-local-mysql-initdb.sh @if [ "$(SERVICE_ID)" != "mysql" ] && [ "$(SERVICE_ID)" != "redis" ]; then \ ./scripts/apply-local-mysql-initdb.sh; \ ./scripts/apply-local-rocketmq-topics.sh; \ fi docker compose up -d --build $(SERVICE_ID) ./scripts/print-compose-addresses.sh # `restart` 重启单个本地服务。 restart: check-service docker compose restart $(SERVICE_ID) # `stop` 停止单个本地服务。 stop: check-service docker compose stop $(SERVICE_ID) # `logs` 查看日志;带 SERVICE 时只看单个服务。 logs: @if [ -z "$(SERVICE_ID)" ]; then \ docker compose logs -f; \ else \ docker compose logs -f --tail=200 $(SERVICE_ID); \ fi # `ps` 查看状态;带 SERVICE 时只看单个服务。 ps: @if [ -z "$(SERVICE_ID)" ]; then \ docker compose ps; \ else \ docker compose ps $(SERVICE_ID); \ fi # `addr` 打印本地和 Docker 内网访问地址。 addr: ./scripts/print-compose-addresses.sh # `down` 停止并清理本地 compose 服务。 down: docker compose down # `check-service` 校验单服务部署目标的 SERVICE 参数。 check-service: @if [ -z "$(SERVICE_ID)" ]; then \ echo "Service is required. Example: make restart rs"; \ echo "Aliases: gs/gateway rs/room ws/wallet us/user as/activity cs/cron game/games ns/notice mysql redis"; \ echo "Services: $(COMPOSE_SERVICES)"; \ exit 1; \ fi @if ! printf '%s\n' $(COMPOSE_SERVICES) | grep -qx "$(SERVICE_ID)"; then \ echo "Unknown service: $(SERVICE_ID)"; \ echo "Aliases: gs/gateway rs/room ws/wallet us/user as/activity cs/cron game/games ns/notice mysql redis"; \ echo "Services: $(COMPOSE_SERVICES)"; \ exit 1; \ fi # `resolve-compose-conflicts` 清理旧 compose 项目遗留的固定容器名占用。 resolve-compose-conflicts: ./scripts/resolve-compose-container-conflicts.sh # `up-service` 是 `up SERVICE=...` 的内部实现。 up-service: check-service ./scripts/resolve-compose-container-conflicts.sh ./scripts/prepare-local-mysql-initdb.sh @if [ "$(SERVICE_ID)" != "mysql" ] && [ "$(SERVICE_ID)" != "redis" ]; then \ ./scripts/apply-local-mysql-initdb.sh; \ ./scripts/apply-local-rocketmq-topics.sh; \ fi docker compose up -d $(SERVICE_ID) ./scripts/print-compose-addresses.sh # 服务别名只用于 `make restart rs` 这类第二参数,不执行动作。 $(SERVICE_ALIASES): @: