несколько соединений TCP, несмотря на http-alive - PullRequest
0 голосов
/ 22 сентября 2018

Я не уверен, правильно ли я понимаю http-keep-alive , на мой взгляд, он должен повторно использовать соединение tcp, а не строить новое.Тем не менее, я нашел что-то действительно странное, кажется, что трудно предвидеть поведение http keep-alive .


Сервер: NodeJS & Express ^ 4.16.3 и яиспользовали Wireshark для анализа результатов


Ситуация 1:

  • На стороне сервера

for(let i =1; i<11; i++){
  app.use('/' + i, (req, res) => {
    res.header('cache-control', 'no-store');
    res.send('i');
  });
}

server.keepAliveTimeout = 50000;
  • Клиентская сторона

setTimeout(() => {
    for (let i = 1; i < 11; i++) {
      fetch('' + i).then(data => console.log(data));
    }
  }, 10000);
  • результат: соединение tcp используется повторно (только одно соединение tcp), все запросы на выборку повторно используют соединение tcp, установленное index.html enter image description here

Ситуация 2:

  • Коды на стороне клиента такие же, здесь меняются только коды на стороне сервера

for(let i =1; i<11; i++){
  app.use('/' + i, (req, res) => {
    res.header('cache-control', 'no-store');
    // here I have added timeout!
    setTimeout(() => {
      res.send('i');
    }, 2000);
  });
}
  • результат: установлено еще 5 tcp-соединений (на рисунке только 4, потому что снимок экрана не завершен), несмотря на то, что я установил сервер.keepAliveTimeout = 50000;

enter image description here


Итак, мой вопрос: что на самом деле означает сохранение http?почему так себя ведет?Если в ситуации 2 он не будет использовать одно и то же TCP-соединение, каково значение поддержания активности ??

Спасибо за любые мысли!

1 Ответ

0 голосов
/ 22 сентября 2018

Да, HTTP Keep Alive должен повторно использовать ваше TCP-соединение с сервером.Сервер добавляет Connection: keep-alive заголовок с ответом, поэтому клиент поддерживает соединение.Таким образом, клиент не будет поддерживать соединение до тех пор, пока ваш сервер не ответит.

Итак, в вашем первом сценарии сервер отвечает заголовком, как только запрос получен.Таким образом, второй ответ (на самом деле может повторно использоваться, вам повезло, так как сервер отвечает на ваш запрос, прежде чем он отправит второй) повторно использует TCP-соединение.

Но во втором сценарии сервер ждет 2 секунды, чтобы отправить ответТаким образом, клиент не будет знать, что соединение должно оставаться активным до следующих 2 секунд.Но все остальные запросы нужно отправлять до этого, поэтому по умолчанию будет создаваться новое соединение для каждого HTTP-запроса.

Это может быть эффективно, если вам нужно постоянно вызывать HTTP-интерфейс, например, req -> res -> req -> res, но это также может быть неэффективно, если вы хотите получить независимый сбор данных с сервера.

Попробуйте на стороне клиента, если у вас есть какие-либо сомнения,

setTimeout(() => {
    fetch('' + i).then(data => console.log(data));

    setTimeout(function () {
        for (let i = 2; i < 11; i++) {
            fetch('' + i).then(data => console.log(data));
        }
    }, 5000)
}, 10000);
...