http server优雅关闭的行为

友情提示:该结论当前只在Golang http server上测试过,其他语言编写的http server可以参考测试方法进行验证。

测试:

  1. 使用golang写一个支持优雅关闭的http server,示例代码如下:
package main

import (
    "context"
    "fmt"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

// handler 处理 HTTP 请求
func handler(w http.ResponseWriter, r *http.Request) {
    time.Sleep(20 * time.Second)
    fmt.Fprintf(w, "Hello, World!")
}

func main() {
    // 创建 HTTP 服务器
    mux := http.NewServeMux()
    mux.HandleFunc("/", handler)

    server := &http.Server{
        Addr:    ":8080",
        Handler: mux,
    }

    // 创建一个通道来监听系统信号
    stop := make(chan os.Signal, 1)
    signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)

    // 启动服务器
    go func() {
        fmt.Println("Server is running on :8080")
        if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            fmt.Printf("ListenAndServe error: %v\n", err)
        }
    }()

    // 阻塞等待系统信号
    <-stop
    fmt.Println("Shutting down server...")

    // 创建超时上下文用于关闭服务器
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    if err := server.Shutdown(ctx); err != nil {
        fmt.Printf("Server forced to shutdown: %v\n", err)
    } else {
        fmt.Println("Server exited properly")
    }
}
  1. 使用http客户端请求http://127.0.0.1:8080,客户端不限,比如:curl、telnet、浏览器等等
  2. 使用wireshark抓包,查看服务端与客户端之间的通信

结论:

  1. [http-client-1] 如果在http server Shutdown之前发起的请求,http server会继续处理,如果在timeout时间内处理完成则正常响应(图中未给出),如果timeout时间内还未处理完成则http server强制使用FIN终止连接,应用层的表现,以curl工具为例:
$ curl -v http://127.0.0.1:8080/
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
* Empty reply from server
* Closing connection
curl: (52) Empty reply from server
  1. [http-client-2] 如果客户端在http server Shutdown过程中发起请求,则http server不会处理该请求,直接以RST包终止连接,应用层的表现,以curl工具为例:
$ curl -v http://127.0.0.1:8080/
*   Trying 127.0.0.1:8080...
* connect to 127.0.0.1 port 8080 from 127.0.0.1 port 61852 failed: Connection refused
* Failed to connect to 127.0.0.1 port 8080 after 0 ms: Couldn't connect to server
* Closing connection
curl: (7) Failed to connect to 127.0.0.1 port 8080 after 0 ms: Couldn't connect to server
  1. [http-client-3] 如果客户端在http server Shutdown之前建立了连接,但是在Shutdown之前没有发起http请求或者所有请求都已经完成,那么http server会立即使用FIN包终止该连接。也就是说http server Shutdown时,会关闭空闲连接

时序图:更清晰的展示http server优雅关闭的过程和行为

image.png

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容