![将给定端口的传入网络请求路由到不同的应用程序](https://linux22.com/image/22367/%E5%B0%86%E7%BB%99%E5%AE%9A%E7%AB%AF%E5%8F%A3%E7%9A%84%E4%BC%A0%E5%85%A5%E7%BD%91%E7%BB%9C%E8%AF%B7%E6%B1%82%E8%B7%AF%E7%94%B1%E5%88%B0%E4%B8%8D%E5%90%8C%E7%9A%84%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F.png)
我有一个监听端口连接的应用程序,但我偶尔会将其关闭以进行更新等。我想要一种配置系统的方法,以便如果该程序正在运行,则对该端口的请求将发送到应用程序,但如果它没有运行,则请求将被定向到某个其他应用程序(可能会返回“暂时不可用”)信息)。实现这一目标的最简单方法是什么?
我在目标计算机上没有 root 访问权限,因此我宁愿避免诸如iptables
.我考虑过一个辅助应用程序,除了将连接路由到其他两个应用程序之外什么都不做,但我希望有一种更简单的方法
答案1
您的问题意味着这两个程序将在同一台计算机上交替运行,绑定到同一端口。这是一个坏主意。如果您尝试这样做,您将遇到TIME_WAIT
(又名 2MSL)问题。本文描述了问题。 (它以 Windows 为中心,但它所讨论的大部分内容都适用于任何 TCP/IP 堆栈。)
BSD 套接字 API 确实提供了一种方法来破坏这种保护 ( setsockopt(SO_REUSEADDR)
),但这并不是这样做合理的情况之一。
相反,以高可用性人员相同的方式解决问题:放置一个反向代理世界和您的“真实”后端服务器之间。
在 HTTP 世界中,解决此问题的一种流行方法是nginx。您可以对其进行配置,以便在后端服务器关闭时,它向客户端提供静态内容。如果您的协议类似于 HTTP、IMAP 或 POP,也许您可以按原样使用 nginx。如果没有,您可以构建自定义代理服务器。
您可能需要两个 TCP 端口才能正常工作。代理绑定到公共 IP 上面向公众的端口号。您的后端服务器仅在本地主机接口上绑定到辅助端口。这样,流量只能通过代理从公网到达后端服务器。
如果两个程序都被编写为允许将它们绑定到同一端口,则您可以逃脱绑定。例如,如果您的公共IP是1.2.3.4
并且您的公共服务端口是,如果反向代理仅绑定到IP并且“真实”服务器仅绑定到,2345
则两个程序都可以绑定到端口。如果任一绑定到(0.0.0.0),则需要不同的端口。2345
1.2.3.4
127.0.0.1
INADDR_ANY
这解决了 2MSL 问题,因为您的客户端始终与同一个程序(代理服务器)通信。网络堆栈永远不会对如何处理 2MSL 时间内清除的任何杂散数据包感到困惑。
反向代理的一个变体是负载均衡器,它也可以在这里工作。负载均衡器旨在智能地将流量路由到不同的机器。如果您认为您的应用程序有一天可能需要水平扩展,那么这种代理是有意义的。您将选择一个负载均衡器,它知道当所有正常应用程序服务器都关闭时如何将流量发送到特殊的“服务关闭”主机。
负载均衡器解决方案变体的主要问题是,通用负载均衡器可能会盲目地假设它代理的所有后端服务都使用相同的端口号,仅 IP 不同。不过,您也许可以获得更灵活的负载平衡器,或者为共享服务器获得多个 IP。