iris.run 默认支持优雅关闭,因其内置信号处理器在收到 sigint/sigterm 时自动执行停止新连接、等待请求完成(默认30秒)、再退出;禁用中断处理需手动调用 srv.shutdown 并控制超时。

为什么 iris.Run 默认就能优雅关闭
因为 iris.Run 内部已注册了系统信号处理器,收到 SIGINT(Ctrl+C)或 SIGTERM 时会触发 graceful shutdown 流程:停止接受新连接、等待已有请求完成(默认 30 秒超时)、再退出。你不需要手动调用 http.Server.Shutdown —— 只要没禁用中断处理,它就自动生效。
DisableInterruptHandler = true 时必须自己处理
如果你在配置中显式设置了 DisableInterruptHandler: true,那 iris.Run 就不会再监听信号,关机逻辑完全交由你控制。常见于容器环境或需要自定义退出前清理动作的场景。
此时必须手动调用 srv.Shutdown,且需确保拿到的是底层 *http.Server 实例:
app := iris.New()
// ... 注册路由等
srv := &http.Server{
Addr: ":8080",
Handler: app,
}
go func() {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
app.Logger().Errorf("server error: %v", err)
}
}()
// 收到 SIGINT 后手动关
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<h3>自定义超时时间与等待行为</h3>
<p>默认 30 秒可能不够(比如长轮询或大文件上传),也可能太长(想快速重启)。关键点在于:超时由 <code>context.WithTimeout</code> 控制,不是 Iris 配置项。</p>
- 使用
iris.Server(srv)启动时,srv.ReadTimeout/srv.WriteTimeout影响单个请求,不影响 shutdown 等待时长 - 真正控制“最多等多久”的是传给
srv.Shutdown的 context,例如context.WithTimeout(context.Background(), 5*time.Second) -
DisableInterruptHandler: true+ 手动 shutdown 是唯一能精确控制超时的方式
热重载(如 rizla)下关闭行为容易被忽略
用 rizla 或其他热重载工具时,每次代码变更都会 kill 旧进程、启动新进程。如果旧进程没正确 shutdown,可能出现端口占用、数据库连接泄漏、未完成事务回滚失败等问题。
务必确认:你的 main 函数里没有提前 os.Exit(0),也没有在 app.Use 中 panic 后未 recover——这些都会跳过 graceful shutdown 流程。











