【发布时间】:2013-05-22 01:07:58
【问题描述】:
我有一个 Go 程序在 localhost:8080 上托管一个简单的 HTTP 服务,因此我可以通过 proxy_pass 指令将我的公共 nginx 主机连接到它,作为反向代理来处理我网站的部分请求。这一切都很好,没有问题。
我想将 Go 程序转换为在 Unix 域套接字而不是本地 TCP 套接字上托管 HTTP 服务,以提高安全性并减少 TCP 不必要的协议开销。
问题:
问题是 Unix 域套接字一旦被 bind() 到,就不能被重用,即使在程序终止之后也是如此。第二次(以及之后的每次)我运行 Go 程序,它以致命错误 "address already in use" 退出。
通常的做法是在服务器关闭时unlink() Unix 域套接字(即删除文件)。但是,这在 Go 中很棘手。我的第一次尝试是在我的主函数中使用defer 语句(见下文),但如果我用 CTRL-C 之类的信号中断进程,它就不会运行。我想这是可以预料的。令人失望,但并不意外。
问题:是否有关于如何在服务器进程关闭(正常或不正常)时unlink() 套接字的最佳实践?
这是我的func main() 的一部分,用于启动服务器侦听以供参考:
// Create the HTTP server listening on the requested socket:
l, err := net.Listen("unix", "/tmp/mysocket")
if err != nil {
log.Fatal(err)
} else {
// Unix sockets must be unlink()ed before being reused again.
// Unfortunately, this defer is not run when a signal is received, e.g. CTRL-C.
defer func() {
os.Remove("/tmp/mysocket")
}()
log.Fatal(http.Serve(l, http.HandlerFunc(indexHtml)))
}
【问题讨论】:
-
@Tom 谢谢。这个问题/答案已经有一年了,Go 仍在改进,所以我想看看是否有任何新的/更好的出现。
-
在第一行之前尝试
os.Remove("/tmp/mysocket"),它有效吗? -
我用一个简单的信号处理程序让它工作得很好。现在没问题,因为用例非常简单,但我担心会有很多无法访问的开放资源进行更复杂的清理操作。
标签: go signals unix-socket