iris超时配置必须通过configurehost设置,run或listen不支持直接传入;read/write/idletimeout需在su.server上显式赋值,且仅对新连接生效。

超时配置必须通过 ConfigureHost 设置,Run 或 Listen 不接受超时参数
直接在 app.Run(iris.Addr(":8080")) 里加超时参数是无效的——Iris 的 HTTP Server 超时控制不走配置选项,而是绑定在底层 *http.Server 实例上。必须用 ConfigureHost 显式修改 su.Server 字段。
常见错误现象:调用 ctx.StatusCode(408) 或手动 sleep 后返回,误以为是“超时处理”,其实这只是业务层模拟;真实连接级超时(如客户端断连、读写卡住)根本不会触发你的 handler。
-
su.Server.ReadTimeout:从连接建立到请求头读完的最长等待时间(含 TLS 握手) -
su.Server.WriteTimeout:从响应开始写入到全部写完的最长耗时(不含 handler 执行时间) -
su.Server.IdleTimeout:HTTP/1.1 持久连接空闲时长,超时后主动关闭(推荐设为 60s)
示例:
app.ConfigureHost(func(su *iris.Supervisor) {
su.Server.ReadTimeout = 5 * time.Second
su.Server.WriteTimeout = 10 * time.Second
su.Server.IdleTimeout = 60 * time.Second
})
ctx.Timeout() 和 context.WithTimeout 是两回事
ctx.Timeout() 是 Iris 提供的便捷方法,它只是从当前请求上下文里提取已设置的 time.Time 截止时间(比如由中间件注入),本身不创建或启动任何定时器。真正起作用的是你手动用 context.WithTimeout 包裹下游调用。
典型使用场景:handler 内部调用外部 API 或 DB 查询,需要限制单次操作耗时。
- 不要依赖
ctx.Timeout()来做超时判断——它可能返回零值,尤其在没被上游设置时 - DB 查询超时应交由驱动层控制(如
sql.DB.SetConnMaxLifetime+ 查询 context) - HTTP 客户端调用务必传入带 timeout 的
context.Context,否则会阻塞整个 goroutine
正确写法:
ctx, cancel := context.WithTimeout(app.Context(), 3*time.Second) defer cancel() resp, err := http.DefaultClient.Do(req.WithContext(ctx))
超时发生时,连接会被立即关闭,不会进入 error handler
Iris 的 OnErrorCode(iris.StatusRequestTimeout, ...) 对网络层超时无效。HTTP 状态码 408 Request Timeout 是由客户端主动发起的(比如浏览器发了 Expect: 100-continue 但没等回包就断开),而服务端的 ReadTimeout 触发时,底层连接已被 net/http 直接关闭,请求甚至没走到 Iris 路由逻辑。
这意味着你无法在 OnErrorCode 里记录日志、返回自定义 HTML 或写监控指标——这些都发生在应用层,而超时是在 transport 层终结的。
- 想观测超时频率?得监听
http.Server的ErrorLog,过滤包含"read timeout"或"write timeout"的日志行 - 想区分是客户端慢还是服务端慢?需结合
ReadTimeout和WriteTimeout日志 + 应用内埋点(如 handler 开始/结束时间戳) - Graceful Shutdown 期间的超时行为不受影响,
ConfigureHost设置依然生效
高并发下超时配置容易被忽略的副作用
把 ReadTimeout 设得太短(如
Go 的 net/http 默认使用非阻塞 I/O + epoll/kqueue,但每个连接仍需分配 goroutine。当并发请求数激增,调度延迟可能超过你设的 timeout 值。
- 生产环境建议
ReadTimeout≥ 3s,WriteTimeout≥ 10s,再根据压测结果微调 - 如果用
iris.TLS(),TLS 握手耗时也计入ReadTimeout,HTTPS 场景下要预留额外 200–500ms -
IdleTimeout过长(如 > 5min)可能撑爆反向代理(Nginx/ALB)的连接池,引发 502/504
最常被漏掉的一点:超时配置只对新连接生效,已建立的连接不会动态更新。改配置后必须重启服务才生效。











