O HAProxy (como muitos balanceadores de carga) geralmente mantém duas conversas. O Proxy possui uma sessão (tcp neste caso) com o cliente e outra sessão com o servidor. Portanto, com proxies, você acaba vendo duas vezes mais conexões no balanceador de carga. Portanto, todo o tráfego flui através do balanceador de carga.
Quando se trata de dimensionar vários balanceadores de carga, não acho que você precise. Mas uma maneira prática e bastante fácil de fazer isso é usar algo como keepalived com dois IPs flutuantes e DNS de rodízio entre esses dois IPs. Com keepalived, se um dos balanceadores de carga cair, o outro manteria os dois IPs, para que você obtenha alta disponibilidade dessa maneira. Dito isto, acho que você ficará bem com uma instância ativa de haproxy com sua carga.
O HAProxy escala muito bem. Por exemplo, a rede Stack Exchange usa soquetes da web que mantêm conexões TCP abertas. Enquanto estou postando isso, temos 143.000 soquetes TCP estabelecidos em uma máquina virtual VMware sem problemas. O uso da CPU na VM é de cerca de 7%.
Com esse tipo de configuração com o HAProxy, certifique-se de definir maxconn
alto o suficiente. Aqui está um exemplo de configuração do HAProxy para você começar:
frontend fe_websockets
bind 123.123.123.123:80
mode tcp
log global
option tcplog
timeout client 3600s
backlog 4096
maxconn 50000
default_backend be_nywebsockets
backend be_nywebsockets
mode tcp
option log-health-checks
option redispatch
option tcplog
balance roundrobin
server web1 10.0.0.1:1234
server web2 10.0.0.2:1234
timeout connect 1s
timeout queue 5s
timeout server 3600s