MST

星途 面试题库

面试题:Go中Context在HTTP服务器场景的应用

在Go语言的HTTP服务器编程中,如何正确使用Context来处理请求的取消和超时?请举例说明。
10.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言的HTTP服务器编程中,context包用于处理请求的取消和超时。以下是一个示例说明:

package main

import (
    "context"
    "fmt"
    "net/http"
    "time"
)

func slowHandler(w http.ResponseWriter, r *http.Request) {
    // 获取请求的上下文
    ctx := r.Context()

    // 设置一个模拟的长时间运行的任务
    select {
    case <-time.After(5 * time.Second):
        fmt.Fprintf(w, "任务完成")
    case <-ctx.Done():
        // 如果上下文被取消(例如请求超时),返回错误
        err := ctx.Err()
        fmt.Fprintf(w, "请求被取消: %v", err)
    }
}

func main() {
    http.HandleFunc("/slow", slowHandler)

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

    // 启动服务器并设置超时
    go func() {
        err := server.ListenAndServe()
        if err != nil && err != http.ErrServerClosed {
            fmt.Printf("服务器启动失败: %v\n", err)
        }
    }()

    // 模拟在一段时间后关闭服务器
    time.Sleep(10 * time.Second)
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    err := server.Shutdown(ctx)
    if err != nil {
        fmt.Printf("服务器关闭失败: %v\n", err)
    }
}

在上述示例中:

  1. slowHandler函数通过r.Context()获取请求的上下文。
  2. 使用select语句监听time.Afterctx.Done()通道。如果ctx.Done()通道接收到信号,说明请求被取消(可能是超时),程序会返回相应的错误信息。
  3. main函数中,启动HTTP服务器,并在一段时间后使用context.WithTimeout设置一个超时的上下文来关闭服务器,以模拟请求超时的场景。

这样就正确地使用了context来处理请求的取消和超时。