加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Golang使用HTTP/2的正确方法

发布时间:2020-12-16 09:33:03 所属栏目:大数据 来源:网络整理
导读:golang在http/2这块做的比较早,但是因为历史原因导致API比较令人迷惑,网上很多同学在抱怨。 我这里记录一下如何正确的实施HTTP/2的客户端与服务端。 HTTP/2协议 HTTP/2协议握手分2种方式,一种叫h2,一种叫h2c。 h2要求必须使用TLS加密,在TLS握手期间会顺
golang在http/2这块做的比较早,但是因为历史原因导致API比较令人迷惑,网上很多同学在抱怨。

我这里记录一下如何正确的实施HTTP/2的客户端与服务端。

HTTP/2协议

HTTP/2协议握手分2种方式,一种叫h2,一种叫h2c。

h2要求必须使用TLS加密,在TLS握手期间会顺带完成HTTPS/2协议的协商,如果协商失败(比如客户端不支持或者服务端不支持),则会使用HTTPS/1继续后续通讯。

h2c不使用TLS,而是多了一次基于HTTP协议的握手往返来完成向HTTP/2协议的升级,一般不建议使用。

GO标准库

GO的http库默认支持HTTP/2协议,只要我们使用TLS则会默认启动HTTP/2特性。

http库在设计API时并没有支持用户使用h2c,而是鼓励使用h2。

只要我们使用TLS,则http库就会默认进行HTTPS/2协商,协商失败则蜕化为HTTPS/1。

让很多开发者迷惑的点在于,当我们希望对http Client或者Server做一些更加定制化的配置时,就会覆盖掉http库的默认行为,从而导致无法启用HTTP/2协议。

下面我就会告诉大家,到底怎么保证HTTP/2协议的启用。

服务端

我们明确一定要用h2模式,也就是牺牲TLS加密的时间,但是换来的就是HTTP/2的使用便捷性。

制作证书

我们首先需要为服务端制作证书和私钥,其中证书会在收到请求时发回给客户端。

证书是我们自签的,没有第三方CA作验证,所以客户端需要关闭校验证书有效性的特性。

1,生成服务端私钥
openssl?genrsa?-out?default.key?2048
2,生成服务端证书
openssl?req?-new?-x509?-key?default.key?-out?default.pem?-days?3650

default.key是私钥,default.pem是证书。

校验证书

因为我们是X509格式签名的证书,所以程序做好先做一下有效性校验:

	//?TLS证书解析验证
	if?_,?err?=?tls.LoadX509KeyPair(G_config.ServerPem,?G_config.ServerKey);?err?!=?nil?{
		return?common.ERR_CERT_INVALID
	}

确认证书有效后,我们最终通过serverTLS传入证书和私钥,启动一个HTTPS/2服务:

	//?HTTP/2?TLS服务
	server?=?&http.Server{
		ReadTimeout:?time.Duration(G_config.ServiceReadTimeout)?*?time.Millisecond,WriteTimeout:?time.Duration(G_config.ServiceWriteTimeout)?*?time.Millisecond,Handler:?mux,}

	//?监听端口
	if?listener,?err?=?net.Listen("tcp",?":"?+?strconv.Itoa(G_config.ServicePort));?err?!=?nil?{
		return
	}

	//?拉起服务
	go?server.ServeTLS(listener,?G_config.ServerPem,?G_config.ServerKey)

除了使用ServeTLS来启动支持HTTPS/2特性的服务端之外,还可以通过http2.ConfigureServer来为http.Server启动HTTPS/2特性并直接使用Serve来启动服务。

客户端

客户端最重要的是配置Transport,所谓Transport就是底层的连接管理器,包括了协议的处理能力。

因为我们有很多定制化Client配置的需求,所以我们自己生成了一个Transport而不是内置的Transport:

	transport?=?&http.Transport{
		TLSClientConfig:?&tls.Config{InsecureSkipVerify:?true,},//?不校验服务端证书
		MaxIdleConns:?G_config.GatewayMaxConnection,MaxIdleConnsPerHost:?G_config.GatewayMaxConnection,IdleConnTimeout:?time.Duration(G_config.GatewayIdleTimeout)?*?time.Second,//?连接空闲超时
	}

其中TLS配置声明了InsecureSkipVerify=true,表示不向CA校验证书的有效性。

类似于服务端,因为我们没有使用内置的Client Transport,所以我们需要使用http2.ConfigureTransport来启动HTTPS/2特性:

	//?启动HTTP/2协议
	http2.ConfigureTransport(transport)

最后将Transport配置给Client,负责底层的连接与协议管理:

	//?HTTP/2?客户端
	gateConn.client?=?&http.Client{
		Transport:?transport,Timeout:?time.Duration(G_config.GatewayTimeout)?*?time.Millisecond,?//?请求超时
	}

最后

首先理解h2和h2c的区别,然后明确Go语言推荐使用h2。

最后,当我们没有使用默认的http配置时,我们需要通过http2.ConfigureXXX重新配置启用HTTP2/S特性。

?

来源:http://www.imooc.com/article/details/id/78928

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读