MST

星途 面试题库

面试题:Go中Context在HTTP服务器中的常见用法

在Go的HTTP服务器编程中,Context是如何被用于处理请求的取消和超时的?请举例说明其实现方式。
22.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go的HTTP服务器编程中,Context 用于处理请求的取消和超时。Context 是一个携带截止时间、取消信号以及请求作用域内值的对象。

  1. 处理请求取消: 当客户端关闭连接或者中间件主动取消请求时,Context 能够感知到并进行相应处理。 示例代码如下:
package main

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

func handler(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    // 模拟一个耗时操作
    select {
    case <-ctx.Done():
        err := ctx.Err()
        fmt.Fprintf(w, "Request cancelled: %v", err)
        return
    default:
        // 实际业务逻辑
        fmt.Fprintf(w, "Request is being processed")
    }
}

func main() {
    http.HandleFunc("/", handler)
    fmt.Println("Server listening on :8080")
    http.ListenAndServe(":8080", nil)
}

在上述代码中,r.Context() 获取当前请求的 Context,通过 select 监听 ctx.Done() 通道,若该通道接收到信号,表示请求被取消,程序可以执行相应的清理操作并返回。

  1. 处理请求超时: 可以通过 context.WithTimeout 创建带有超时的 Context,在指定时间内未完成处理,则取消请求。 示例代码如下:
package main

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

func handler(w http.ResponseWriter, r *http.Request) {
    ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
    defer cancel()

    // 模拟一个可能超时的操作
    select {
    case <-ctx.Done():
        err := ctx.Err()
        fmt.Fprintf(w, "Request timed out: %v", err)
        return
    case <-time.After(3 * time.Second):
        fmt.Fprintf(w, "Request completed")
    }
}

func main() {
    http.HandleFunc("/", handler)
    fmt.Println("Server listening on :8080")
    http.ListenAndServe(":8080", nil)
}

在这个例子中,context.WithTimeout 创建了一个 Context,其超时时间为2秒。如果操作在2秒内未完成(这里模拟为 time.After(3 * time.Second)),ctx.Done() 通道将接收到信号,从而判断请求超时并进行相应处理。