Roteie solicitações de rede recebidas de uma determinada porta para diferentes aplicativos

Roteie solicitações de rede recebidas de uma determinada porta para diferentes aplicativos

Eu tenho um aplicativo que escuta conexões em uma porta, mas ocasionalmente o desativo para atualizações e coisas do gênero. Eu gostaria de configurar o sistema de forma que, se esse programa estiver em execução, as solicitações para essa porta sejam enviadas para o aplicativo, mas se não estiver em execução, as solicitações sejam direcionadas para algum outro aplicativo (que pode retornar um "temporariamente indisponível" mensagem). Qual é a maneira mais fácil de conseguir isso?

Não tenho acesso root na máquina de destino, então prefiro evitar coisas como iptables. Eu considerei um aplicativo auxiliar que não faz nada além de rotear conexões para os outros dois aplicativos, mas espero que haja uma maneira mais fácil

Responder1

Sua pergunta implica que ambos os programas estariam rodando alternadamente na mesma máquina, vinculados à mesma porta. Esta é uma má ideia. Você encontrará o TIME_WAITproblema (também conhecido como 2MSL) se tentar isso.Este artigodescreve o problema. (É centrado no Windows, mas a maior parte do que está falando se aplica a qualquer pilha TCP/IP.)

A API de soquetes BSD fornece uma maneira de anular essa proteção ( setsockopt(SO_REUSEADDR)), mas esse não é um dos casos em que isso se justifica.

Em vez disso, resolva o problema da mesma forma que o pessoal da Alta Disponibilidade: coloque umproxy reversoentre o mundo e seu servidor back-end "real".

No mundo HTTP, uma solução popular para este problema énginx. Você pode configurá-lo para que, enquanto o servidor back-end estiver inativo, ele forneça conteúdo estático aos clientes. Se o seu protocolo for semelhante a HTTP, IMAP ou POP, talvez você possa usar o nginx como está. Caso contrário, você poderá criar um servidor proxy personalizado.

Você provavelmente precisará de duas portas TCP para que isso funcione. O proxy se liga ao número da porta pública, no IP público. Seu servidor back-end se liga a uma porta secundária, apenas na interface localhost. Assim, o tráfego pode ir da rede pública para o servidor back-end somente por meio do proxy.

Você pode vincular ambos à mesma porta se ambos os programas forem escritos para permitir isso. Por exemplo, se o seu IP público for 1.2.3.4e a sua porta de serviço público for 2345, ambos os programas poderão se vincular à porta 2345se o proxy reverso se vincular apenas ao IP 1.2.3.4e o servidor "real" se vincular apenas ao 127.0.0.1. Se algum deles estiver vinculado a INADDR_ANY(0.0.0.0), você precisará de portas diferentes.

Isso resolve o problema do 2MSL porque seus clientes estão sempre conversando com o mesmo programa, o servidor proxy. A pilha de rede nunca ficará confusa sobre o que fazer com quaisquer pacotes perdidos varridos no tempo 2MSL.

Uma variação do proxy reverso é obalanceador de carga, e também pode funcionar aqui. Um balanceador de carga é projetado para rotear de forma inteligente o tráfego para diferentes máquinas. Esse tipo de proxy faria sentido se você achasse que algum dia seu aplicativo precisaria ser dimensionado horizontalmente. Você selecionaria um balanceador de carga que soubesse como enviar tráfego para um host especial de "serviço inativo" quando todos os servidores de aplicativos normais estivessem inativos.

O principal problema da variante da solução do balanceador de carga é que um balanceador de carga genérico pode assumir cegamente que todos os serviços de back-end para os quais ele faz proxy estão usando o mesmo número de porta, diferindo apenas no IP. Você pode conseguir um balanceador de carga mais flexível ou vários IPs para seu servidor compartilhado.

informação relacionada