http.ListenAndServe(*http_addr, handle),如何设置keep-alive的时间?

http.ListenAndServe(*http_addr, handle),如何设置keep-alive的时间?

因为不访问网站了,但浏览器跟网站的连接还没有释放,要过几分钟才释放,导致系统打开文件数不够用了,

  1. 一方面增加打开最大文件数,
  2. 另一方面,需要减少http keep-alive 的时间。

一直没有在golang中找到如何像apache、nginx类似的设置。
请指点一下啊

共 7 个回复


stevewang

设置net/http.ServerReadTimeout字段。

func ListenAndServe(addr string, handler http.Handler, timeout time.Duration) error {
    server := &http.Server{
        Addr:        addr,
        Handler:     handler,
        ReadTimeout: timeout,
    }
    return server.ListenAndServe()
}
# 0

Zhangyc310

非常感谢,但还有个问题

        ReadTimeout    time.Duration 
        // maximum duration before timing out read of the request

在golang中,这个参数是等待请求返回结果的超时时间,
需要设置的是:浏览器与服务器空闲关闭时间,例如30s没有发送请求、返回数据,则服务器关闭与浏览器之间connection。

# 1

stevewang

设置了ReadTimeout以后,如果指定时间没有接收到数据,服务器就会关闭客户端连接。

package main

import (
    "fmt"
    "net"
    "net/http"
    "io"
    "time"
)

func ListenAndServe(addr string, handler http.Handler, timeout time.Duration) error {
    server := &http.Server{
        Addr:        addr,
        Handler:     handler,
        ReadTimeout: timeout,
    }
    return server.ListenAndServe()
}

func main() {
    addr := "127.0.0.1:6061"
    http.HandleFunc("/", func(http.ResponseWriter, *http.Request) {})
    go ListenAndServe(addr, nil, time.Second*10)
    time.Sleep(time.Second)
    started := time.Now()
    remoteAddr, _ := net.ResolveTCPAddr("tcp4", addr)
    conn, err := net.DialTCP("tcp4", nil, remoteAddr)
    if err != nil {
        panic("failed to connect")
    }
    defer conn.Close()
    _, err = conn.Read(make([]byte, 128))
    if err != io.EOF {
        panic("should return EOF")
    }
    fmt.Printf("time escaped=%s, error=%s\n", time.Now().Sub(started), err)
}
# 2

Zhangyc310

试了一下,确实很快就释放了,非常感谢!
还有个问题请教一下:
如果设置了timeout为30s,如果下载一个大文件超过30s,会不会被切断啊?

# 3

Zhangyc310

还有个问题,我启动了一个ListenAndServe,浏览器访问,当似乎每一个文件都新建了一个connection,打开第二个网页,之前的connection没有使用,还是重新建立了新的conn。。。
这个问题可能是什么原因啊?

# 4

stevewang

下载文件不受影响,因为WriteTimeout没有修改。
http是短连接,每次请求都会创建一个新的连接。服务器没有办法知道第二个页面和第一个页面是同一个进程发起的请求,所以必须使用新的连接。
不过从客户端的角度说,是可以用一个连接请求多个资源的,比如http2协议就支持这种复用连接方式。

# 5