Отдельный прокси-сервер может быть полезными, когда на штатном HTTP-сервере нет должной поддержки HTTP/2 или вы, по тем или иным причинам, не можете обновить версию сервера. Я попробовал некоторые из большого списка, существующих на данный момент, серверов.
nghttp2
Проект nghttp2 представляет собой библиотеку для работы с потоками данных и набор инструментов, написанных на базе этой библиотеки.
Процесс сборки несложен и подробно описан в документации. В результате компиляции вы получите:
- nghttp — клиент HTTP/2;
- nghttpd — сервер;
- nghttpx — прокси-сервер;
- h2load — инструмент нагрузочного тестирования.
Клиент по своей функциональности очень напоминает curl
, а утилита нагрузочного тестирования — ab
.
Прокси-сервер имеет несколько режимов работы и множество настроек. Тем не менее, его настройка в режиме обратного прокси оказалось очень простой.
$ nghttpx --frontend=*,443 \
--backend=prod.noteskeeper.ru,80 \
--tls-proto-list=TLSv1.2,TLSv1.1,TLSv1.0 \
--dh-param-file=/etc/letsencrypt/live/noteskeeper.ru/dhparam.pem \
/etc/letsencrypt/live/noteskeeper.ru/privkey.pem \
/etc/letsencrypt/live/noteskeeper.ru/fullchain.pem
Обратный прокси будет слушать порт 443
на всех интерфейсах и передавать запросы на хост prod.noteskeeper.ru
. Остальные параметры нужны для настройки TLS.
Ещё, возможно, будет полезен ключ --host-rewrite
. Если он будет указан, то прокси заменит заголовок Host
в запросе к бекэнду на значение из исходного запроса от клиента. Например, рассмотрим следующую ситуацию. Пусть на одном сервере будет настроен хостинг для моего блога по адресу noteskeeper.ru
. На другом сервере я запускаю прокси. Теперь я должен заменить адрес в DNS-записи A
на тот, который будет указывать на прокси и добавить ещё одну запись A на сайт, но с другим под-доменом (назовём его prod
). Проблема в том, что хостинг знает только о сайте noteskeeper.ru
и ничего не знает о prod.noteskeeper.ru
. Из-за этого сайт начнёт отвечать ошибками с кодом 404. С таким же успехом мы могли бы в конфигурации бекэнда nghttpx указать просто IP-адрес, но домен всё же удобнее. Тут нам и поможет замена заголовка — клиент будет обращаться по адресу
noteskeeper.ru
и этот же адрес будет передаваться в запросе на сайт.
Минусом решения на базе nghttpx является то, что вам придётся запустить несколько его экземпляров с разными параметрами чтобы обслуживать запросы с или без www , а так же на 80 порту без шифрования и на 443 с шифрованием.
h2o
Проект h2o развивается как альтернатива Nginx и представляет собой высокопроизводительный веб-сервер с возможностью обратного прокси. Собирается он так же из исходников без каких-либо сложностей. В документации описаны все требуемые условия.
Сервер настраивается с помощью конфигурационного файла. В моём случае он получился вот таким:
hosts:
"noteskeeper.ru:80":
listen:
port: 80
paths:
"https://noteskeeper.ru/heritage/":
redirect: https://noteskeeper.ru/
"noteskeeper.ru:443":
listen:
port: 443
ssl:
key-file: /etc/letsencrypt/live/noteskeeper.ru/privkey.pem
certificate-file: /etc/letsencrypt/live/noteskeeper.ru/fullchain.pem
dh-file: /etc/letsencrypt/live/noteskeeper.ru/dhparam.pem
paths:
"https://noteskeeper.ru/heritage/":
proxy.reverse.url: "http://prod.noteskeeper.ru:80/"
proxy.preserve-host: ON
# Включаем компрессию данных.
# Без этой настройки клиент получит данные в не сжатом виде,
# даже если они были сжаты на бекэнде.
gzip: ON
# Передавать быстрее файлы с большим приоритетом.
# Изначально к таким файлам относятся CSS и JS.
http2-reprioritize-blocking-assets: ON
# Включить проверку кешировани для файлов, которые
# были переданы с помощью server push.
http2-casper: ON
Вот таким способом можно указать типы данных, которые должны иметь повышенный приоритет при их передачи.
file.mime.addtypes:
"application/x-javascript":
extensions: [".js"]
is_compressible: yes
priority: highest
Запускается сервер командой:
$ h2o -c ./noteskeeper.conf
Заключение
Оба сервера, которые я протестировал, понимают заголовки ответа Link
со значением rel=preload
. Это позволит управлять очередью доставки контента пользователю. Ресурсы, которые вы указали, начнут отсылаться по сети ещё до того как браузер их запросит.
Для поддержки HTTP/2 вам придётся получить SSL-сертификат.
Ни одно из этих решений пока не выпущено в качестве собранного пакета. А это значит нужно будет повозиться с настройкой запуска демона.