0

Включение HTTP/2 в Tomcat для Spring Boot

10

Проблема: Как включить поддержку HTTP/2 в приложении Spring Boot?

Я использую Tomcat 8.5, который станет стандартным в Spring Boot 1.4, и он поддерживает HTTP/2. Мне нужно узнать, как правильно включить поддержку HTTP/2 в моем приложении Spring Boot. Какие шаги необходимо предпринять для этого?

3 ответ(ов)

0

Чтобы добавить протокол HTTP/2 в коннектор Tomcat, необходимо настроить встроенный контейнер Tomcat. Вот как это можно сделать в зависимости от используемой версии Java.

Для Java 8:

@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
    return (container) -> {
        if (container instanceof TomcatEmbeddedServletContainerFactory) {
            ((TomcatEmbeddedServletContainerFactory) container)
                .addConnectorCustomizers((connector) -> {
                    connector.addUpgradeProtocol(new Http2Protocol());
                });
        }
    };
}

Для Java 7:

@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
    return new EmbeddedServletContainerCustomizer() {

        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            if (container instanceof TomcatEmbeddedServletContainerFactory) {
                ((TomcatEmbeddedServletContainerFactory) container)
                    .addConnectorCustomizers(new TomcatConnectorCustomizer() {
                        @Override
                        public void customize(Connector connector) {
                            connector.addUpgradeProtocol(new Http2Protocol());
                        }
                    });
            }
        }
    };
}

Эти примеры кода демонстрируют, как можно адаптировать настройки рабочего контейнера для поддержки HTTP/2, в зависимости от версии Java, которую вы используете. Не забудьте добавить необходимые зависимости для использования HTTP/2 в вашем проекте.

0

Самый элегантный и производительный способ активировать HTTP/2 в приложении на Spring Boot выглядит следующим образом.

Сначала, как упоминалось в ответе Эндии Уилкинсона, необходимо включить HTTP/2 на уровне Tomcat:

@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
    return (container) -> {
        if (container instanceof TomcatEmbeddedServletContainerFactory) {
            ((TomcatEmbeddedServletContainerFactory) container)
                    .addConnectorCustomizers((connector) -> {
                connector.addUpgradeProtocol(new Http2Protocol());
            });
        }
    };
}

Если вы не используете встроенный Tomcat, то можно настроить слушатель HTTP/2 так:

<Connector port="5080" protocol="HTTP/1.1" connectionTimeout="20000">
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
</Connector>

Не забудьте, что вам нужен Tomcat >= 8.5.

Далее стоит использовать HAProxy (версии >= 1.7) перед Tomcat для управления шифрованием.

Клиент будет общаться по https с HAProxy, а HAProxy будет использовать незашифрованный HTTP/1.1 или HTTP/2 для общения с бэкендом в зависимости от запроса клиента. Никаких ненужных переводов протоколов не будет.

Подходящая конфигурация HAProxy будет следующей:

# Создание PEM: cat cert.crt cert.key ca.crt > /etc/ssl/certs/cert.pem

global
    tune.ssl.default-dh-param 2048
    ssl-default-bind-options no-sslv3 no-tls-tickets force-tlsv12
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
    chroot /var/lib/haproxy
    user haproxy
    group haproxy

defaults
    timeout connect 10000ms
    timeout client 60000ms
    timeout server 60000ms

frontend fe_https
    mode tcp
    rspadd Strict-Transport-Security:\ max-age=31536000;\ includeSubDomains;\ preload
    rspadd X-Frame-Options:\ DENY
    bind *:443 ssl crt /etc/ssl/certs/cert.pem alpn h2,http/1.1
    default_backend be_http

backend be_http
    mode tcp
    server domain 127.0.0.1:8080
    # compression algo gzip # не работает в режиме "tcp"
    # compression type text/html text/css text/javascript application/json

Исправление 2019

Я столкнулся с двумя проблемами при использовании режима "tcp":

  1. Компрессия не работает, так как она зависит от режима HTTP. Поэтому бэкенд должен позаботиться об этом.
  2. Бэкенд не может видеть IP-адрес клиента. Вероятно, мне нужен NAT. Всё ещё investigate...

В общем, так как HAProxy проксирует соединение на более низком уровне, доступа к любым HTTP-данным нет.

0

Чтобы настроить SSL в Spring Boot 2, вам сначала потребуется создать сертификат. Это можно сделать с помощью следующей команды:

keytool -genkey -keyalg RSA -alias my-the-best-api -keystore c:\tmp\keystore.store -storepass secret -validity 3650 -keysize 2048

После генерации сертификата добавьте его в classpath вашего проекта и внесите необходимые настройки в файл application.properties. Вот пример конфигурации:

server.http2.enabled=true
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret

Не забудьте заменить путь к хранилищу ключей на правильный, если вы переместите файл keystore.jks в другое место в вашем проекте. После этих шагов ваше приложение должно быть доступно по HTTPS на порту 8443.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь