O HAProxy (como muitos balanceadores de carga) geralmente mantém duas conversas. O Proxy tem uma sessão (tcp neste caso) com o cliente e outra sessão com o servidor. Portanto, com proxies, você acaba vendo duas vezes as conexões no balanceador de carga. Portanto, todo o tráfego flui pelo balanceador de carga.
Quando se trata de escalonar vários balanceadores de carga, não acho que você precise. Mas uma maneira prática e relativamente fácil de fazer isso é usar algo parecido com keepalive com dois IPs flutuantes e round robin DNS entre esses dois IPs. Com o keepalived, se um dos balanceadores de carga cair, o outro manterá os dois IPs, para que você obtenha alta disponibilidade dessa maneira. Dito isto, acho que você vai ficar bem com uma instância haproxy ativa com sua carga.
HAProxy escala muito bem. Um exemplo, a rede do Stack Exchange usa soquetes da Web que mantêm conexões TCP abertas. Enquanto eu 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