Golang中遇到HTTP2接收GOAWAY帧时如何实现优雅关闭
Golang中遇到HTTP2接收GOAWAY帧时如何实现优雅关闭 你好,我使用 Go 的 net/http 包构建了一个 Web 应用程序。有时服务器会返回错误“http2: received GOAWAY [FrameHeader GOAWAY len=8], starting graceful shutdown”。我该如何修复它?
1 回复
更多关于Golang中遇到HTTP2接收GOAWAY帧时如何实现优雅关闭的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中处理HTTP/2 GOAWAY帧的优雅关闭,可以通过配置http.Server的IdleTimeout和实现连接状态监控来实现。当收到GOAWAY帧时,服务器会开始优雅关闭空闲连接,但不会中断活跃请求。以下是一个示例实现:
package main
import (
"context"
"fmt"
"net/http"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(100 * time.Millisecond) // 模拟处理时间
w.Write([]byte("Hello, World!"))
})
server := &http.Server{
Addr: ":8080",
Handler: mux,
IdleTimeout: 120 * time.Second, // 空闲连接超时时间
ReadTimeout: 10 * time.Second, // 读取超时
WriteTimeout: 10 * time.Second, // 写入超时
}
// 启动服务器
go func() {
if err := server.ListenAndServeTLS("cert.pem", "key.pem"); err != nil && err != http.ErrServerClosed {
fmt.Printf("Server error: %v\n", err)
}
}()
// 模拟收到GOAWAY信号后的优雅关闭
time.Sleep(30 * time.Second) // 运行30秒后触发关闭
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
fmt.Printf("Graceful shutdown failed: %v\n", err)
}
fmt.Println("Server gracefully stopped")
}
对于客户端连接,可以配置http.Transport来更好地处理GOAWAY:
func createHTTP2Client() *http.Client {
tr := &http.Transport{
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
// 启用HTTP/2
ForceAttemptHTTP2: true,
}
return &http.Client{
Transport: tr,
Timeout: 30 * time.Second,
}
}
在服务器端,可以通过监控连接状态来记录GOAWAY事件:
type connStateLogger struct{}
func (csl *connStateLogger) logState(conn net.Conn, state http.ConnState) {
switch state {
case http.StateIdle:
// 记录空闲连接
case http.StateActive:
// 记录活跃连接
case http.StateHijacked, http.StateClosed:
// 记录连接关闭
}
}
func main() {
server := &http.Server{
Addr: ":8080",
ConnState: func(conn net.Conn, state http.ConnState) {
// 记录连接状态变化
fmt.Printf("Connection %s changed to %v\n", conn.RemoteAddr(), state)
},
}
}
GOAWAY帧是HTTP/2协议的正常部分,用于连接关闭前的通知。上述配置允许服务器在收到GOAWAY后完成正在处理的请求,同时拒绝新连接。

