如何使用Go编程语言可靠地unlink()Unix域套接字

我有一个Go程序,在其上托管了一个简单的HTTP服务,localhost:8080因此我可以nginx通过该proxy_pass指令将我的公共主机连接到它,作为反向代理来满足我的网站请求的一部分。一切都很好,在那里没有问题。

我想将Go程序转换为在Unix域套接字而不是本地TCP套接字上承载HTTP服务,以提高安全性并减少TCP不必要的协议开销。

:问题在于bind(),即使程序终止后,Unix域套接字也无法重用。第二次(以及之后的每一次)我运行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)))

}

回答:

这是我使用的完整解决方案。我在问题中发布的代码是简化版本,目的是清楚地进行演示。

// Create the socket to listen on:

l, err := net.Listen(socketType, socketAddr)

if err != nil {

log.Fatal(err)

return

}

// Unix sockets must be unlink()ed before being reused again.

// Handle common process-killing signals so we can gracefully shut down:

sigc := make(chan os.Signal, 1)

signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM)

go func(c chan os.Signal) {

// Wait for a SIGINT or SIGKILL:

sig := <-c

log.Printf("Caught signal %s: shutting down.", sig)

// Stop listening (and unlink the socket if unix type):

l.Close()

// And we're done:

os.Exit(0)

}(sigc)

// Start the HTTP server:

log.Fatal(http.Serve(l, http.HandlerFunc(indexHtml)))

我肯定希望这是一个好而有效的Go代码,它将使Go作者感到骄傲。在我看来确实如此。如果不是这样,那会让我感到尴尬。:)

对于任何好奇的人来说,这都是https://github.com/JamesDunne/go-index-

html的一部分,它是一个简单的HTTP目录列表生成器,具有Web服务器无法为您提供的一些额外功能。

以上是 如何使用Go编程语言可靠地unlink()Unix域套接字 的全部内容, 来源链接: utcz.com/qa/406190.html

回到顶部