如何在Go中禁用http警报

时间:2014-03-12 13:40:22

标签: http go

调用http.ListenAndServe时出现以下错误我遇到了问题:

http: Accept error: *ip* accept tcp too many open files; retrying in 10ms

我如何禁用此功能? ulimit -n为1024,我无法更改。

2 个答案:

答案 0 :(得分:6)

问题是您无法再打开文件描述符,因此您无法接受更多连接。如果你无法改变这个事实,你有三种可能的选择来解决这个问题:

  1. 保持原样:标准库使用exponential backoff等待再次存在文件描述符的时间。这通常是一种很好的做法,让未来的客户有机会获得一个位置。实际上,http包会针对发生的每个临时网络错误执行此操作。
  2. 发生此类临时错误时关闭连接。这可以通过包装net.Listener返回的net.Listen并修改它的Accept()方法来删除临时错误的连接来实现。
  3. 忽略该消息。如果邮件是困扰您的唯一信息,您只需将log.Output()设置为ioutil.Discard即可。 (虽然这是一个选项,但我没有看到它的使用。你最终会忽略重要的错误消息,并想知道为什么你的服务不起作用。)
  4. 我更喜欢第一个,但可能有一个你需要第二个的情况,所以这里是一个连接丢弃监听器(on play)的例子:

    type DroppingListener struct {
        net.Listener
    }
    
    func (d DroppingListener) Accept() (net.Conn, error) {
        for {
            conn, err := d.Listener.Accept()
    
            if err != nil {
                if ne, ok := err.(net.Error); ok && ne.Temporary() {
                    log.Println("Dropping connection because:", ne)
                    continue
                }
            }
    
            return conn, err
        }
    }
    
    func ListenAndServe(addr string, handler http.Handler) error {
        srv := &http.Server{Addr: addr, Handler: handler}
    
        l, e := net.Listen("tcp", addr)
        if e != nil {
            return e
        }
    
        l = &DroppingListener{l}
    
        return srv.Serve(l)
    }
    

    使用此DroppingListenerAccept方法将立即返回连接 没有更多的临时错误。

答案 1 :(得分:2)

少于1,000个客户。

你希望在这里发生什么?您似乎无法满足您的资源需求。