你出错的原因
context deadline exceeded
是因为
context.Context
请求的客户端比服务器端处理程序中的超时时间短。这意味着
上下文。上下文
因此客户方
http.DefaultClient
在写任何回应之前放弃。
这个
panic: runtime error: invalid memory address...
是因为您延迟关闭响应的主体,但响应是
nil
如果客户端返回错误。
这里的响应为零,如果错误为非零,则更改
t.Error
到
t.Fatal
resp, err := http.DefaultClient.Do(req.WithContext(ctx))
if err != nil {
// this should be t.Fatal, or don't do the body close if there's an error
t.Error("Response error", err)
}
defer resp.Body.Close()
找到问题的真正根源,
http.StatusGatewayTimeout
是服务器端超时,这意味着创建的任何超时都必须在服务器端。客户
默认客户端
永远不会创建自己的服务器错误响应代码。
要创建服务器端超时,可以将处理程序函数包装在
http.TimeoutHandler
:
handlerFunc := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
d := map[string]interface{}{
"id": "12",
"scope": "test-scope",
}
time.Sleep(100 * time.Millisecond)
e := json.NewEncoder(w)
err := e.Encode(&d)
if err != nil {
t.Error(err)
}
w.WriteHeader(http.StatusOK)
})
backend := httptest.NewServer(http.TimeoutHandler(handlerFunc, 20*time.Millisecond, "server timeout"))
但是,这将创建一个
503 - Service Unavailable
错误响应代码。
了解504的重要一点是,这是一个“网关”或“代理”错误响应代码。这意味着这段代码不太可能来自实际处理请求的服务器。这个代码在负载平衡器和代理中更常见。
504网关超时
服务器在充当网关或代理时,没有收到上游服务器的及时响应,该服务器需要访问才能完成请求。
你已经嘲笑了
http.Server
在试验方法中使用
httptest.NewServer(...)
所以你可以手动返回
http.statusgateway超时
处理程序函数中的响应状态。
handlerFunc := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusGatewayTimeout)
})
backend := httptest.NewServer(handlerFunc)