Я пытаюсь понять, как последовательно отключить keepalive на различных клиентских машинах, которые выдают HTTP-запросы через curl
.
Это мой целевой сервер:
- Ubuntu 18.04.2 LTS
- 4.15.0-47-generic
- HA-Proxy version 1.8.19-1ppa1~bionic 2019/02/12
Это клиент 1, на котором я выдаю curl
(ванильная установка):
- Ubuntu 16.04.3 LTS
- 4.4.0-62-generic
- curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Это клиент 2, на котором я выдаю curl
(ванильная установка):
- Ubuntu 18.04 LTS
- 4.15.0-20-generic
- curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.0g zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
Для отключения keepalive я пробовал использовать -H "Connection: close"
, --no-keepalive
и --keepalive-time 1
и только первый вариант кажется работает, но только с клиента 1.
На клиенте 1 (Ubuntu 16) соединение не остается открытым, но с клиента 2 (Ubuntu 18) соединение остается открытым, пока не завершится. Я подтверждаю это либо просмотром watch -n 0.1 "netstat -na | fgrep CLIENT_IP_ADDRESS"
, либо используя -vvv
на обоих клиентах, что на клиенте 1 всегда * Closing connection 0
, а на клиенте 2 всегда * Connection #0 to host www.example.com left intact
.
Разница между клиентом 1 и 2 очевидна - это версия Ubuntu и версия curl. Что заставляет соединение закрываться на клиенте 1, но не на клиенте 2?
Я также обнаружил, что если я поменяю целевой сервер на другую машину, работающую под управлением старого дистрибутива со старым apache httpd, посылаю ли я Connection: close
или нет, это не имеет никакого значения, и keepalive всегда используется от любого из моих двух клиентов. Поэтому я предполагаю, что конфигурация целевого сервера также играет некоторую роль в этом.
Edit:
Чтобы еще больше усложнить ситуацию, если с клиента 1 и 2 я отправляю запросы на целевой сервер через ab
, то соединение мгновенно разрывается. Это ожидаемо, потому что ab
использует HTTP/1.0
, а не HTTP/1.1
. Но затем, если я нацеливаюсь на старый дистрибутив с apache, то в обоих случаях соединение остается открытым. Это означает, что, действительно, принимающая сторона также играет роль.
Edit 2:
Я взял все /proc/sys/net/ipv4/
настройки обоих клиентов через:
for file in /proc/sys/net/ipv4/*
do
echo "$file $(cat $file)"
done
и их можно найти здесь:
Согласно https://ec.haxx.se/usingcurl-persist.html
curl всегда будет пытаться поддерживать соединения и повторно использовать существующие
Следовательно, вы не можете использовать его, используя инструменты как есть.
Как @ pl-nowlan упомянул в своем ответе, единственный способ сделать это - на стороне сервера.
1151850]
Параметр --no-keepalive полезен только для пакетов поддержки активности TCP, как упоминалось в этой заархивированной ветке на веб-сайте curl: https://curl.haxx.se/mail /archive-2013-04/0037.html
Звучит так, будто вам нужно специально отключить пакеты поддержки активности HTTP, что будет сделано на ваших серверах с помощью keepalive_timeout 0; как упоминалось в этом потоке stackoverflow мой первый пост :)
Надеюсь, что поможет!
вы можете использовать опцию --no-keepalive. См. Больше на man curl
- no-keepalive Отключает использование сообщений keepalive для TCP-соединения, поскольку по умолчанию curl их включает.
Обратите внимание, что это задокументированное отрицательное имя параметра. Таким образом, вы можете использовать --keepalive для принудительного поддержания активности.