I have a udp server, [...] server is almost entirely stateless [..] have some fidelity, I mean if client X was routed to server y, then I want all of X's subsequent requests to go to server Y, as long as it is sensible and not overloads Y.
Então, você está usando um protocolo de aplicativo não divulgado que mantém algum estado de aplicativo e é executado sobre o UDP? Você está indo numa direção difícil. O UDP não é um transporte de dados confiável, esse é o objetivo dele - para um transporte de dados confiável, veja o seu popular amigo TCP. A única maneira de obter sua 'fidelidade' é ter um proxy de balanceamento de carga que entenda o protocolo da sua camada de aplicação e que saiba qual é o seu estado atual de aplicativo e atue de acordo.
Eu vejo três abordagens que chegam perto de fornecer o que você procura:
-
Estique estaticamente as conexões de entrada em mais de três endereços IP, com base no endereço IP source (usuário final). Dessa forma, um determinado usuário sempre será direcionado para o mesmo servidor. A maioria dos firewalls profissionais pode fazer isso por você. Talvez você precise tornar os três servidores altamente disponíveis, já que a maioria dos firewalls não fará verificações de integridade de backend para você.
-
Use DNS e use o DNS Round Robin, como já sugerido por Matt Simmons.
-
Use o Balanceamento de carga de rede (NLB) incorporado do Windows. Honestamente, eu não sei como o cenário de failover seria executado com o NLB e seu serviço baseado em UDP com semi-estado - você teria que investigar você mesmo, com base em como seu aplicativo lida com o estado. No lado positivo, o NLB é muito fácil de configurar, gratuitamente com a licença do Windows, maduro e com bom desempenho.