Использование http2_push с nginX в сочетании с HAProxy не работает - PullRequest
0 голосов
/ 25 апреля 2018

Я не могу заставить работать HTTP / 2 push, когда nginX настроен за HaProxy. Однако работает , когда nginX напрямую попадает в веб-браузер.

Провел много исследований, но не нашел намеков. Надеюсь, кто-нибудь знает, что я делаю неправильно. См. Конфигурацию и дальнейшие наблюдения ниже.

Конфигурация

Соответствующая конфигурация HaProxy (версия 1.8.7) задается следующим образом:


    frontend appname
        bind *:443 ssl crt certificate.pem alpn h2,http/1.1
        mode tcp
        use_backend app-http2 if { ssl_fc_alpn -i h2 }
        default_backend app

    backend app-http2
        mode tcp
        server lamp2 127.0.0.1:8002 check send-proxy

И соответствующая конфигурация nginX (версия 1.14.0) выглядит следующим образом:


    http {
        # This is the one I would like to use
        server {
            listen       8002 http2 proxy_protocol;

            server_name  _;
            root         /usr/share/nginx/html;

            location / {
                http2_push /image.jpg;
            }
        }

        # This one can be accessed directly; and *does* work
        server {
            listen       8004 http2 ssl;

            ssl_certificate certificate.pem;
            ssl_certificate_key private.key;

            server_name  _;
            root         /usr/share/nginx/html;

            location / {
                http2_push /image.jpg;
            }
        }
    }

Наблюдения

  • В журналах nginx я могу убедиться, что оба способа доступа к контенту используют HTTP2.
  • Когда я использую Chrome для доступа к странице, я вижу, что push используется только при непосредственном посещении nginX

Обновление 9 мая 2018 Все еще не решено. Но люди, похоже, согласны с тем, что это ошибка. Я открыл проблему на их трекере: https://trac.nginx.org/nginx/ticket/1549#ticket

Обновление 26 апреля 2018

Кажется, проблема не только в http2 push. Если я регистрирую переменную $scheme nginX, она всегда устанавливается на http. Оба при доступе с http как с http2.

Так что, похоже, проблема в этом. Однако я не уверен, как я могу это исправить. Haproxy работает в режиме TCP; таким образом, вероятно, не будет делать ничего плохого.

Связанная (но, возможно, устаревшая) тема переполнения стека - переменная схемы nginx $ за балансировщиком нагрузки . Но этот ответ не помогает решить эту проблему!

Обновление 25 апреля 2018

Все еще не работает. Но на шаг ближе. Запустил nghttp2 на обоих, и результаты приведены ниже.

Кажется, что в обоих случаях есть встроенный ресурс /image.jpg. Но тот, который проходит через haproxy, имеет схему, установленную на http; а не в https. Как видно из этой разницы:

diff of nghttp requests

Полагаю, из-за этого; Chrome не будет использовать этот отправленный ресурс. Я, однако, не уверен, что вызывает это!

У кого-нибудь есть подсказка?


Полный вывод обеих команд:


    nghttp -nv https://127.0.0.1:8004/

    [  0.001] Connected
    The negotiated protocol: h2
    [  0.003] send SETTINGS frame 
    (niv=2)
    [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
    [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=201, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=101, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=1, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=7, weight=1, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=3, weight=1, exclusive=0)
    [  0.003] send HEADERS frame 
    ; END_STREAM | END_HEADERS | PRIORITY
    (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
    ; Open new stream
    :method: GET
    :path: /
    :scheme: https
    :authority: 127.0.0.1:8004
    accept: */*
    accept-encoding: gzip, deflate
    user-agent: nghttp2/1.25.0
    [  0.003] recv SETTINGS frame 
    (niv=3)
    [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
    [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536]
    [SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
    [  0.003] recv WINDOW_UPDATE frame 
    (window_size_increment=2147418112)
    [  0.003] send SETTINGS frame 
    ; ACK
    (niv=0)
    [  0.003] recv SETTINGS frame 
    ; ACK
    (niv=0)
    [  0.003] recv (stream_id=13) :method: GET
    [  0.003] recv (stream_id=13) :path: /image.jpg
    [  0.003] recv (stream_id=13) :scheme: https
    [  0.003] recv (stream_id=13) :authority: 127.0.0.1:8004
    [  0.003] recv (stream_id=13) accept-encoding: gzip, deflate
    [  0.003] recv (stream_id=13) user-agent: nghttp2/1.25.0
    [  0.003] recv PUSH_PROMISE frame 
    ; END_HEADERS
    (padlen=0, promised_stream_id=2)
    [  0.003] recv (stream_id=13) :status: 200
    [  0.003] recv (stream_id=13) server: nginx/1.14.0
    [  0.003] recv (stream_id=13) date: Wed, 25 Apr 2018 15:08:26 GMT
    [  0.003] recv (stream_id=13) content-type: text/html
    [  0.003] recv (stream_id=13) content-length: 638
    [  0.003] recv (stream_id=13) last-modified: Wed, 25 Apr 2018 11:42:58 GMT
    [  0.003] recv (stream_id=13) etag: "5ae069c2-27e"
    [  0.003] recv (stream_id=13) accept-ranges: bytes
    [  0.003] recv HEADERS frame 
    ; END_HEADERS
    (padlen=0)
    ; First response header
    [  0.004] recv DATA frame 
    ; END_STREAM
    [  0.004] recv (stream_id=2) :status: 200
    [  0.004] recv (stream_id=2) server: nginx/1.14.0
    [  0.004] recv (stream_id=2) date: Wed, 25 Apr 2018 15:08:26 GMT
    [  0.004] recv (stream_id=2) content-type: image/jpeg
    [  0.004] recv (stream_id=2) content-length: 182884
    [  0.004] recv (stream_id=2) last-modified: Sat, 18 Jun 2016 15:42:26 GMT
    [  0.004] recv (stream_id=2) etag: "57656be2-2ca64"
    [  0.004] recv (stream_id=2) accept-ranges: bytes
    [  0.004] recv HEADERS frame 
    ; END_HEADERS
    (padlen=0)
    ; First push response header
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] send WINDOW_UPDATE frame 
    (window_size_increment=33248)
    [  0.004] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32925)
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.046] recv DATA frame 
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.046] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.090] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.090] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.090] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.134] recv DATA frame 
    [  0.134] recv DATA frame 
    [  0.134] recv DATA frame 
    ; END_STREAM
    [  0.134] send GOAWAY frame 
    (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])

и


    nghttp -nv https://127.0.0.1:8002/

    [  0.001] Connected
    The negotiated protocol: h2
    [  0.003] send SETTINGS frame 
    (niv=2)
    [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
    [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=201, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=101, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=1, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=7, weight=1, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=3, weight=1, exclusive=0)
    [  0.003] send HEADERS frame 
    ; END_STREAM | END_HEADERS | PRIORITY
    (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
    ; Open new stream
    :method: GET
    :path: /
    :scheme: https
    :authority: 127.0.0.1:8002
    accept: */*
    accept-encoding: gzip, deflate
    user-agent: nghttp2/1.25.0
    [  0.003] recv SETTINGS frame 
    (niv=3)
    [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
    [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536]
    [SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
    [  0.003] recv WINDOW_UPDATE frame 
    (window_size_increment=2147418112)
    [  0.003] send SETTINGS frame 
    ; ACK
    (niv=0)
    [  0.004] recv SETTINGS frame 
    ; ACK
    (niv=0)
    [  0.004] recv (stream_id=13) :method: GET
    [  0.004] recv (stream_id=13) :path: /image.jpg
    [  0.004] recv (stream_id=13) :scheme: http
    [  0.004] recv (stream_id=13) :authority: 127.0.0.1:8002
    [  0.004] recv (stream_id=13) accept-encoding: gzip, deflate
    [  0.004] recv (stream_id=13) user-agent: nghttp2/1.25.0
    [  0.004] recv PUSH_PROMISE frame 
    ; END_HEADERS
    (padlen=0, promised_stream_id=2)
    [  0.004] recv (stream_id=13) :status: 200
    [  0.004] recv (stream_id=13) server: nginx/1.14.0
    [  0.004] recv (stream_id=13) date: Wed, 25 Apr 2018 15:08:45 GMT
    [  0.004] recv (stream_id=13) content-type: text/html
    [  0.004] recv (stream_id=13) content-length: 638
    [  0.004] recv (stream_id=13) last-modified: Wed, 25 Apr 2018 11:42:58 GMT
    [  0.004] recv (stream_id=13) etag: "5ae069c2-27e"
    [  0.004] recv (stream_id=13) accept-ranges: bytes
    [  0.004] recv HEADERS frame 
    ; END_HEADERS
    (padlen=0)
    ; First response header
    [  0.004] recv DATA frame 
    ; END_STREAM
    [  0.004] recv (stream_id=2) :status: 200
    [  0.004] recv (stream_id=2) server: nginx/1.14.0
    [  0.004] recv (stream_id=2) date: Wed, 25 Apr 2018 15:08:45 GMT
    [  0.004] recv (stream_id=2) content-type: image/jpeg
    [  0.004] recv (stream_id=2) content-length: 182884
    [  0.004] recv (stream_id=2) last-modified: Sat, 18 Jun 2016 15:42:26 GMT
    [  0.004] recv (stream_id=2) etag: "57656be2-2ca64"
    [  0.004] recv (stream_id=2) accept-ranges: bytes
    [  0.004] recv HEADERS frame 
    ; END_HEADERS
    (padlen=0)
    ; First push response header
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] send WINDOW_UPDATE frame 
    (window_size_increment=33406)
    [  0.004] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.044] recv DATA frame 
    [  0.044] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.044] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.044] recv DATA frame 
    [  0.044] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.045] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.045] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.045] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.045] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    ; END_STREAM
    [  0.046] send GOAWAY frame 
    (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

В итоге я открыл билет на трекере NginX.И это исправлено.Исправление доступно в недавно выпущенной версии 1.15.1.

Исправление: принудительное использование HTTP / 2-сервера не работало, если SSL был прерван прокси-сервером перед nginx.

Спасибо за помощь!

0 голосов
/ 25 апреля 2018

Похоже, что Chrome гарантирует, что если отправка push-сообщения в потоке, соответствующем запросу, обслуживаемому по схеме https, в обещании также используется та же схема: https://chromium.googlesource.com/chromium/src/+/master/net/spdy/chromium/spdy_session.cc#1766

I 'Я не уверен, что проверка верна: RFC 7540 говорит, что сервер, отправляющий PUSH_PROMISE, должен быть авторитетным.Для http это означает, что имя хоста совпадает, поэтому браузер должен иметь возможность обрабатывать файл.

Тем не менее, даже если браузер принял push, он будет использовать его только в случае запроса против http://127.0.0.1:8002/image.jpg были выданы браузером.Если HTML был получен через https и он запросил /image.jpg, то я не уверен, что браузер согласится получить http://127.0.0.1:8002/image.jpg.

, что подводит нас к nginx, устанавливая схему как http.Я предполагаю, что это связано с тем, что haproxy выполняет SSL-завершение, поэтому ngnix видит входящее соединение в виде открытого текста, и, что касается схемы, - это http.Я не знаю достаточно о ngnix, чтобы предложить решение этой проблемы.

...