面试题答案
一键面试在Go的HTTP服务器编程中,Context
用于处理请求的取消和超时。Context
是一个携带截止时间、取消信号以及请求作用域内值的对象。
- 处理请求取消:
当客户端关闭连接或者中间件主动取消请求时,
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()
通道,若该通道接收到信号,表示请求被取消,程序可以执行相应的清理操作并返回。
- 处理请求超时:
可以通过
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()
通道将接收到信号,从而判断请求超时并进行相应处理。