公司大量使用微服务框架 go-micro,但框架作者已不再维护低版本(新版本已经商业化),只能自己动手了。
起因是我用 Go 1.16 编译,启动报错:
panic: qtls.ConnectionState not compatible with tls.ConnectionState
goroutine 1 [running]:
github.com/lucas-clemente/quic-go/internal/handshake.init.0()
/go/pkg/mod/github.com/lucas-clemente/[email protected]/internal/handshake/unsafe.go:17 +0x118
跟进去看:
func init() {
if !structsEqual(&tls.ConnectionState{}, &qtls.ConnectionState{}) {
panic("qtls.ConnectionState not compatible with tls.ConnectionState")
}
if !structsEqual(&tls.ClientSessionState{}, &qtls.ClientSessionState{}) {
panic("qtls.ClientSessionState not compatible with tls.ClientSessionState")
}
}
发现 tls.ConnectionState
在是标准库的包 crypto/tls
,也就是说,新版本的 Go 标准库的定义,和 github.com/marten-seemann/qtls
不兼容。
公司使用 Go 1.14 编译,程序是正常运行的。
翻了一大圈资料,都是让我降级版本:
https://github.com/ipfs/go-ipfs/issues/7597
https://segmentfault.com/a/1190000020124701
https://www.jianshu.com/p/253d08c50c44
https://www.cnblogs.com/huay/p/14491557.html
https://blog.csdn.net/Xiang_lhh/article/details/113814742
还真不能降版本!因为我电脑是 M1 芯片,必须使用 Go 1.16,只能硬着头皮改了。
翻了 go-micro 源码,Transport 定义了客户端和服务端的通信接口,支持 http、grpc、quic 等协议。
引用 外部 的一张 go-micro 架构图:
我也搜到了一片文章,解释 QUIC 到底是个啥:
干货 | HTTP探索之路(一)- HTTP1/HTTP2/QUIC
https://zhuanlan.zhihu.com/p/102517430
言归正传,既然是 quic 不兼容标准库,那我们升级一下不就完了:
github.com/lucas-clemente/quic-go v0.12.1 -> v0.22.0
发现编译不通过——好家伙,新包直接改了接口定义!
对比了官方的更新,也就换了个方法名和包名,细节就不展开了,直接看我修复的代码吧:
https://github.com/Lofanmi/go-micro/commit/68bbf601cfa46b0c49c67f51e4e38e6a6f029f42
用法很简单,直接 replace 掉就 OK 了!
replace (
github.com/micro/go-micro => github.com/Lofanmi/go-micro v1.16.1-0.20210804063523-68bbf601cfa4
)
如果还不行,再 replace 掉下面的包:
replace (
github.com/golang/protobuf => github.com/golang/protobuf v1.3.2
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1
google.golang.org/grpc v1.30.0 => google.golang.org/grpc v1.26.0
google.golang.org/protobuf => google.golang.org/protobuf v1.25.0
)
上面四个 replace 是工程内其他依赖的,我没办法测试只替换 go-micro 是否可以解决问题,所以也贴在这里,需要请自取哈。