HAProxy + NodeJS застревает при повторной передаче TCP - PullRequest
0 голосов
/ 30 ноября 2011

У меня есть HAProxy + NodeJS + Rails Setup, я использую NodeJS Server для загрузки файлов.

Проблема, с которой я сталкиваюсь, заключается в том, что если я загружаю через haproxy на nodejs и происходит «TCP (Fast) Retransmission» из-за потерянного пакета, скорость передачи на клиенте падает до нуля в течение 5-10 секунд. и заполняется повторными передачами TCP.

Этого не происходит, если я загружаю в NodeJS напрямую (повторная передача TCP тоже происходит, но она не застревает с десятками попыток повторной передачи).

Моя тестовая установка - это простая ФОРМА HTML4 (метод POST) с одним полем ввода файла. Сервер NodeJS только читает входящие данные и больше ничего не делает.

Я проверял это на нескольких машинах, в сетях, браузерах, всегда одна и та же проблема.

Вот дамп трафика TCP от клиента при загрузке файла:

.....
TCP 1506    [TCP segment of a reassembled PDU]
>> everything is uploading fine until:
TCP 1506    [TCP Fast Retransmission] [TCP segment of a reassembled PDU]
TCP 66      [TCP Dup ACK 7392#1] 63265 > http [ACK] Seq=4844161 Ack=1 Win=524280 Len=0 TSval=657047088 TSecr=79373730
TCP 1506    [TCP Retransmission] [TCP segment of a reassembled PDU]
>> the last message is repeated about 50 times for >>5-10 secs<< (TX drops to 0 on client, RX drops to 0 on server)
TCP 1506    [TCP segment of a reassembled PDU]
>> upload continues until the next TCP Fast Retransmission and the same thing happens again

Файл haproxy.conf (стабильный haproxy v1.4.18) выглядит следующим образом:

global
    log 127.0.0.1   local1 debug
    maxconn     4096 # Total Max Connections. This is dependent on ulimit
    nbproc      2

defaults
    log global
    mode        http
    option      httplog
    option      tcplog

frontend http-in
    bind *:80

    timeout client 6000

    acl is_websocket   path_beg /node/

    use_backend node_backend  if is_websocket

    default_backend app_backend

# Rails Server (via nginx+passenger)
backend app_backend
    option httpclose
    option forwardfor

    timeout server 30000
    timeout connect 4000
    server app1 127.0.0.1:3000

# node.js
backend node_backend
    reqrep ^([^\ ]*)\ /node/(.*)     \1\ /\2
    option httpclose
    option forwardfor
    timeout queue 5000
    timeout server 6000
    timeout connect 5000
    server node1 127.0.0.1:3200 weight 1 maxconn 4096

Спасибо за чтение! :)

Simon

Ответы [ 2 ]

0 голосов
/ 30 ноября 2011

Попробуйте использовать https://github.com/nodejitsu/node-http-proxy. Я не уверен, будет ли оно соответствовать вашим общим архитектурным требованиям, но стоит попробовать.

0 голосов
/ 30 ноября 2011

Попробуйте установить глобальный тайм-аут http-запроса на 6 секунд.Как правило, он может быть слишком низким для повторной передачи, и, хотя он не объяснит причину, он может решить вашу проблему.

...