You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Makefile执行常驻命令阻塞 如何并行启动多服务后运行客户端

问题根因

原有Makefile无法按预期运行有两个核心原因:

  • Make默认串行执行依赖目标,会等前一个目标的命令完全执行退出后才会运行下一个目标,而Envoy、Go服务都是常驻前台的进程,启动后不会主动退出,执行到envoy目标时就会永久卡住,根本不会走到后续服务启动逻辑。
  • 所有服务都以前台模式运行,Make会阻塞等待当前命令的进程生命周期结束,不具备并行运行的基础。
修改方案

需要做三处调整:

  1. 把所有常驻服务进程放到后台运行,不阻塞Make的执行流,同时把服务日志重定向到独立文件,避免输出混乱
  2. 开启Make的并行执行能力,让Envoy和3台Go服务可以同时启动,不需要串行等待
  3. 增加服务就绪等待逻辑,确保所有服务启动完成后再拉起客户端,避免客户端提前启动连接失败

修改后的完整Makefile如下:

LOG_DIR := ./logs
.PHONY: envoy server1 server2 server3 loadbalancer stop

# 初始化日志目录
$(LOG_DIR):
	mkdir -p $(LOG_DIR)

# 后台启动Envoy,日志输出到logs目录
envoy: | $(LOG_DIR)
	envoy -c envoy.yaml > $(LOG_DIR)/envoy.log 2>&1 &

# 后台启动3台Go服务,日志分别输出到对应文件
server1: | $(LOG_DIR)
	go run ./server1/main.go > $(LOG_DIR)/server1.log 2>&1 &
server2: | $(LOG_DIR)
	go run ./server2/main.go > $(LOG_DIR)/server2.log 2>&1 &
server3: | $(LOG_DIR)
	go run ./server3/main.go > $(LOG_DIR)/server3.log 2>&1 &

# 所有服务依赖拉起后,等待就绪再启动客户端
loadbalancer: envoy server1 server2 server3
	@echo "服务启动中,等待初始化完成..."
	@sleep 3 # 可根据服务实际启动速度调整等待时长,也可替换为端口探活逻辑
	go run ./client/main.go

# 辅助目标:一键停止所有后台启动的服务,避免残留进程占用端口
stop:
	pkill -f "envoy -c envoy.yaml" || true
	pkill -f "go run ./server1/main.go" || true
	pkill -f "go run ./server2/main.go" || true
	pkill -f "go run ./server3/main.go" || true
使用方式

启动完整流程时执行带并行参数的make命令,指定最多并行4个任务(刚好匹配4个需要同时启动的服务):

make -j4 loadbalancer

需要停止所有后台服务时执行:

make stop
补充说明
  • 命令末尾的&是Shell后台运行语法,会把进程放到后台执行,Make不需要等待进程退出就会继续推进后续流程
  • 2>&1是把标准错误输出重定向到标准输出,统一写入日志文件,方便排查问题
  • 如果你不想用固定sleep等待,可以把sleep替换成端口探活逻辑,比如循环检测对应服务的监听端口是否可用,确认全部就绪后再启动客户端,可靠性更高
  • 所有服务的日志都存在./logs目录下,出问题可以直接查看对应文件定位原因

内容的提问来源于stack exchange,提问作者Chris G.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 05:45:06