仓库地址:https://github.com/rakyll/hey
Hey是一款类似于ab的工具,基于golang开发,代码较为精简,对代码简要分析。
最开始项目命名为(
boom
),后来改名为hey,再次表明取名的重要性!
1. 安装
基于golang编译安装:
|
|
仓库地址中也支持二进制安装
2. 运行效果
|
|
3. 核心流程
3.1. 拎出请求包的Work主流程
|
|
3.2. runWorkers() - 基于sync.WaitGroup做多goroutine同步
这里client被多个goroutine复用,
|
|
3.3. runWorker() - 分配给单个worker运行n次http请求
runWorker()基于非阻塞方式makeRequest()
,执行client.Do()
http请求
b.stopCh
为程序基于运行时间设置-z
或者发送Interupt中断信号
给到hey进程时候,会从通道接收数据,并退出
|
|
3.4. makeRequest() - 具体的http请求和trace跟踪
- 基于
net/http/httptrace
,对HTTP请求的几个关键节点进行了跟踪:trace := &httptrace.ClientTrace{..}
- DNS开始、结束
- ConnTCP连接开始结束
- 请求发送、首字节响应获取
- trace需要放入到http请求对象req中,以上下文
req.WithContext
进行设置:req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
- 请求的body部分丢弃:
io.Copy(ioutil.Discard, resp.Body)
|
|
4. 其他
- Usage的编写方式,基于单一的usage方法设置,相对于flag的默认提升,可以做到help的统一
- 清晰的包文件、以及结构方法,先骨架,再细节,另外一点,导出的方法往前写:
type Work struct {}
func (b *Work) writer() io.Writer
func (b *Work) Init()
func (b *Work) Run()
func (b *Work) Stop()
func (b *Work) Finish()
func (b *Work) makeRequest(c *http.Client)
func (b *Work) runWorker(client *http.Client, n int)
func (b *Work) runWorkers()
func cloneRequest(r *http.Request, body []byte) *http.Request
func min(a, b int) int
- 信号量的捕获、防止竟态+单次实例的
sync.Once.Do方法
、sync.WaitGroup
4.1. 模板的呈现方式、模板函数的定义
|
|
5. 后续可以做的事情
常规的压测工具替换,相比于ab,hey可以接收定制化的开发:
- 基于requester包思想,可以自己组装http请求,实现一个全功能的http并发请求模拟
- 基于C端的巡检相关工作
- 基于C端的请求数据分析(类似statusok) & 收集,上报到influxDB,基于grafana图显