英文:
In what situation will http.ListenAndServe return
问题
我看到很多代码都这样做:
log.Fatal(http.ListenAndServe(":8080", nil))
我从来没有见过 HTTP 服务器返回错误,但我想更多地了解可能遇到的故障场景。
如果我的处理程序代码发生恐慌,它会停止吗?它只会在无法初始绑定的情况下返回吗?
如何确保服务器尽可能保持活动状态的最佳实践是什么?
英文:
I see a lot of code do this kind of thing:
log.Fatal(http.ListenAndServe(":8080",nil))
I have never seen the http server return an error, but I would like to understand more about the possibility what types of failure scenarios I can encounter.
Will it stop if my handler code panics? Will it only return in the case where it can't bind initially?
What is the best practice for making sure the server stays active to the highest degree possible?
答案1
得分: 3
> 如果我的处理程序代码发生恐慌,它会停止吗?
不会。内置的HTTP服务器会从恐慌中恢复并记录下来。
> 它只会在无法绑定初始地址的情况下返回吗?
这是通常的原因,尽管也有可能出现其他错误导致侦听器关闭。
> 保证服务器尽可能保持活动的最佳实践是什么?
如果HTTP服务器的主循环退出,那可能是一个致命错误,你不希望尝试从中恢复。如果在尝试绑定地址时返回,你可以检查address in use
错误,然后等待并重试。
// 示例展示了*nix系统上的错误类型和字段。
// 如果你不想恐慌,你应该检查这些断言的有效性。
// 由于这个示例涉及到syscall,所以它可能不比检查字符串"address already in use"更好。
if err.(*net.OpError).Err.(*os.SyscallError).Err == syscall.EADDRINUSE {
fmt.Println("地址已被使用")
}
请记住,ListenAndServe实际上是两个调用,你可以自己分开它们。它创建一个net.Listener
,然后将其传递给http.Server
的Serve(l net.Listener)
方法。
英文:
> Will it stop if my handler code panics?
No. The built-in http server recovers from panics and logs them.
> Will it only return in the case where it can't bind initially?
That's the usual reason, though it's possible that some other error could force the listener to close.
> What is the best practice for making sure the server stays active to the highest degree possible?
If the http server's main loop exits, it's likely a fatal error that you don't want to try and recover from. If that call returns when trying to bind the address, you could check for the address in use
error, then wait and try again.
// Example to show the error types and fields on a *nix system.
// You should check the validity of these assertions if you don't want to
// panic. Due to the fact that this reaches into syscall, it's probably
// not much better than checking the string for "address already in use"
if err.(*net.OpError).Err.(*os.SyscallError).Err == syscall.EADDRINUSE {
fmt.Println("Address in use")
}
Remember that ListenAndServe is actually 2 calls, and you can separate them yourself. It creates a net.Listener
, then gives it to an http.Server
's Serve(l net.Listener)
method.
答案2
得分: 0
值得注意的是,log.Fatal
的go包文档中提到:
> Fatal等同于Print()后调用os.Exit(1)。
此外,http.ListenAndServe
的文档解释说:
> 此函数将阻塞,直到程序终止。
因此,只有在某种原因导致http监听器被终止时,才会调用log.Fatal
。
正如上面的回答所说,panic将被处理。
http.ListenAndServe
函数应该持续运行,直到底层套接字连接断开。在这一点上,log.Fatal
将打印监听器返回的任何消息,然后调用程序以错误代码(1)完全退出。
因此,“最佳实践”是保持监听器活动的任何操作,这更可能是一个网络考虑。
英文:
It may be worth noting that the go package documentation for log.Fatal
says
> Fatal is equivalent to Print() followed by a call to os.Exit(1).
Also, the documentation for http.ListenAndServe
explains that
> This function will block until the program is terminated.
So the log.Fatal
call will only be made if the http listener is killed for some reason.
A panic will be handled, as the answer above says.
The http.ListenAndServe
function should continue indefinitely until the underlying socket connection is broken. At that point log.Fatal
will print any message returned by the listener, before calling the program to exit completely with an error code (1).
So the "best practice" to keep the listener alive would be to do anything that keeps the socket connection alive. At that stage, it's more likely to be a network consideration.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论