英文:
How to disable http alerts in Go
问题
当调用http.ListenAndServe
时,我遇到了以下错误:
http: Accept error: *ip* accept tcp too many open files; retrying in 10ms
我该如何禁用它?ulimit -n
的值为1024,我无法更改它。
英文:
I have a problem with the following error when calling http.ListenAndServe
:
http: Accept error: *ip* accept tcp too many open files; retrying in 10ms
How I can disable this? ulimit -n
is 1024 and I can't change it.
答案1
得分: 6
问题是你不能再打开更多的文件描述符,因此无法接受更多的连接。如果你不能改变这个事实,你有三种可能的选择来解决这个问题:
- 保持原样:标准库使用指数退避来等待再次有文件描述符的时间。这通常是一个很好的做法,并且给未来的客户端一个获取插槽的机会。实际上,
http
包对每个发生的 临时 网络错误都会这样做。 - 在发生临时错误时关闭连接。可以通过包装
net.Listen
返回的net.Listener
并修改其Accept()
方法来实现在临时错误上断开连接。 - 忽略消息。如果消息是唯一困扰你的事情,你可以简单地将
log.Output()
设置为ioutil.Discard
。(虽然这是一个选项,但我不认为有用。你最终会忽略重要的错误消息,并想知道为什么你的服务不工作。)
我更喜欢第一种方法,但也可能有情况需要第二种方法,所以这里有一个丢弃连接的监听器的示例(在 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)
}
使用这个 DroppingListener
,Accept
方法将在没有临时错误时立即返回连接。
英文:
The problem is that you cannot open anymore file descriptors and therefore you cannot accept more connections. If you can't change the fact you have three possible options to deal with this problem:
- Leave it as it is: The standard library uses an exponential backoff to wait for a time when there are file descriptors again. This is generally a good practice and gives future clients a chance to get a slot. In fact, the
http
package does this for every temporary network error that occurs. - Close the connection when a temporary error like this occurs. This can be achieved by wrapping the
net.Listener
returned bynet.Listen
and modify it'sAccept()
method to drop the connection on temporary errors. - Ignore the message. If the message is the only thing that bothers you, you can simply set the
log.Output()
toioutil.Discard
. (While this is an option, I don't see the use of that. You will end up ignoring important error messages and wonder why your service does not work.)
I would prefer the first but there may be a case where you want the second, so here is an example of a connection dropping listener (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)
}
With this DroppingListener
, the Accept
method will return a connection as soon as there is
no more temporary error.
答案2
得分: 2
少于1000个客户。
你希望在这里发生什么?你似乎无法满足资源需求。
英文:
Have fewer than ~1,000 clients.
What are you hoping to happen here? You don't seem to be able to meet your resource requirements.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论