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