1 背景

在业务服务重构过程中,发现后台一些RPC服务,使用的自定义的应用层协议(七层)。 为了方便验证重构逻辑,想在在海量的请求中,快速找到某一类业务请求包。

2 思考

一般来说简单的协议使用 lua 实现即可,但是遇到 pb/thrift 等 tlv 类型的协议就比较麻烦了; 比较友好的是,目前有 lua-protobuf 这样的库,可以在lua中解析PB协议, 只需要提供proto即可;

但是对于内部的 tlv 协议,由于本人不太会使用lua去封装c库;

突然萌生了一个想法,能不能用 golang 来开发 wireshark 插件? 是否可以让 lua5.2 直接调用cgo?

3 定制目标(okr)

定位: 本地的报文分析工具

  • 1 当业务遇到一种业务的字节协议时,可快速在 wireshark 中解析,展示;
  • 2 支持使用 go 实现包解析;
  • 3 对解析性能要求(1000条/s即可),准确解析;

4 思考方案

采用lua可快速实现一个简单的 wireshark 插件,快捷高效,官方文档也比较完善。 调试验证脚本也比较方便,重新加载即可生效,无需编译。 但是在工作中,有各种各样的 tlv 类型协议接口(历史原因),lua在tlv类型的协议解析上就显得有点吃力。

4.1 那么怎么解决这类问题呢?

既然 lua 作为胶水语言,我们把 lua 当作入口,然后调用 go 的动态库。 同时业务也有各种协议的编解码包,对接新的协议可谓是顺风顺水呀! 能不能直接复用呢? 经过一番折腾,没有成功 :(

4.2 退一步海阔天空

当然我们不能气馁,不行就退一步,折中一下,能不能把c 也当做一个入口(桥梁);
链路:lua -> c -> go, 因为这两个环节是相当成熟的,初步评估可行,于是写代码验证。

arch

5 代码实现

wireshark_plugin

5.1 插件效果

effect

5.2 Benchmark

整体性能还不错,比预想的高10倍^_^。

1
2
3
4
5
6
7
记录条数: 96180文件总大小: 44 M
单个报文大小:300 ~ 500 bytes
解析耗时: 9.479s
平均速率: 1 W/s
time tshark -r udp.cap > /dev/null
#  9.479s real      9.05s user      0.94s sys

总结

探索了一种跨语言编程方式,结合多种语言的特性,最终将一个想法落地实现。 在解决问题方面:尝试用已有技能,解决不同问题,能力提升。

解决的一些问题

在编写插件过程中,也遇到和解决了不少问题,系列文章如下: