我是靠谱客的博主 热情小蝴蝶,最近开发中收集的这篇文章主要介绍查看telnet服务是否开启_微服务火爆,我们聊聊同样火爆的 gRPC,它是否必须开启 TLS?...01 过去为什么 h2 不行寻找 h2c琢磨其他方式02 现在使用标准库 h2c验证03 总结04 参考,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Go语言中文网,致力于每日分享编码知识,欢迎关注我,会有意想不到的收获!

如果你以前有涉猎过 gRPC+gRPC Gateway 这两个组件,你肯定会遇到这个问题,就是 “为什么非得开 TLS,才能够实现同端口双流量,能不能不开?” 又或是 “我不想用证书就实现这些功能,行不行?”。我被无数的人问过无数次这些问题,也说服过很多人,但说服归说服,不代表放弃。前年不行,不代表今年不行,在今天我希望分享来龙去脉和具体的实现方式给你。

fb4dc95bc083ae1aa9931d2d66d4c7ca.png

01 过去

17d5acc7e1fa71ddf960e48a237a052c.png

为什么 h2 不行

因为 net/http2 仅支持 "h2" 标识,而 "h2" 标识 HTTP/2 必须使用传输层安全性(TLS)的协议,此标识符用于 TLS 应用层协议协商字段以及识别 HTTP/2 over TLS。

简单来讲,也就 net/http2 必须使用 TLS 来交互。通俗来讲就要用证书,那么理所当然,也就无法支持非 TLS 的情况了。

寻找 h2c

那这条路不行,我们再想想别的路?那就是 HTTP/2 规范中的 "h2c" 标识了,"h2c" 标识允许通过明文 TCP 运行 HTTP/2 的协议,此标识符用于 HTTP/1.1 升级标头字段以及标识 HTTP/2 over TCP。

但是这条路,早在 2015 年就已经有在 issue 中进行讨论,当时 @bradfitz 明确表示 “不打算支持 h2c,对仅支持 TLS 的情况非常满意,一年后再问我一次”,原文回复如下:

We do not plan to support h2c. I don't want to receive bug reports from users who get bitten by transparent proxies messing with h2c. Also, until there's widespread browser support, it's not interesting. I am also not interested in being the chicken or the egg to get browser support going. I'm very happy with the TLS-only situation, and things like https://LetsEncrypt.org/ will make TLS much easier (and automatic) soon.

Ask me again in one year.

琢磨其他方式

使用 cmux

基于多路复用器 https://github.com/soheilhy/cmux的另类实现 https://github.com/Stoakes/grpc-gateway-example。若对 cmux 的实现方式感兴趣,还可以看看 《Golang: Run multiple services on one port》https://blog.dgraph.io/post/cmux/。

使用第三方 h2

  • https://github.com/veqryn/h2c

这种属于自己实现了 h2c 的逻辑,以此达到效果。

02 现在

f53e82e16ffd333cbf46b95774411e10.png

经过社区的不断讨论,最后在 2018 年 6 月,代表 "h2c" 标志的 golang.org/x/net/http2/h2c 标准库正式合并进来,自此我们就可以使用官方标准库(h2c),这个标准库实现了 HTTP/2 的未加密模式,因此我们就可以利用该标准库在同个端口上既提供 HTTP/1.1 又提供 HTTP/2 的功能了。

使用标准库 h2c

85a6ced213366e5789b31c43d84249d6.png

我们可以看到关键之处在于调用了 h2c.NewHandler 方法进行了特殊处理,h2c.NewHandler 会返回一个 http.handler,主要的内部逻辑是拦截了所有 h2c 流量,然后根据不同的请求流量类型将其劫持并重定向到相应的 Hander 中去处理。

验证

HTTP/1.1

$ curl -X GET 'http://127.0.0.1:9005/search?request=EDDYCJY'{"response":"EDDYCJY"}

HTTP/2(gRPC)

c2dce2ee11bacb19bd5a86ad4c74a3e7.png

输出结果:

$ go run main.go2019/06/21 20:04:09 resp: gRPC h2c Server

03 总结

在本文中我介绍了大致的前因后果,且介绍了几种解决方法,我建议你选择官方的 h2c 标准库去实现这个功能,也简单。在最后,不管你是否曾经为这个问题烦恼过许久,又或者正在纠结,都希望这篇文章能够帮到你。

04 参考

  • https://github.com/golang/go/issues/13128
  • https://github.com/golang/go/issues/14141
  • https://github.com/golang/net/commit/c4299a1a0d8524c11563db160fbf9bddbceadb21
  • https://go-review.googlesource.com/c/net/+/112997/

本文作者:煎鱼,原创授权发布

最后

以上就是热情小蝴蝶为你收集整理的查看telnet服务是否开启_微服务火爆,我们聊聊同样火爆的 gRPC,它是否必须开启 TLS?...01 过去为什么 h2 不行寻找 h2c琢磨其他方式02 现在使用标准库 h2c验证03 总结04 参考的全部内容,希望文章能够帮你解决查看telnet服务是否开启_微服务火爆,我们聊聊同样火爆的 gRPC,它是否必须开启 TLS?...01 过去为什么 h2 不行寻找 h2c琢磨其他方式02 现在使用标准库 h2c验证03 总结04 参考所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部