Goreplay工具学习(1)
之前看了一些go的开源项目的源码,比如使用gin的开源后端服务,而这些项目对于实际的业务偏重较大,主要都是一些对于数据库的CRUD操作来完成实际的业务,而如果我想学习go实际的并发类型的项目,则只看这些后端项目代码可能掌握不了太多。如果直接看一些开源框架的代码,框架为了做好普适性,就使用了大量的泛型,反射等,对于目前我的水平来说,阅读起来比较困难。因此,我转而选择阅读一些go的开源工具项目,对于工具项目,其目的性就和明确,是为了完成某项功能,而且里边也不缺少并发的场景。因此接下来可以通过阅读一些比较不错的开源工具来学习go语言。
本次学习的目的主要是学习工具的执行框架,业务处理逻辑,并发场景代码的编写与注意事项。
0 工具介绍
goreplay是一个由go语言编写的流量录制/转发工具。github地址为 https://github.com/buger/goreplay
因为此工具主要的作用是录制流量,并将流量输出到用户指定的位置,因此可以首先来一个比较简单的场景:将8000端口的流量打印到终端上
如我们使用如下命令
./goreplay --input-raw :8000 --output-stdout
如我在本机8000端口启动了一个服务,然后给这个服务发送一个get请求后,工具的终端会输出如下内容:
这个就是我们发送的get请求。若换为post请求则会输出如下内容:
这样对于post的请求头,请求体也可以输出在终端上。
1 初始化
首先看main.go中的init函数,里边主要是定义了几个路由。这些路由主要是我们启动的服务的各种性能数据。
如我在本地启动了此工具,并通过--http-pprof 127.0.0.1:8080
参数,可将工具的服务绑定到本机的8080端口,然后访问8080端口对应的路由即可出现如下的方法。对于性能相关数据,底层调用的是go的pprof性能分析工具。
在settings.go中的init()方法,主要是使用flag包对入参定义。
有了这些定以后,就可以通过命令行来查看该工具的使用方法
2 main函数
在执行完init函数后,接下来就会执行main方法。在main方法中,把此流量录制工具分成了两大模式。第一个模式是文件服务模式,第二个就是流量录制模式。
若想使用此工具的文件服务模式,则需要在启动时候 第一个参数填写file-server
,第二个参数填写ip:port
对于第二种模式,就是流量录制功能了。在此种模式下,首先会初始化一个InOutPlugins
的对象,这个对象的定义如下:
// InOutPlugins struct for holding references to plugins
type InOutPlugins struct {
Inputs []PluginReader
Outputs []PluginWriter
All []interface{}
}
Inputs是读流量,Outputs是写流量,All则增加中间件,如流量过滤等。
对于PluginReader
接口,则有一个方法为PluginRead() (msg *Message, err error)
,插件需要实现此方法用于读取流量
对于PluginWriter
接口,则有一个方法为PluginWrite(msg *Message) (n int, err error)
,插件需要实现此方法用于输出流量
然后在main方法中会生成插件对象。主要是通过我们命令行中输入的参数来对插件对象进行初始化。
接下来则是创建一个执行器,将插件对象传入执行器的Start方法后执行插件。
对于执行插件的核心代码,则是将读取到的流量拷贝到目标输出的地方
3 总结
本文主要是对goreplay工具的基本执行流程做了简要的概述,并通过一条实际命令来验证其执行。其中主要的执行流程为根据命令行所配置的参数来创建一个InOutPlugins对象,里边包含了从哪读取流量,并把流量输出到哪里。然后将此插件对象提交给执行器(Emitter),执行器会根据插件对象的配置来执行此插件,以此来完成此次流量录制的任务。