MST

星途 面试题库

面试题:Go语言中context如何在HTTP服务中传递上下文

在Go语言开发的HTTP服务中,通常会使用context来管理请求的上下文。请描述一下如何将context从HTTP请求的入口传递到后续的业务处理函数中,并且在处理过程中利用context进行超时控制。请给出具体的代码示例。
32.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言中,将context从HTTP请求的入口传递到后续业务处理函数并进行超时控制,可以参考以下代码示例:

package main

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

// 模拟业务处理函数
func businessLogic(ctx context.Context) error {
    select {
    case <-time.After(2 * time.Second): // 模拟业务处理耗时2秒
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

func handler(w http.ResponseWriter, r *http.Request) {
    // 创建带有超时的context
    ctx, cancel := context.WithTimeout(r.Context(), 1*time.Second)
    defer cancel()

    err := businessLogic(ctx)
    if err != nil {
        if err == context.DeadlineExceeded {
            http.Error(w, "请求超时", http.StatusGatewayTimeout)
        } else {
            http.Error(w, "业务处理错误", http.StatusInternalServerError)
        }
        return
    }
    fmt.Fprintf(w, "业务处理成功")
}

func main() {
    http.HandleFunc("/", handler)
    fmt.Println("Server is listening on :8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Println("Server failed to start: ", err)
    }
}

在上述代码中:

  1. handler函数通过context.WithTimeout创建了一个带有1秒超时的context,同时获取到取消函数cancel,在函数结束时调用cancel以防止资源泄漏。
  2. businessLogic函数通过select语句监听ctx.Done()通道,当ctx被取消(超时或手动取消)时,ctx.Done()通道会被关闭,从而可以处理超时逻辑。
  3. handler函数中,调用businessLogic并检查错误,如果是超时错误context.DeadlineExceeded,则返回http.StatusGatewayTimeout状态码。如果是其他错误,返回http.StatusInternalServerError状态码。