Spring应用和外部Tomcat服务器HTTP2

huangapple go评论75阅读模式
英文:

Spring application and external tomcat server HTTP2

问题

当我在外部Tomcat服务器上部署Spring Boot应用程序时,我需要在Tomcat服务器上配置HTTP2吗?我对在通过浏览器或其他客户端(例如Postman)调用部署在Tomcat内的Spring应用程序时通信的方式感到有些困惑。

我已在Tomcat上启用了HTTP2并进行了验证:

0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] "GET / HTTP/2.0" 200 11408
0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] "GET /tomcat.svg HTTP/2.0" 200 68761
0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] "GET /tomcat.css HTTP/2.0" 200 5895

我还配置了我的Spring Boot应用程序,使用了此链接中提到的步骤来使用HTTP2

但是,当我调用部署在外部Tomcat上的我的RestController时,仍然获得HTTP 1.1

127.0.0.1 - - [08/Jan/2023:23:41:26 +0530] "HEAD /demo-0.0.1-SNAPSHOT/ HTTP/1.1" 200 -
127.0.0.1 - - [08/Jan/2023:23:41:51 +0530] "HEAD /demo-0.0.1-SNAPSHOT/getMessage HTTP/1.1" 200 -

其中demo-0.0.1-SNAPSHOT是已部署的构件。

我使用curl验证了这一点:

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 41
Date: Sun, 08 Jan 2023 18:11:51 GMT

我在这里错过了什么?

我的application.properties文件如下:

# 配置SSL
server.port=8443
server.ssl.key-store-type=pkcs12
server.ssl.key-store=classpath:springboot.p12
server.ssl.key-store-password=password
server.ssl.key-alias=springboot

# 启用http2
server.http2.enabled=true

我已使用以下命令正确创建了Keystore

keytool -genkeypair -alias springboot -keyalg RSA -keysize 4096 -storetype PKCS12 -keystore springboot.p12 -validity 3650 -storepass password

编辑1:
Spring Boot版本 - 2.7.2
Tomcat服务器 - 9.0.70

在我的server.xml中,我已注释并编辑了以下Connector

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
                   maxThreads="200" SSLEnabled="true">
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="ssl/tomcat.jks"
    					 certificateKeyAlias="tomcat"
    					 certificateKeystorePassword="password"
                             type="RSA" />
        </SSLHostConfig>
    </Connector>

这帮助我在Tomcat上同时启用了TLS和HTTP2。问题在于,当我部署Spring Boot应用程序并调用该应用程序的RestController时,我仍然得到HTTP1.1响应。调用Tomcat Web服务会得到正确的HTTP2响应。

英文:

When I deploy a spring boot application on an external tomcat server, do I need to configure HTTP2 on the tomcat server as well my spring boot application? I am a bit confused here about how the communication occurs when I call my spring application deployed inside of Tomcat via the browser or any other client say, Postman.

I have enabled HTTP2 on Tomcat and verified the same:

0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] &quot;GET / HTTP/2.0&quot; 200 11408
0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] &quot;GET /tomcat.svg HTTP/2.0&quot; 200 68761
0:0:0:0:0:0:0:1 - - [08/Jan/2023:18:28:44 +0530] &quot;GET /tomcat.css HTTP/2.0&quot; 200 5895

and I have configured my spring boot application to use HTTP2 as well using the steps mentioned in this link.

When I am calling my RestController deployed in the external tomcat, I am still getting HTTP 1.1

127.0.0.1 - - [08/Jan/2023:23:41:26 +0530] &quot;HEAD /demo-0.0.1-SNAPSHOT/ HTTP/1.1&quot; 200 -
127.0.0.1 - - [08/Jan/2023:23:41:51 +0530] &quot;HEAD /demo-0.0.1-SNAPSHOT/getMessage HTTP/1.1&quot; 200 -

where demo-0.0.1-SNAPSHOT is the deployed artifact.

I verified the same using curl

HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 41
Date: Sun, 08 Jan 2023 18:11:51 GMT

What am I missing here?

My application.properties file looks like:

# configuring SSL
server.port=8443
server.ssl.key-store-type=pkcs12
server.ssl.key-store=classpath:springboot.p12
server.ssl.key-store-password=password
server.ssl.key-alias=springboot

# enabling http2
server.http2.enabled=true

and I have created the Keystore correctly using the following command:

keytool -genkeypair -alias springboot -keyalg RSA -keysize 4096 -storetype PKCS12 -keystore springboot.p12 -validity 3650 -storepass password

Spring应用和外部Tomcat服务器HTTP2

EDIT 1:
Spring Boot version - 2.7.2
Tomcat server - 9.0.70

In my server.xml, I have commented and edited the following Connector:

&lt;Connector port=&quot;8443&quot; protocol=&quot;org.apache.coyote.http11.Http11NioProtocol&quot;
               maxThreads=&quot;200&quot; SSLEnabled=&quot;true&quot;&gt;
		&lt;UpgradeProtocol className=&quot;org.apache.coyote.http2.Http2Protocol&quot; /&gt;
        &lt;SSLHostConfig&gt;
            &lt;Certificate certificateKeystoreFile=&quot;ssl/tomcat.jks&quot;
						 certificateKeyAlias=&quot;tomcat&quot;
						 certificateKeystorePassword=&quot;password&quot;
                         type=&quot;RSA&quot; /&gt;
        &lt;/SSLHostConfig&gt;
    &lt;/Connector&gt;

which has helped me enable TLS as well as HTTP2 both on Tomcat. The problem is when I am deploying a spring boot application and making rest calls to that application's RestController, I am getting HTTP1.1 response. Making calls to Tomcat webservices is giving correct HTTP2 response.

答案1

得分: 1

Tomcat作为独立服务器,默认在其server.xml中禁用了http 2连接器。

Spring Boot 2,适用于Tomcat 9

如果这是一个部署为WAR应用的spring boot 2,那么它可能使用的是Tomcat 9。

您需要在部署的服务器conf目录下找到您的Tomcat 9(Server.xml)http2连接器,取消注释此连接器,并提供必要的证书文件。

您需要取消注释以下部分:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
                    maxThreads="150" SSLEnabled="true">
             <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
             <SSLHostConfig>
                 <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                              certificateFile="conf/localhost-rsa-cert.pem"
                              certificateChainFile="conf/localhost-rsa-chain.pem"
                              type="RSA" />
             </SSLHostConfig>
         </Connector>

Spring Boot 3,Tomcat 10或更高版本

如果您有一个部署为WAR应用的spring boot 3,那么这应该使用Tomcat 10或更高版本。

您需要在部署的服务器conf目录下找到您的Tomcat 10(Server.xml)http2连接器,取消注释并提供必要的证书文件。

您需要取消注释以下部分:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
                    maxThreads="150" SSLEnabled="true">
             <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
             <SSLHostConfig>
                 <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                              type="RSA" />
             </SSLHostConfig>
         </Connector>
英文:

Tomcat as standalone sever has by default in it's sever.xml disabled the connector for http 2.

Spring Boot 2, up to Tomcat 9

If this is a spring boot 2 deployed as war application then this could be using up to Tomcat 9.

You must find your Tomcat 9 (Server.xml) connector for http2 under the deployed server conf directory and uncomment this connector, while also providing the necessary certificate files.

You need to uncomment the

> <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
> maxThreads="150" SSLEnabled="true" >
> <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
> <SSLHostConfig>
> <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
> certificateFile="conf/localhost-rsa-cert.pem"
> certificateChainFile="conf/localhost-rsa-chain.pem"
> type="RSA" />
> </SSLHostConfig>
> </Connector>

Spring Boot 3, Tomcat 10 or later

In case you have a spring boot 3 deployed as war application then this should be using Tomcat 10 or later.

You must find your Tomcat 10 (Server.xml) connector for http2 under the deployed server conf directory and uncomment while also providing the necessary certificate file.

> <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
> maxThreads="150" SSLEnabled="true">
> <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
> <SSLHostConfig>
> <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
> type="RSA" />
> </SSLHostConfig>
> </Connector>

答案2

得分: 0

我找到了解决方案。在将Spring Boot应用部署到外部Tomcat时,无需在Spring属性文件中指定服务器SSLHTTP2参数,因为Tomcat会处理所有HTTPS请求。我试图混合两件事情。

如果我们使用内嵌Tomcat服务器部署,配置Spring Boot应用以支持HTTP2将起作用,我已经能够使用Chrome浏览器验证这一点。

在撰写此帖子时,Postman仍然不支持HTTP2请求,因此,在Tomcat访问日志中看到HTTP 1.1协议。我认为curl请求也存在相同的问题。由于我的证书是自签名的,我正在使用选项-k-sI。也许这就是我得到以下响应的原因:

HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 10 Jan 2023 18:09:29 GMT

当运行curl -k -sI https://localhost:8443时。我会找出为什么我得到HTTP 1.1并在这里更新。

分享这个答案以帮助下次遇到这个问题的任何人。

英文:

I found the solution. While deploying a spring boot application on external tomcat there is no need to specify Server SSL and HTTP2 parameters in the spring properties file as Tomcat will handle all the HTTPS requests. I was trying to mix 2 things.

Configuring the Spring Boot application to support HTTP2 will work if we are deploying using an embedded Tomcat server and I was able to verify that with Chrome browser.

As of writing this post, Postman still doesn't support HTTP2 requests, hence, I was seeing HTTP 1.1 protocol in the Tomcat access log. The same thing I believe is the issue with curl request. As my certificate is self-signed, I am using options -k and -sI. Maybe that's the reason, I am getting the response :

HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 10 Jan 2023 18:09:29 GMT

when running curl -k -sI https://localhost:8443. I will figure out why I am getting HTTP 1.1 and update it here.

Sharing this answer to help anyone coming across this question next time.

huangapple
  • 本文由 发表于 2023年1月9日 02:26:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050323.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定