通八洲科技

如何优化Golang Web性能_Golang HTTP服务器性能提升方法

日期:2026-01-02 00:00 / 作者:P粉602998670
必须显式配置 http.Server 的 ReadTimeout 和 WriteTimeout 防止 goroutine 堆积;ReadTimeout 控制读请求头和体超时(建议 5s),WriteTimeout 控制写响应总耗时(建议 10s),并推荐设置 IdleTimeout 防长连接滥用。

http.ServerReadTimeoutWriteTimeout 防止连接拖垮服务

Go 默认不设超时,一个慢客户端或网络抖动就可能让 goroutine 堆积、内存暴涨。必须显式配置读写超时,而不是依赖反向代理(如 Nginx)的超时设置——后者只管转发层,Go 服务内部仍会持续等待。

server := &http.Server{
    Addr:         ":8080",
    Handler:      mux,
    ReadTimeout:  5 * time.Second,
    WriteTimeout: 10 * time.Second,
    IdleTimeout:  30 * time.Second, // 推荐同时设 IdleTimeout 防长连接滥用
}

禁用默认 http.DefaultServeMux,用 http.ServeMux 或第三方路由器时注意并发安全

直接用 http.HandleFunc 会注册到全局 http.DefaultServeMux,它底层是 map + sync.RWMutex,高并发下锁争用明显。更严重的是,它不支持路径参数、中间件链、HTTP 方法精确匹配,容易写出低效甚至错误的路由逻辑。

响应体压缩用 gzip.Handler 要谨慎:只对文本类内容启用

盲目套一层 gzip.NewHandler 看似简单,实则可能降低性能:压缩本身吃 CPU,而小响应(

数据库查询别用 database/sqlQueryRow 直接扫全表

很多新手写 db.QueryRow("SELECT * FROM users WHERE id = ?", id),看似没问题,但 * 会让数据库返回所有字段,网络传输、内存分配、GC 压力都上升;更糟的是没加 WHERE 索引或写成 SELECT * FROM logs,直接拖垮整个服务。

实际压测中,去掉 SELECT * 和补上索引,QPS 常提升 3~5 倍;而一个没设 WriteTimeout 的服务,在慢日志场景下可能 2 分钟内耗尽 65535 个文件描述符。这些点不难改,但上线前常被跳过。