服务端设置超时时间
在这小节,您将学习如何在服务端超时连接。您需要这样做,因为有时客户端结束 HTTP 连接的时间比预期的要长得多。这通常由于俩个原因而发生:第一个原因是客户端软件有 bug,第二个原因是服务进程正经历攻击!
在 serverTimeOut.go
源码文件中实现了这个技巧,并分四部分介绍。
serverTimeOut.go
的第一部分如下:
package main
import (
"fmt"
"net/http"
"os"
"time"
)
func myHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Serving: %s\n", r.URL.Path)
fmt.Fprintf("Served: %s\n", r.Host)
}
serverTimeOut.go
的第二部分代码如下:
func timeHandler(w http.ResponseWriter, r *http.Request) {
t := time.Now().Format(time.RFC1123)
Body := "The current time is:"
fmt.Fprintf(w, "<h1 align=\"center\">%s</h1>", Body)
fmt.Fprintf(w, "<h2 align=\"center\">%s</h2>n", t)
fmt.Fprintf(w, "Serving: %s\n", r.URL.Path)
fmt.Printf("Served time for :%s\n", r.Host)
}
serverTimeOut.go
的第三段代码如下:
func main() {
PORT := ":8001"
arguments := os.Args
if len(arguments) == 1 {
fmt.Printf("Listening on http://0.0.0.0%s\n", PORT)
} else {
PORT = ":" + arguments[1]
fmt.Printf("Listening on http://0.0.0.0%s\n", PORT)
}
m := http.NewServeMux()
srv := &http.Server {
Addr: PORT,
Handler: m,
ReadTimeout: 3 * time.Second,
WriteTimeout: 3 * time.Second,
}
在这个例子中,我们使用 http.Server
结构, 它的字段支持两类超时。第一个叫 ReadTimeout
,第二个叫 WriteTimeout
。ReadTimeout
字段的值定义读取整个请求,包括消息体的最大持续时间。
WriteTimeout
字段的值定义超时写入响应之前的最大持续时间。简单说,这是从请求头读取结束到响应写入结束的时间。
serverTimeOut.go
的剩余代码如下:
m.HandleFunc("/time". timeHandler)
m.HandleFunc("/", myHandler)
err := srv.ListenAndServe()
if err != nil {
fmt.Println(err)
return
}
}
我们现在执行 serverTimeOut.go
,使用 nc(1)
与之交互。
$ go run serverTimeOut.go
Listening on http://0.0.0.0:8001
在 nc(1)
部分(在这个例子中作为一个虚拟 HTTP 客户端),您应该发出下一个命令来连接到 serverTimeOut.go
:
$ time nc localhost 8001
real 0m3.012s
user 0m0.001s
sys 0m0.002s
由于我们没有发出任何命令,HTTP 服务器结束了连接。time(1)
程序的输出验证了服务器关闭连接所用时间。