Вопрос или проблема
У меня возникла проблема при отправке запроса QUIC/HTTP3 на мой сервер.
Мой сервер работает на nginx с включенным QuicTLS и модулем http3. Вот вывод моей команды nginx -V
версия nginx: NGINX-QuicTLS с ModSec/1.27.1
собрано с помощью gcc 13.2.0 (Ubuntu 13.2.0-23ubuntu4)
собрано с OpenSSL 3.3.0+quic 30 янв 2024
Поддержка TLS SNI включена
аргументы настройки: --build= --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-threads --with-file-aio --with-libatomic --with-pcre --without-poll_module --without-select_module --with-openssl=/src/openssl --with-openssl-opt="no-ssl3 no-ssl3-method no-weak-ssl-ciphers" --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_realip_module --with-http_v2_module --with-http_v3_module --with-http_ssl_module --with-http_realip_module --with-http_gunzip_module --with-http_addition_module --with-http_gzip_static_module --with-http_auth_request_module --with-debug
Я пишу программу на стороне клиента, которая в данный момент просто пытается отправить очень простой GET-запрос для запроса пути /
на моем сервере, используя QUIC.
Библиотека на стороне клиента, которую я использую для quic, – это msquic, и я использую библиотеку nghttp3 для связи и кодирования/декодирования потоков qpack.
Я не смог получить успешный ответ от сервера, каждый раз, когда я отправляю запрос, мой сервер инициирует отключение со стороны клиента, и при отладке моего подключения с nginx.
Я вижу следующие журналы в моем /var/log/nginx/error.log
2024/10/05 00:32:49 [debug] 800#800: *3 http3 отправка настроек
2024/10/05 00:32:49 [debug] 800#800: *3 quic слишком много серверных uni потоков:0
2024/10/05 00:32:49 [error] 800#800: *3 не удалось создать серверный поток во время обработки кадров, клиент: 174.108.244.188, сервер: 0.0.0.0:443
2024/10/05 00:32:49 [debug] 800#800: *3 пост событие 0000634AA9045F68
2024/10/05 00:32:49 [debug] 800#800: *3 quic пакет завершен rc:-1 уровень:hs decr:1 pn:2 perr:0
2024/10/05 00:32:49 [debug] 800#800: *3 quic закрытие инициировано rc:-1
2024/10/05 00:32:49 [debug] 800#800: *3 таймер события удалён: 6: 104359
2024/10/05 00:32:49 [debug] 800#800: *3 quic закрытие немедленное term:1 drain:0 ошибка приложения:259 "не удалось создать серверный поток"
2024/10/05 00:32:49 [debug] 800#800: *3 quic sendto пакет приложения max:1200 min:0
2024/10/05 00:32:49 [debug] 800#800: *3 quic кадр tx приложение:0 CONNECTION_CLOSE_APP ошибка:259 не удалось создать серверный поток
Кажется, что у моего сервера нет доступных оставшихся уни-направленных потоков…
Вот мой nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
quic_bpf on;
events {
worker_connections 1024;
debug_connection 174.108.244.188;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
log_format quic '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$http3"';
access_log /var/log/nginx/access.log quic;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
http3 on;
http3_hq off;
http3_max_concurrent_streams 1024;
http3_stream_buffer_size 64k;
quic_active_connection_id_limit 128;
quic_retry off;
ssl_early_data on;
quic_gso on;
include /etc/nginx/conf.d/*.conf;
}
Согласно документации модуля http3:
http3_max_concurrent_streams устанавливает максимальное количество параллельных потоков, но не кажется, чтобы это определяло, являются ли они двунаправленными или уни-направленными потоками.
https://nginx.org/en/docs/http/ngx_http_v3_module.html
Я не вижу другого способа это настроить.
Я смотрю на исходный код:
https://github.com/nginx/nginx/blob/e24f7ccc161f1a2a759eb27263ec9af4fc7c8e96/src/event/quic/ngx_event_quic_streams.c#L83C20-L83C50
и, похоже, что он сравнивает с этой переменной:
streams.server_max_streams_uni
но даже если я напишу это в конфигурации, ничего не изменится, мой сервер по-прежнему выдаёт 0 уни-направленных потоков.
Я в полном недоумении и не знаю, что ещё мне следует сделать.
Ответ или решение
Проблема, с которой вы столкнулись, связана с настройками QUIC и HTTP/3 в вашем конфигурационном файле Nginx. Судя по логам, ошибка возникает из-за того, что сервер не может создать поток: "quic too many server uni streams:0". Это означает, что сервер не имеет доступных недирективных (unidirectional) потоков для обработки вашего запроса.
Вот несколько рекомендаций, которые помогут вам исправить эту проблему:
-
Установите максимальное количество недирективных потоков:
В вашей конфигурации Nginx нет параметра, который определяет максимальное количество недирективных потоков (unidirectional streams). Попробуйте добавить следующий параметр в блокhttp
вашегоnginx.conf
:http3_max_concurrent_streams_uni 1024;
Это должно позволить серверу иметь доступ к новым недирективным потокам.
-
Проверьте параметры QUIC:
Убедитесь, что вы настроили все необходимые параметры QUIC. Добавьте и проверьте следующие параметры в вашей конфигурации:quic_max_concurrent_streams 1024; # максимальное количество потоков quic_max_unidirectional_streams 1024; # конкретно для недирективных потоков
-
Версия Nginx и модули:
Проверьте, что ваша версия Nginx полностью поддерживает HTTP/3 и QUIC. Убедитесь, что все модули и зависимости установлены правильно. Иногда стоит обновить версию Nginx до последней стабильной, чтобы избежать проблем с совместимостью. -
Перепроверьте конфигурацию SSL:
Убедитесь, что ваша конфигурация SSL корректна. Например, используйте правильные сертификаты и ключи. Неправильные настройки SSL могут вызвать проблемы с установлением соединения. -
Тестируйте с другими клиентами:
Попробуйте протестировать ваш сервер с использованием других библиотек клиента QUIC, таких какquiche
илиaioquic
, чтобы узнать, воспроизводится ли проблема. Это поможет исключить вероятность ошибки в коде вашего клиента наmsquic
. -
Логи отладки:
Включите дополнительные отладочные логи для QUIC, чтобы получить больше информации о происходящем. Вы можете увеличить уровень детализации логов, изменивerror_log
:error_log /var/log/nginx/error.log debug;
-
Перезапустите Nginx:
После внесения изменений в конфигурацию не забудьте проверить конфигурацию на наличие ошибок с помощью команды:nginx -t
После тестирования перезапустите сервер:
systemctl restart nginx
-
Обратитесь к документации:
Ознакомьтесь с официальной документацией по настройке и отладке модуля HTTP/3 в Nginx: https://nginx.org/en/docs/http/ngx_http_v3_module.html. Убедитесь, что все настройки соответствуют требованиям вашей среды.
Следуя этим шагам, вы сможете устранить проблему с потоками QUIC/HTTP/3 на своем сервере Nginx. Если проблема все еще не решена, возможно, имеет смысл обратиться к сообществу Nginx или на специальные форумы для получения более детальной помощи.