Tenho três servidores, totalmente conectados via wireguard. Eles executam o Ubuntu Server 22.04 e o cluster repmr postgresql com replicação de streaming.
Todos os computadores têm um endereço público, mas as instâncias do PostgreSQL e os clientes de banco de dados usam os endereços internos (na VPN wireguard).
Em um dos computadores, vejo isto nos logs:
2024-07-26 07:23:14.463 UTC [147915] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
2024-07-26 07:25:56.242 UTC [148509] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
2024-07-26 07:28:17.567 UTC [148818] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
2024-07-26 07:33:13.234 UTC [149090] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
2024-07-26 07:48:42.721 UTC [149723] FATAL: terminating walreceiver due to timeout
2024-07-26 07:52:17.298 UTC [151521] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
2024-07-26 08:01:25.141 UTC [151889] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
2024-07-26 08:02:16.337 UTC [152868] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
2024-07-26 08:06:13.169 UTC [152951] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
2024-07-26 08:22:04.180 UTC [153377] FATAL: could not receive data from WAL stream: server closed the connection unexpectedly
Além disso, quando tento conectar-me ao banco de dados primário a partir de um programa Go ou Python, às vezes vejo "tempo limite de conexão" ou "redefinição de conexão por peer", "a conexão foi fechada no meio da operação" e mensagens semelhantes. É importante observar que isso acontece apenas em um computador e não nos outros.
No lado do servidor (postgresql primário), vejo isso nos logs:
2024-07-26 12:31:36.667 UTC [3778655] telegraf@telegraf LOG: could not receive data from client: Connection reset by peer
2024-07-26 12:31:36.897 UTC [3777638] telegraf@telegraf LOG: could not receive data from client: Connection reset by peer
2024-07-26 12:31:39.462 UTC [3775606] telegraf@telegraf LOG: could not receive data from client: Connection reset by peer
2024-07-26 12:31:39.480 UTC [3780628] telegraf@telegraf LOG: could not receive data from client: Connection reset by peer
Esses erros acontecem apenas algumas vezes por hora. É o suficiente para tornar meus aplicativos não confiáveis, mas eles são intermitentes. Executei este teste de ping entre os endereços públicos:
ping -c 3600 primary.public.com
# waited an hour...
--- primary.public.com ping statistics ---
3600 packets transmitted, 3600 received, 0% packet loss, time 3603052ms
rtt min/avg/max/mdev = 72.849/73.214/101.325/0.881 ms
Também executei um teste de ping no endereço IP privado:
ping -c 1008 primary.private.com
# waited...
--- primary.private.com ping statistics ---
1008 packets transmitted, 783 received, 22.3214% packet loss, time 1013304ms
rtt min/avg/max/mdev = 80.742/91.383/256.720/16.133 ms
Em outras palavras, 22% dos pacotes de ping são perdidos no wireguard.
O valor MTU para todos os dispositivos wireguard é o padrão 1420.
3: dev0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.241.64.3/32 scope global dev0
valid_lft forever preferred_lft forever
Também tentei testar o MTU usando este script:
size=1272
while ping -s $size -c1 -M do primary.internaladdress.com >&/dev/null; do
((size+=4))
done
echo "Max MTU size: $((size-4+28))
E também imprimiu 1420.
E observe que o problema só existe entre dois computadores dos três. Por exemplo, é ruim entre A e B, mas é bom entre BC.
Deve-se notar que o computador problemático está longe (num continente diferente). Mas isso não deveria causar isso.
Pelo que entendi, o wireguard encapsula pacotes IP em pacotes UDP criptografados, e o protocolo TCP se encarrega de reenviar os pacotes perdidos.
É muito estranho que os pacotes IP entre endereços públicos tenham 0% de data de descarte, mas os pacotes wireguard/UDP tenham mais de 20%. É possível que pacotes UDP sejam descartados por algum roteador ou switch? Talvez QoS esteja acontecendo?
Esses servidores são alugados e ficam muito distantes um do outro. Obviamente, não posso fazer nada para eliminar a queda de pacotes. Entendo que o UDP sempre não será confiável. Mas me pergunto se posso consertar as conexões TCP de alguma forma. Mesmo que às vezes fiquem lentos (mesmo que não consigam se comunicar por um ou dois segundos), eles não devem reiniciar a conexão. Quais são minhas opções?
Tudo bem, aqui está o que encontrei. Todos os três servidores tinham endereços IPv6 e IPv4, e esses endereços foram atribuídos aos seus FQDNs. Por algum motivo, o servidor BC usou o endereço IPv4 quando estabeleceu a conexão. Mas a AB usou o endereço IPv6. Parece que encapsular pacotes IPv4 em pacotes IPv6 UDP (wireguard) é problemático. Não consegui descobrir o motivo exato, pode ser algo fora dos meus servidores VPS. Mas é fato que no IPv6 houve 20-70% de perda de pacotes, e foi do pior tipo (por exemplo, nenhuma perda por um minuto, depois 100% de perda por vários segundos). Além disso, os tempos de resposta eram ridículos, de 20 a 90 ms no mesmo datacenter.
Em seguida, removi todos os endereços IPv6 das interfaces públicas e forcei todo o tráfego wireguard para IPv4. De repente, o tempo de resposta caiu para cerca de 2 ms em média e 0% de perda de pacotes.
Não consegui determinar a causa exata, mas é quase certo que o problema NÃO é porque a rede está com excesso de inscrições. Não é uma “solução” real, mas funcionou para mim e pode funcionar para outros.