Я пытаюсь выяснить, как последовательно отключать поддержку активности на различных клиентских машинах, которые выдают 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
Чтобы отключить поддержку активности, я пробовал использовать -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 всегда используется одним из моих двух клиентов. Поэтому я полагаю, что конфигурация целевого сервера также играет в этом некоторую роль.
редактировать: Чтобы еще больше усложнить ситуацию, если от клиентов 1 и 2 я отправляю запросы на целевой сервер через ab
то соединение разрывается мгновенно. Это ожидается, потому что ab
использует HTTP/1.0
и нет HTTP/1.1
. Но затем, если я нацелен на старый дистрибутив с помощью apache, в обоих случаях соединение останется открытым. Это означает, что принимающая сторона тоже играет роль.
Редактировать 2: Я все схватил /proc/sys/net/ipv4/
настройки обоих клиентов через:
for file in /proc/sys/net/ipv4/*
do
echo "$file $(cat $file)"
done
и их можно найти здесь:
Параметр --no-keepalive полезен только для пакетов поддержки активности TCP, как упоминалось в этой заархивированной ветке на веб-сайте curl: https://curl.haxx.se/mail/archive-2013-04/0037.html
Похоже, вам нужно специально отключить HTTP-пакеты поддержки активности, что будет сделано на ваших серверах с помощью keepalive_timeout 0; как упоминалось в этом потоке stackoverflow https://stackoverflow.com/questions/24924237/linux-curlnginx-cant-request-with-no-keepalive.
Извините, если форматирование отключено, это мой первый пост :)
Надеюсь, это поможет!
За https://ec.haxx.se/usingcurl-persist.html
curl всегда будет пытаться поддерживать соединения и повторно использовать существующие соединения, насколько это возможно.
Следовательно, вы не можете использовать его, используя те инструменты, которые есть.
Как отметил @ pl-nowlan в своем ответе, единственный способ сделать это - на стороне сервера.
вы можете использовать опцию --no-keepalive. Смотрите больше на man curl
--no-keepalive Отключает использование сообщений keepalive для TCP-соединения, поскольку по умолчанию curl их включает.
Обратите внимание, что это задокументированное отрицательное имя параметра. Таким образом, вы можете использовать --keepalive для обеспечения активности.