在 http 模式下对 HTTP/2 后端服务器的 HA 代理支持
Posted
技术标签:
【中文标题】在 http 模式下对 HTTP/2 后端服务器的 HA 代理支持【英文标题】:HA Proxy support for HTTP/2 backend servers in http mode 【发布时间】:2018-07-06 03:51:11 【问题描述】:我有一个支持 HTTP/2 并在 TLS1.2 上运行的 tomcat 9.0.2 服务器。下面是 server.xml 中的连接器配置
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
address="0.0.0.0"
maxThreads="150" SSLEnabled="true" asyncTimeout="10000" maxHeaderCount="50"
maxPostSize="1048576" scheme="https" secure="true" compression="force"
compressionMinSize="2048" maxConnections="10000">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig protocols="TLSv1.2">
<Certificate certificateKeystoreFile="$keystore.file.path"
certificateKeystorePassword="$keystore.password"
certificateKeyAlias="$server.cert.alias"
certificateKeystoreType="$keystore.type" />
</SSLHostConfig>
</Connector>
我使用的是 HA Proxy 1.8,配置如下
frontend mydomain-ux
mode http
bind <ip>:8080 ssl crt /etc/certs/mydomain.com.cert.pem
http-request set-var(txn.path) path
acl mydomain hdr_end(host) -i mydomain.com
use_backend mydomain_server if mydomain
backend mydomain_server
mode http
server mydomain_backeend_server <server-ip>:8443 ssl
由于我有多个基于主机的后端,我不能使用 TCP 模式并通过 HTTP/2 SSL 终止
有没有办法在后端模式 http 中终止 HTTP/2?
【问题讨论】:
【参考方案1】:据我所知,HAProxy 不支持后端的 HTTP/2。他们只有recently announced front end support。 (2019 年 1 月 18 日编辑 - 自 v1.9 中添加 - https://www.haproxy.com/blog/haproxy-1-9-has-arrived/)。
即使没有后端 HTTP/2 支持,可以在 HTTPS 上终止前端,然后通过 TCP(不使用 HTTPS)转发到后端,并且 可以 可以使用 HTTPS 的 SNI 部分来执行您想要的可选路由(顺便说一句,这是完全未经测试的):
frontend mydomain-ux
mode tcp
bind <ip>:8080 ssl crt /etc/certs/mydomain.com.cert.pem alpn h2,http/1.1
use_backend mydomain_server if ssl_fc_sni mydomain.com
use_backend mydomain_server2 if ssl_fc_sni mydomain2.com
default_backend mydomain_server
backend mydomain_server
mode tcp
server mydomain_backeend_server <server-ip>:8081
这将允许您的后端在端口 8081 上使用 HTTP/2,但不使用 HTTPS(端口 8443),甚至可以在 1.8 之前的 HAProxy 上工作(当添加了前端 HTTP/2 支持时)。但是,这意味着您的 Tomcat 需要在没有 SSL 的情况下进行设置。
HAProxy 也不建议使用 SNI 主机进行路由,如 this answer 和 mailing thread it refers to 中所述。另外,SNI 支持并不是普遍的(尽管从所有实际意图来看,除非支持像 XP 上的 IE8 这样的非常旧的浏览器)。
您应该问自己的另一个问题是if you really need HTTP/2 in the backend or if just supporting this at the HAProxy level is enough?
【讨论】:
根据建议,我会等到后端服务器严重需要 HTTP/2。接受了答案,但我现在没有尝试规定的配置。 是的,这就是我推荐的。当有严重需求时,HAProxy 可能会在后端原生支持它。老实说,上面有点破解。 haproxy 1.9 发布并支持后端 HTTP/2 haproxy.com/blog/haproxy-1-9-has-arrived > 开启后,您可以在后端服务器上使用 HTTP/2。将 alpn h2 添加到服务器行(或 alpn h2,http/1.1,如果您希望让 HAProxy 与服务器协商协议)。 谢谢。更新了答案以反映这一点。【参考方案2】:我在 Barry Pollard 上一篇文章的基础上做了一个完整的 h2 管道基础,并进行了一些修改,现在它的工作已经足够好,可以在开发中使用。需要进行一些进一步的测试来清除生产路径。但至少它的工作。
浏览器不支持 h2 明文 (h2c),因为 google 希望每个人都使用 ssl,但它在 2 个 httpd 服务器之间工作正常(使用 apache 测试,但不使用 nginx 或 tomcat 或其他任何 httpd)。
frontend mydomain-ux
mode tcp
bind 0.0.0.0:443 ssl crt /etc/ssl/tdl.pem alpn h2,h2c,http/1.1
bind 0.0.0.0:80 alpn h2,h2c,http/1.1
use_backend mydomain_server if ssl_fc_alpn -i h2
default_backend mydomain_server
backend mydomain_server
mode tcp
http-request add-header X-Forwarded-Proto https
server mydomain_backeend_server 1.1.1.1:80
server mydomain_backeend_server2 1.1.1.2:80
这是我从后端 access_log 看到的:
1.1.1.3 - - [17/Jan/2019:10:57:49 -0500] "GET / HTTP/2.0" 403 3985 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/ 537.36(Khtml,如 Gecko)Chrome/71.0.3578.98 Safari/537.36"
【讨论】:
模式 tcp 和 http-request 在同一个后端?那一定是错字吧?以上是关于在 http 模式下对 HTTP/2 后端服务器的 HA 代理支持的主要内容,如果未能解决你的问题,请参考以下文章
设计模式-单例模式下对多例的思考(案例:Server服务器)
Windows 2016 IIS 上 HTTP/2 的混合模式