直接改r.run()参数可换端口,如r.run(":3000");但硬编码端口不适用于多环境部署,推荐从环境变量(如os.getenv("gin_port"))或配置文件读取并做空值fallback,避免每次部署修改源码。

直接改 r.Run() 的参数就能换端口,不需要动配置文件或环境变量;但硬编码端口在多环境部署时会踩坑。
修改端口最简方式:传字符串给 r.Run()
Gin 默认监听 :8080,调用 r.Run() 时不传参就走默认值。想换端口,直接传带冒号的字符串即可:
-
r.Run(":3000")→ 监听所有网卡的 3000 端口(等价于0.0.0.0:3000) -
r.Run("127.0.0.1:8080")→ 只允许本机访问,不对外暴露 -
r.Run(":80")→ 需要 root 权限(Linux/macOS),生产慎用
注意:r.Run() 必须放在最后,它会阻塞当前 goroutine —— 后面的代码不会执行。
避免硬编码:从环境变量或配置文件读取端口
开发、测试、生产环境端口不同,硬写死在代码里会导致每次部署都要改源码。推荐用 os.Getenv 或结构体解析 JSON 配置:
- 用环境变量:
port := os.Getenv("GIN_PORT"),启动前设GIN_PORT=8081 - 用 JSON 配置(如
config.json):{"Self":{"RouterPort":"2048"}},解析后取cfg.Self.RouterPort - 别忘了类型转换:
strconv.Atoi(portStr),r.Run()只接受字符串,但校验逻辑常需整数
常见错误:环境变量为空时没 fallback,默认值写成 ":8080" 而不是 os.Getenv("GIN_PORT") ?: ":8080",Go 里得手动判空。
多个端口共存:不能靠多次 r.Run(),得用 http.Server 手动启
r.Run() 是封装好的快捷方式,内部只起一个 http.Server。想同时监听 :8080 和 :8081,必须绕过它,自己构造 Server 实例:
- 创建两个
*http.Server,分别绑定不同地址和同一个r.Engine - 用
go server.ListenAndServe()并发启动,否则第二个会阻塞 - 记得处理
http.ErrServerClosed,避免ListenAndServe返回错误被忽略
示例关键行:srv1 := &http.Server{Addr: ":8080", Handler: r},srv2 := &http.Server{Addr: ":8081", Handler: r}。别用 rk-boot 这类第三方方案,除非你真需要它附带的健康检查、中间件自动注入等能力。
端口被占用了怎么办?查进程 + 杀掉或换端口
启动报错 listen tcp :8080: bind: address already in use,说明端口正被占用:
- Linux/macOS:
lsof -i :8080或netstat -tulpn | grep :8080查 PID - Windows:
netstat -ano | findstr :8080,再用taskkill /PID 1234 /F - 更稳妥的做法是:启动前先尝试监听,失败则自动换下一个端口(比如从 8080 试到 8090),适合 CI/CD 场景
注意:Docker 容器内如果用 localhost 做健康检查,宿主机 curl localhost:8080 可能连不上 —— 因为容器里 localhost 指自己,而服务绑的是 0.0.0.0,这个细节容易被忽略。











