【发布时间】:2019-12-13 10:57:58
【问题描述】:
美好的一天。
我遇到了 ASP.NET Core WebAPI 服务器的问题。当我重新启动 Web 服务器时,大约 80% 的时间会发生这种情况。
它不会发生在任何本地 Windows 机器上。
技术细节:
服务器在 Ubuntu Linux 上运行:
NAME="Ubuntu"
VERSION="16.04.6 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.6 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
点网信息:
~# dotnet --version
2.2.203
~# dotnet --list-sdks
2.0.3 [/usr/share/dotnet/sdk]
2.1.4 [/usr/share/dotnet/sdk]
2.2.203 [/usr/share/dotnet/sdk]
为 .NET Core 2.0 构建的服务器本身
出现的问题:
服务器重启后,Kestrel 绑定端口失败。我在 2001 端口绑定它。
来自journalctl的日志:
Unhandled Exception: System.IO.IOException: Failed to bind to address http://[::]:2001: address already in use. ---> Microsoft.AspNetCore.Connections.AddressInUseException: Address already in use ---> System.Net.Sockets.SocketException: Address already in use
at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.BindAsync()
--- End of inner exception stack trace ---
我该如何解决:
我真的无能为力。我必须等待几分钟(它会重新启动并崩溃几次),然后服务器将正常启动,就像什么都没发生一样。
我尝试过的:
我创建了一个小代码,尝试在启动 Kestrel 之前绑定端口。
如果失败,它会稍等片刻,然后再试一次。基本上它会等到端口被释放。
当绑定成功时,它会释放端口并尝试启动 Kestrel。
这段代码在我的机器上运行良好,但在远程 Linux 机器上不起作用。
我最好的猜测是它与 IPv6 有关,但我真的不知道到底是什么。
(Kestrel 在 Windows 上完美重启(在本地网络中使用 IPv4 地址)并在 Linux 上失败(使用 IPv6 本地地址))
我将不胜感激。
【问题讨论】:
-
我会从客户端做的是从 cmd.exe >ping -t IP 运行 ping。 -t 选项连续运行 ping。然后重新启动服务器几次,看看 ping 需要多长时间才能开始工作。尝试在window和linux上。我不确定是服务器花了很长时间才开始识别 IP,还是存在未关闭并最终超时的现有连接。
-
停止服务器后,您的连接可能处于 TIME_WAIT 状态。这是为了处理可能仍在网络中传输的数据包。不同的操作系统有不同的实现如何限制使用相同的端口号。 Linux 比 Windows 更严格。要重用相同的端口,您必须在服务器代码中调用
bind之前设置套接字选项 SO_REUSEADDR 和/或 SO_REUSEPORT。 (我不知道如何在 C# 中执行此操作。)请参阅 serverframework.com/asynchronousevents/2011/01/… -
@jdweng Ping 不会做任何与端口打开或关闭相关的事情。
-
@Bodo 会检查的,谢谢!
-
除非 PING 有效,否则您无法打开或关闭端口。所以 PING 与端口的打开或关闭有关。如果您没有到服务器的路由,则 ping 将不起作用,并且打开/关闭将不起作用。
标签: c# linux sockets ubuntu asp.net-core