Tomcat 8.5
, qui sera la valeur par défaut dans Spring Boot 1.4
, (à paraître demain) prend en charge http2
.
Comment puis http2
être activé dans un Spring Boot
demande?
La façon la plus élégante et la plus performante d'activer HTTP/2
avec une application Spring Boot suit ici.
Tout d'abord, comme mentionné dans la réponse d'Andy Wilkinson, vous devez activer HTTP/2 au niveau de Tomcat:
@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
return (container) -> {
if (container instanceof TomcatEmbeddedServletContainerFactory) {
((TomcatEmbeddedServletContainerFactory) container)
.addConnectorCustomizers((connector) -> {
connector.addUpgradeProtocol(new Http2Protocol());
});
}
};
}
Si vous n'utilisez pas de Tomcat intégré, vous pouvez configurer l'écoute HTTP/2 comme ceci:
<Connector port="5080" protocol="HTTP/1.1" connectionTimeout="20000">
<UpgradeProtocol className="org.Apache.coyote.http2.Http2Protocol" />
</Connector>
N'oubliez pas que vous avez besoin de Tomcat> = 8.5.
Ensuite, vous devez utiliser HAProxy
(version> = 1.7) devant Tomcat pour vous occuper du chiffrement.
Le client parlera https à HAProxy et HAProxy parlera en clair HTTP/1.1 ou HTTP/2 au backend, comme le client l'a demandé. Il n'y aura aucune traduction de protocole inutile.
La configuration HAProxy correspondante est ici:
# Create 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 # does not work in mode "tcp"
# compression type text/html text/css text/javascript application/json
Modifier 2019
Je fais face à deux problèmes lors de l'utilisation du mode "tcp"
En règle générale, étant donné que les serveurs proxy proxy utilisent une connexion TCP de niveau inférieur, il n'y a pas d'accès à des éléments http
Vous devez ajouter le protocole de mise à niveau HTTP 2 au connecteur de Tomcat. Vous pouvez le faire en personnalisant le conteneur Tomcat intégré:
@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
return (container) -> {
if (container instanceof TomcatEmbeddedServletContainerFactory) {
((TomcatEmbeddedServletContainerFactory) container)
.addConnectorCustomizers((connector) -> {
connector.addUpgradeProtocol(new Http2Protocol());
});
}
};
}
@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());
}
});
}
}
};
}
Dans Spring Boot 2.1 et supérieur, c'est aussi simple que d'ajouter cette propriété à votre fichier .properties (ou .yml):
server.http2.enabled=true
Vous pouvez également le faire par programme comme ceci (dans l'une de vos classes de configuration):
@Bean
public ConfigurableServletWebServerFactory tomcatCustomizer() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(connector -> connector.addUpgradeProtocol(new Http2Protocol()));
return factory;
}
Dans Spring Boot 2, vous avez d'abord besoin d'un certificat - il peut être généré comme ceci:
keytool -genkey -keyalg RSA -alias my-the-best-api -keystore c:\tmp\keystore.store -storepass secret -validity 3650 -keysize 2048
Ensuite, il vous suffit d'ajouter ce certificat à classpath et d'ajouter les propriétés nécessaires à application.properties:
server.http2.enabled=true
server.port = 8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-password=secret