wrk是一款比较常用的压测工具,支持多核,多线程,同时支持Lua脚本对返回结果和统计数据进行定制。详见github: https://github.com/wg/wrk
wrk源码部分结合了很多优秀的github开源项目,例如Redis数据库中的事件循环ae,用于nginx、nodejs、joyent的解析http请求相应的模块http-parser,以及Mike Pall所写的及时lua脚本编译器LuaJIT–lua Just in Time。这次我着重追踪了下wrk代码本身、以及ae时间循环的部分,至于http-parser以及luaJIT由于不涉及主要逻辑,暂时没有深究。抛砖引玉,一起探讨哈~
AE(Redis EventLoop)
ae是Redis内部使用的事件循环,由于我没有仔细研读过Redis的源码,所以对ae本身并不熟悉。只是ae的实现,和接触过的node的实现类似(Event-Driven Design
),结合之前实践时对Redis的零星记忆(例如Redis单线程、命令串式执行等),大概明白其在wrk中的作用。
ae的event-loop监听的事件分为两种,一种是AE_FILE_EVENTS
,另一种是AE_TIME_EVENTS
。
AE_FILE_EVENTS
AE_FILE_EVENTS
在Linux下是利用epoll
相关机制实现的。例如:
aeCreateEventLoop(); // 调用epoll_create
aeCreateFileEvent(); // 调用epoll_ctl
aeProcessEvents(); // 调用epoll_wait
以wrk的调用为例:
main()->(每个thread)aeCreateEventLoop()