goc/doc/protocol.md
2021-06-03 23:30:01 +08:00

1.9 KiB

通信协议设计

背景

v1 版本中,被插桩的服务会暴露一个 HTTP 接口,由 goc server 来访问获取覆盖率。

该方式要求被插桩的服务要有一个外界可访问的 ip + port。

如果被测服务躲在 NAT 网络下,该方式就不可行了,典型的就是被测服务由 docker 拉起,而 goc server 部署在另外的网络。

新设计选择

新设计只需要暴露 goc server 的地址,由插桩服务发起链接,然后保持长链接,在该长链接上构建 goc 自己的业务逻辑。

自行设计 TCP 应用层协议

go 语言做网络编程非常适合,非阻塞地处理“粘包”也不麻烦。但设计出来不管是纯二进制的、还是类似 HTTP 的,都不会是通用协议,后续维护和扩展估计是个大坑。

websocket + jsonrpc2

websocket + jsonrpc2 有流式调用,消息边界。非常适合

我找到 github.com/goriila/websocketgithub.com/sourcegraph/jsonrpc2 库,后者 import 了前者,前者没有 import 任何其它外部库,全是标准库。把两个库的代码合并一下:github.com/lyyyuna/jsonrpc2 就是一个无任何外部库引用的 jsonrpc 实现。

这非常适合由插桩代码来使用,因为该库没有再引用其它库,不会污染原服务的依赖关系

gRPC

老实说 gRPC 在这里更适合作为通信协议来使用,更快更通用,流式调用也有,上一小节的 github.com/sourcegraph/jsonrpc2 使用广度就很低。

但 gRPC 的 go 实现有一个很大的缺点,用了一些非标准库,且有版本依赖。我们不清楚原服务是不是有特定 gRPC 要求,或是 goc 插入的 gRPC 库会导致编译依赖冲突,或者是编译后运行冲突。

所以不适合。

结论

先使用 websocket + jsonrpc2 来做吧。

协议内容

注册

获取覆盖率

清空覆盖率

watch

异常处理