Go 防止超过上下文截止时间(等待标头时超过Client.Timeout)HTTP 200 OK错误
我有一个客户端和服务器。服务器处理请求的时间超过2秒。但客户并没有这么多时间。它需要在1秒内得到响应。这就是为什么它的反应是 得到“http://localhost:8888“:超出上下文截止日期(等待标头时超出Client.Timeout) 死机:运行时错误:无效内存地址或零指针取消引用 问题? 如何更改server.go以正确恢复所有错误 端点始终可用吗? 注意客户端正在调用的端点应尽快处理请求,并在完成后立即返回200 OK 客户机,开始Go 防止超过上下文截止时间(等待标头时超过Client.Timeout)HTTP 200 OK错误,go,tcp,server-timing,Go,Tcp,Server Timing,我有一个客户端和服务器。服务器处理请求的时间超过2秒。但客户并没有这么多时间。它需要在1秒内得到响应。这就是为什么它的反应是 得到“http://localhost:8888“:超出上下文截止日期(等待标头时超出Client.Timeout) 死机:运行时错误:无效内存地址或零指针取消引用 问题? 如何更改server.go以正确恢复所有错误 端点始终可用吗? 注意客户端正在调用的端点应尽快处理请求,并在完成后立即返回200 OK 客户机,开始 package main import (
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
c := &http.Client{Timeout: 2 * time.Second}
res, err := c.Get("http://localhost:8888")
if err != nil {
log.Println(err)
}
var r []byte
_, err = res.Body.Read(r)
fmt.Println(string(r))
}
server.go
package main
import (
"fmt"
"io"
"net/http"
"time"
)
func slowHandler(w http.ResponseWriter, req *http.Request) {
time.Sleep(2 * time.Second)
io.WriteString(w, "I am slow!\n")
}
func main() {
srv := http.Server{
Addr: ":8888",
Handler: http.HandlerFunc(slowHandler),
}
if err := srv.ListenAndServe(); err != nil {
fmt.Printf("Server failed: %s\n", err)
}
}
您可以通过实施恢复中间件从恐慌中恢复,例如:
defer func(){
如果错误:=recover();错误!=nil{
Println(“从恐慌中恢复”,错误)
fmt.Fprintf(w,“从恐慌中恢复”)
}
}()
您可以使用这篇有用的文章作为指导
编辑
您可以创建自定义中间件来处理自定义处理程序超时
func timeOutMiddleware(下一个http.Handler)http.Handler{
返回http.HandlerFunc(func(w http.ResponseWriter,r*http.Request){
完成:=制作(陈波)
ctx,cancelFunc:=context.WithTimeout(r.context(),time.Second*1)
延迟取消func()
go func(){
next.ServeHTTP(w,r)
结束(完成)
}()
挑选{
case通过实现恢复中间件,您可以从恐慌中恢复,例如:
defer func(){
如果错误:=recover();错误!=nil{
Println(“从恐慌中恢复”,错误)
fmt.Fprintf(w,“从恐慌中恢复”)
}
}()
您可以使用这篇有用的文章作为指导
编辑
您可以创建自定义中间件来处理自定义处理程序超时
func timeOutMiddleware(下一个http.Handler)http.Handler{
返回http.HandlerFunc(func(w http.ResponseWriter,r*http.Request){
完成:=制作(陈波)
ctx,cancelFunc:=context.WithTimeout(r.context(),time.Second*1)
延迟取消func()
go func(){
next.ServeHTTP(w,r)
结束(完成)
}()
挑选{
案例啊,我的错,不是服务器恐慌是客户端,因为您正在读取一个由于超时而产生的nil响应,在您的示例中,客户端从未从服务器获得响应,因此,r是nil和恐慌。现在可以做两件事:-客户端错误处理如果出错,ok:=err.(net.error);ok&&err.timeout(){
-服务器处理程序超时处理程序:http.TimeoutHandler(http.HandlerFunc(slowHandler),1*time.Second,“我超时!\n”),
此服务将返回503,但超时完成后将立即返回。让我们假设此服务是公共服务,它需要不可预测的时间,并且可能有许多客户端。有些客户端可以再分配1秒。在这种情况下,您的代码不起作用,我不确定您所说的是否可能,这是我唯一能想到的about out是在请求中接收一个参数/头,然后根据该参数调整上下文超时,否则您无法知道客户端超时设置是什么。不幸的是,您无法从请求头中获取客户端超时。我的意思是客户端在处理之前需要知道的自定义头/参数,这不是服务器死机king是客户机,因为由于超时,您正在读取一个nil响应,在您的示例中,客户机从未从服务器获得响应,因此,r是nil和panic。现在您可以做两件事:-客户机错误处理如果出错,ok:=err.(net.error);ok&&err.timeout(){
-服务器处理程序超时处理程序:http.TimeoutHandler(http.HandlerFunc(slowHandler),1*time.Second,“我超时!\n”),
此服务将返回503,但超时完成后将立即返回。让我们假设此服务是公共服务,它需要不可预测的时间,并且可能有许多客户端。有些客户端可以再分配1秒。在这种情况下,您的代码不起作用,我不确定您所说的是否可能,这是我唯一能想到的about out是在请求中接收一个参数/头,然后根据该参数调整上下文超时,否则您无法知道客户端超时设置是什么。不幸的是,您无法从请求头获取客户端超时。我指的是客户端需要事先知道的自定义头/参数