
Tengo una aplicación que escucha conexiones en un puerto, pero ocasionalmente la quito para actualizaciones y cosas por el estilo. Me gustaría encontrar una forma de configurar el sistema de modo que, si ese programa se está ejecutando, las solicitudes para ese puerto se envíen a la aplicación, pero si no se está ejecutando, las solicitudes se dirijan a alguna otra aplicación (que puede devolver un mensaje "temporalmente no disponible"). mensaje). ¿Cuál es la forma más fácil de lograrlo?
No tengo acceso de root en la máquina de destino, por lo que prefiero evitar cosas como iptables
. He considerado una aplicación auxiliar que no hace más que enrutar conexiones a las otras dos aplicaciones, pero espero que haya una manera más sencilla.
Respuesta1
Su pregunta implica que ambos programas se ejecutarían alternativamente en la misma máquina, vinculados al mismo puerto. Esta es una mala idea. Te encontrarás con el TIME_WAIT
problema (también conocido como 2MSL) si intentas esto.Este artículodescribe el problema. (Está centrado en Windows, pero la mayor parte de lo que habla se aplica a cualquier pila TCP/IP).
La API de sockets BSD proporciona una forma de anular esta protección ( setsockopt(SO_REUSEADDR)
), pero este no es uno de los casos en los que está justificado hacerlo.
En su lugar, resuelva el problema de la misma manera que lo hace la gente de Alta Disponibilidad: coloque unproxy inversoentre el mundo y su servidor back-end "real".
En el mundo HTTP, una solución popular a este problema esnginx. Puede configurarlo para que, mientras el servidor back-end esté inactivo, proporcione contenido estático a los clientes. Si su protocolo se parece a HTTP, IMAP o POP, tal vez pueda usar nginx tal como está. De lo contrario, puede crear un servidor proxy personalizado.
Probablemente necesites dos puertos TCP para que esto funcione. El proxy se vincula al número de puerto público, en la IP pública. Su servidor back-end se vincula a un puerto secundario, solo en la interfaz del host local. Por lo tanto, el tráfico puede llegar desde la red pública al servidor back-end sólo a través del proxy.
Puede salirse con la suya vinculando ambos al mismo puerto si ambos programas están escritos para permitirlo. Por ejemplo, si su IP pública es 1.2.3.4
y su puerto de servicio público es 2345
, ambos programas pueden vincularse al puerto 2345
si el proxy inverso se vincula solo a la IP 1.2.3.4
y el servidor "real" se vincula solo a 127.0.0.1
. Si cualquiera de los dos se une a INADDR_ANY
(0.0.0.0), necesita puertos diferentes.
Esto resuelve el problema de 2MSL porque sus clientes siempre están hablando con el mismo programa, el servidor proxy. La pila de red nunca estará confundida acerca de qué hacer con los paquetes perdidos arrastrados en el tiempo 2MSL.
Una variación del proxy inverso es laequilibrador de carga, y también podría funcionar aquí. Un equilibrador de carga está diseñado para enrutar el tráfico de forma inteligente a diferentes máquinas. Este tipo de proxy tendría sentido si pensara que su aplicación algún día necesitaría escalar horizontalmente. Seleccionaría un equilibrador de carga que sepa cómo enviar tráfico a un host especial de "servicio inactivo" cuando todos los servidores de aplicaciones normales estén inactivos.
El principal problema de la variante de la solución del balanceador de carga es que un balanceador de carga genérico podría asumir ciegamente que todos los servicios de back-end que representa utilizan el mismo número de puerto, diferenciándose solo en la IP. Sin embargo, es posible que pueda obtener un equilibrador de carga más flexible u obtener varias IP para su servidor compartido.