Go-Zero服务启动失败“address already in use”本质是端口被占或etcd配置缺失;需先提取报错端口号,用lsof/netstat查PID并kill释放,再检查etcd host配置及YAML缩进与字段tag小写是否合规。

Go-Zero服务启动失败,控制台打印“address already in use”或静默卡在初始化阶段,本质不是代码缺陷,而是端口被占或关键配置项缺失导致服务无法完成绑定或注册。
排查端口占用:快速定位并释放冲突进程
第一步:从报错日志里提取真实端口号。例如看到 listen tcp :8080: bind: address already in use,目标就是 【8080】。
第二步:Linux/macOS 执行 lsof -i :8080;若提示 command not found,macOS 用 brew install lsof,Ubuntu/Debian 用 sudo apt install net-tools 补齐依赖。
第三步:Windows 执行 netstat -ano | findstr :8080,输出中找 PID 列的数字——注意,它可能出现在倒数第二列,别错当成最后一列的端口号。
第四步:杀掉对应进程。Linux/macOS 运行 kill -9 12345(把 12345 换成你查到的 PID);Windows 运行 taskkill /F /PID 12345。这一步做完,端口就空出来了。
检查 etcd 配置缺失:RPC 服务卡住不报错的元凶
go-zero 的 RPC 服务默认依赖 etcd 做服务注册,但配置缺失时不会报错,只会让服务启动后“假死”——日志停在 starting rpc server... 再无下文。
方法一:确认本地 etcd 是否真在运行。执行 docker ps | grep etcd,没输出就说明没跑起来。用这条命令拉起:docker run -d -p 2379:2379 --name etcd quay.io/coreos/etcd:v3.5.15 --advertise-client-urls http://0.0.0.0:2379 --listen-client-urls http://0.0.0.0:2379。
方法二:检查 etc/user.yaml(文件名以你项目为准)里是否有完整 etcd 配置块,必须包含 host 字段且值为可连通地址:etcd:。【不能只写 etcd: {} 或直接删掉整段】
host: 127.0.0.1:2379
方法三:临时绕过 etcd 调试。把 conf.MustLoad("etc/user.yaml") 替换为手动构造 config 结构体,跳过 etcd 初始化逻辑——但这仅限本地验证,上线前必须切回原逻辑。
验证 YAML 配置加载是否成功
go-zero 启动时读一次 YAML,读不到或格式错就直接 os.Exit(1),但错误信息极简,常被忽略。
打开你的 etc/user.yaml,逐行核对缩进:OSS、Redis 等嵌套块下的字段必须比父级多缩进至少两个空格,不能用 Tab 混插,也不能少一个空格——YAML 解析器对这个极其敏感。
检查配置结构体字段 tag 是否全小写。比如 Etcd string `json:"Etcd"` 是错的,必须写成 Etcd string `json:"etcd"`,否则字段永远绑定不上。
运行前加一句调试输出:fmt.Printf("Loaded config: %+v\n", c)(c 是你 conf.Load 返回的结构体变量),如果打印出来全是零值,说明配置根本没加载成功。











