Go学习:在开发过程中使用热重载功能
热重载:是指后台进程监控你的源代码变化,然后自动重新编译你的整个应用。 热更新:则是指你只需要重新编译应用的一部分,然后把它注入到已经运行的进程中。
Go 语言支持热重载,但是不支持热更新
在开发过程中,频繁修改代码和重启应用程序是常见的场景,尤其是在Go(Golang)开发中,程序编译速度较快,但手动重启依然会降低开发效率。 为了提升开发体验,Air 工具为Go开发者提供了实时热重载(hot-reload)功能。本文将介绍如何使用 Air 实现 Go 项目的热重载,但不会分析其背后的原理。相关原理可以参考:使用Air实现Go程序实时热重载 - daligh - 博客园
选择air作为go热重载的必须性
Air 是一个专为Go语言设计的实时热重载工具,它简单易用、功能强大,支持多种开发环境,并且性能优异。相比于其他类似工具如 Reflex 或 CompileDaemon,Air 具有以下优势:
速度快:Air 的编译速度非常快,能够在修改后几乎立刻重载程序。 简单配置:Air 允许通过一个简单的配置文件来设置要监控的文件或目录。 跨平台:无论在Windows、Linux还是MacOS上,Air 都能顺利运行。
air重载的步骤是文件监听和重新编译
Air 能够在文件保存后几乎瞬间完成代码的重载,为开发者提供了流畅的开发体验:
文件变更监控:Air 使用文件系统监听(类似于 fsnotify 库)来实时监控项目中的代码文件。当监控的文件(如 .go 文件)发生变更时,Air 会捕获到这一事件。
重新编译:在捕获到文件变更后,Air 会根据 .air.toml 中的配置自动调用 go build 命令,重新编译项目的代码,生成新的可执行文件。
重启应用:一旦新版本的可执行文件编译完成,Air 会停止当前运行的旧进程,并启动新编译的程序,从而实现实时重载效果。
增量优化:Air 在重载过程中,采用了增量编译的方式,只对修改的部分文件进行编译,减少了整体的编译时间,从而提升了重载的速度。
air.toml的基本配置文件
cmd: 运行程序的命令 bin: 编译输出的二进制文件路径 watch_dir: 需要监听的目录或文件 exclude_dir: 排除不需要监听的目录 extensions: 监听的文件扩展名
# .air.toml
# 工作目录
root = "."
tmp_dir = "tmp"
# 需要监控的文件类型
[watch]
extensions = ["go", "tpl", "html", "js"]
# 编译输出的二进制文件路径
[build]
bin = "bin/app"
cmd = "go build -o bin/app main.go"
正确使用air热重载gin程序
ubuntu
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ go version
go version go1.25.5 linux/amd64
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ echo 'export GOPATH=$HOME/go' >> ~/.bashrc
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ echo 'export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin' >> ~/.bashrc
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ source ~/.bashrc
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ go install github.com/cosmtrek/air@latest
go: downloading github.com/cosmtrek/air v1.63.4
go: github.com/cosmtrek/air@latest: version constraints conflict:
github.com/cosmtrek/[email protected]: parsing go.mod:
module declares its path as: github.com/air-verse/air
but was required as: github.com/cosmtrek/air
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ air -v
__ _ ___
/ /\ | | | |_)
/_/--\ |_| |_| \_ v1.63.4, built with Go go1.25.5```
### macos
```shell
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ go install github.com/air-verse/air@latest
go: downloading github.com/air-verse/air v1.63.4
go: downloading github.com/fatih/color v1.18.0
go: downloading dario.cat/mergo v1.0.2
go: downloading github.com/gohugoio/hugo v0.149.1
go: downloading github.com/fsnotify/fsnotify v1.9.0
go: downloading github.com/pelletier/go-toml v1.9.5
go: downloading github.com/mattn/go-colorable v0.1.14
go: downloading github.com/tdewolff/parse/v2 v2.8.3
go: downloading github.com/bep/golibsass v1.2.0
go: downloading github.com/gobwas/glob v0.2.3
go: downloading github.com/bep/godartsass/v2 v2.5.0
go: downloading github.com/spf13/cast v1.9.2
go: downloading github.com/spf13/afero v1.14.0
go: downloading golang.org/x/text v0.28.0
go: downloading google.golang.org/protobuf v1.36.8
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ echo "alias air='~/go/bin/air'" >> ~/.zshrc
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ source ~/.zshrc
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ air -v
__ _ ___
/ /\ | | | |_)
/_/--\ |_| |_| \_ v1.63.4, built with Go go1.25.5
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ air init
__ _ ___
/ /\ | | | |_)
/_/--\ |_| |_| \_ v1.63.4, built with Go go1.25.5
2025/12/20 12:41:16 Failed writing default config: configuration already exists
启动air,监听文件并自动热重载gin
通过别名变量air即可启动程序,并进行热重载监听(^-^)
ctyun@00gcbjih-0OqRgn1nUE:/media/vdb/code/gin-demo$ air
[warning] build.bin is deprecated; set build.entrypoint instead
__ _ ___
/ /\ | | | |_)
/_/--\ |_| |_| \_ v1.63.4, built with Go go1.25.5
watching .
!exclude bin
watching middleware
watching router
watching utils
building...
running...
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET / --> gin-demo/router.InitRouter.func1 (5 handlers)
[GIN-debug] GET /api/health --> gin-demo/router.InitRouter.func2 (5 handlers)
{"file":"main.go:16","func":"main.main","level":"info","msg":"服务启动中,监听端口: 8992","time":"2025-12-20 13:01:14"}
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8992
air配置示例文件如下
# Air 配置文件 - Go 项目热重载工具
# Air 是一个用于 Go 项目的热重载工具,可以在代码修改后自动重新构建和重启应用
# 官方文档: https://github.com/cosmtrek/air
#
# 使用方法:
# 1. 确保已安装: go install github.com/cosmtrek/air@latest
# 2. 在项目根目录运行: air
# 3. 或者指定配置文件: air -c .air.toml
# 根目录配置 - Air 将在此目录及其子目录中监控文件变化
root = "."
# 测试数据目录 - 包含测试所需的数据文件,Air 会监控此目录
testdata_dir = "testdata"
# 临时文件目录 - 存储构建产物和临时文件
# 建议将此目录添加到 .gitignore 中
tmp_dir = "bin"
[build]
# 构建相关配置
# 传递给构建后二进制文件的命令行参数
# 例如: args_bin = ["-port", "8080"]
args_bin = []
# 构建产物的输出路径(相对于项目根目录)
# 建议使用相对路径,便于在不同环境中运行
bin = "./bin/main"
# 构建命令 - 编译 Go 项目
# 可以添加 Go 构建标签: cmd = "go build -tags 'dev' -o ./bin/main ."
cmd = "go build -o ./bin/main"
# 文件变化后的重建延迟(毫秒)
# 建议设置 500-2000ms,避免频繁重建
# 延迟 = 1000
# 排除监控的目录列表 - 这些目录的变化不会触发重建
# 常见排除项:
# - vendor: Go 模块依赖目录
# - node_modules: 前端依赖(如有)
# - .git: Git 目录
# - docs: 文档目录
exclude_dir = ["bin",".git"]
# 排除监控的特定文件列表
# 可以排除特定文件,如配置文件
exclude_file = []
# 使用正则表达式排除文件
# 例如: 排除所有测试文件
exclude_regex = ["_test.go", ".*_test\\.go$"]
# 是否重建未变化的文件
# false: 只重建变化的文件(推荐)
# true: 重建所有文件(较慢)
exclude_unchanged = false
# 是否跟踪符号链接
# false: 不跟踪(推荐,避免循环引用)
# true: 跟踪符号链接
follow_symlink = false
# 完整的二进制文件路径(包含环境变量)
# 高级用法,可以设置环境变量和完整路径
# 例如: full_bin = "APP_ENV=dev ./bin/main"
full_bin = ""
# 额外包含的目录(空数组表示监控所有非排除目录)
# 如果设置了,会只监控这些目录
include_dir = []
# 监控的文件扩展名
# Go 项目通常需要监控: .go, .tmpl, .tpl(模板文件)
# 如果使用前端资源,可能需要: .js, .css, .html
include_ext = ["go", "tpl", "tmpl", "html", "js", "css"]
# 特定包含文件(空数组表示使用 include_ext 配置)
include_file = []
# 发送中断信号后等待进程结束的时间(0 表示立即终止)
# "0s": 立即终止
# "5s": 等待 5 秒后强制终止
kill_delay = "0s"
# 构建错误日志文件
# 建议使用 .log 扩展名,并添加到 .gitignore
log = "build-errors.log"
# 是否使用轮询模式而非文件系统事件
# false: 使用文件系统事件(推荐,更高效)
# true: 使用轮询(适用于网络挂载或其他特殊环境)
poll = false
# 轮询间隔(毫秒)- 仅在 poll=true 时生效
# 推荐设置: 1000-5000ms
poll_interval = 0
# 构建成功后的后处理命令
# 例如: post_cmd = ["echo 'Build completed!'"]
post_cmd = []
# 构建前的预处理命令
# 例如: pre_cmd = ["go mod tidy"]
pre_cmd = []
# 构建成功后是否重新运行二进制文件
# false: 不重新运行(推荐,手动重启)
# true: 自动重启
rerun = true
# 重新运行延迟(毫秒)- 仅在 rerun=true 时生效
rerun_delay =1000
# 是否发送中断信号而非终止信号
# false: 发送终止信号 (SIGTERM)
# true: 发送中断信号 (SIGINT)
send_interrupt = false
# 是否在第一个构建错误时停止
# false: 继续监控文件变化(推荐)
# true: 停止监控
stop_on_error = false
[color]
# 颜色配置 - 终端输出颜色设置
# 应用输出颜色(应用自身的日志和输出)
# 可用颜色: red, green, yellow, blue, magenta, cyan, white, black
# 空字符串表示使用默认颜色
app = ""
# 构建相关输出的颜色(编译信息、错误等)
build = "yellow"
# 主要输出颜色(Air 自身的输出)
main = "magenta"
# 运行器颜色(程序运行状态)
runner = "green"
# 监控器颜色(文件监控相关输出)
watcher = "cyan"
[log]
# 日志配置
# 是否只显示主进程的日志
# false: 显示所有进程的日志
# true: 只显示主进程日志
main_only = false
# 静默模式 - 隐藏除错误外的所有输出
# false: 显示所有输出(推荐)
# true: 只显示错误
silent = false
# 是否在日志中添加时间戳
# false: 不添加时间戳
# true: 添加时间戳(便于调试)
time = false
[misc]
# 其他配置
# 退出时清理临时文件
# false: 保留临时文件(推荐,调试时有用)
# true: 退出时清理临时文件
clean_on_exit = false
[proxy]
# 代理配置 - 当应用运行在代理服务器(如 nginx)后方时使用
# 应用监听的端口
# 0: 自动分配或从环境变量获取
app_port = 0
# 是否启用代理功能
# false: 不启用(推荐,大多数情况下不需要)
enabled = false
# 代理服务器监听的端口
proxy_port = 0
[screen]
# 终端/屏幕配置
# 每次重建后是否清空终端屏幕
# false: 保留输出历史(推荐,便于查看历史信息)
# true: 清空屏幕
clear_on_rebuild = false
# 清空屏幕时是否保持滚动位置
# true: 保持滚动位置(推荐)
# false: 滚动到顶部
keep_scroll = true
# 使用建议:
# 1. 开发 Go Web 应用时,推荐包含模板文件扩展名
# 2. 如果项目较大,可以适当增加 delay 值以避免频繁重建
# 3. 建议将 bin/ 目录添加到 .gitignore 中
# 4. 可以根据需要在 pre_cmd 中添加代码格式化或测试命令
# 5. 使用 colors 配置可以提高开发体验的视觉效果
谢谢关注收藏
⏰ 刚刷到的朋友注意啦!点击【关注】锁定宝藏库,从此升职加薪不迷路 ✨
我的个人博客网站: https://funkygod.vip
📢 腾讯云资源限时福利
有云服务器、CDN、对象存储、网络防护等需求的朋友,欢迎联系下方腾讯云官方销售 👇
轻量云主机限时优惠
RackNerd
☁ 主机显示特惠:只要80元(3TB流量,1vcpu,50GB硬盘),且多区域IDC机房。
购买地址:https://my.racknerd.com/aff.php?aff=14942

CloudCone
CloudCone 特惠轻量云主机:购买地址:https://app.cloudcone.com/?ref=12332


评论区