我在调用http.ListenAndServe时遇到以下错误的问题:

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

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

最佳答案

问题在于您无法再打开文件描述符,因此不能接受更多连接。如果您不能更改事实,则可以使用三个选项来解决此问题:

  • 保持原样:标准库使用exponential backoff等待再次出现文件描述符时。通常,这是一个好习惯,并为将来的客户提供了获得广告位的机会。实际上,http包针对发生的每个临时网络错误执行此操作。
  • 发生此类临时错误时,请关闭连接。这可以通过包装net.Listener返回的net.Listen并修改其Accept()方法以在出现临时错误时删除连接来实现。
  • 忽略该消息。如果仅是让您感到困扰的消息,则只需将log.Output()设置为ioutil.Discard即可。 (虽然这是一个选项,但我看不到它的用法。您最终将忽略重要的错误消息,并想知道为什么您的服务无法正常工作。)

  • 我希望使用第一个,但在某些情况下可能需要第二个,因此下面是一个连接删除监听器(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方法将在存在后立即返回连接
    没有更多的临时错误。

    关于http - 如何在Go中禁用HTTP警报,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22353350/

    10-11 16:52