WRK 的源码详解网上已经有一些了,但是都不是特别详细,最近有时间特意详读了一下,希望能给大家一些参考以及启发

WRK 介绍

wrk 是一个多线程,内部通过事件驱动模型 +IO 多路复用处理网络连接的一个针对 HTTP/HTTPS 的压测工具(不支持 windows 系统)

WRK 代码结构

wrk 源码在 src 目录下,其中比较重要的文件有 wrk,stats,net,http_parser
wrk 想阅读明白要先理解 AE,在第一个文章中,我会先介绍一下:AE

AE 介绍(Redis EventLoop)

AE 是 Redis 内置的一个高性能事件驱动器,主要分为文件事件和定时器事件
但也是由于 AE 这套规则只能在符合 POSIX 标准的系统中工作,所以 wrk 不能在 windows 系统中运行

API
创建/删除驱动器:
aeEventLoop *aeCreateEventLoop(int setsize); 
void aeDeleteEventLoop(aeEventLoop *eventLoop);

setsize 参数表示了 eventloop 可以监听的网络事件 fd 个数,一般这个数字是最大并发数 + 一些预留空间

创建/删除文件 IO 事件:当套接字变得可读/可写时,执行
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData); 
void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask);

eventLoop 为上面创建的驱动器,fd 为监听的文件句柄,注册事件类型分别有:AE_READABLE,AE_WRITABLE ,AE_BARRIER,mask 是这几个事件经过或运算后的掩码(例如如果想监听读写事件,则 mask=AE_READABLE|AE_WRITABLE,如果只想监听写事件,则 mask=AE_WRITABLE),proc 为执行的回调函数,clientData 为传给回调参数的值

创建/删除定时器事件:让一段程序在指定的时间之后执行一次。
long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, aeTimeProc *proc, void *clientData, aeEventFinalizerProc *finalizerProc);
int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id);

milliseconds 为超时时间,proc 为超时后的回调函数,finalizerProc 为定时器删除后执行的回调函数

处理事件
void aeMain(aeEventLoop *eventLoop);
// 事件循环

一般使用方式是创建驱动器,再根据需要添加文件 IO 事件或定时器事件,通过 aeMain 事件循环

关于 AE 中的 IO 复用

FeeBSD 或 Apple 使用的是 kqueue,linux 使用的是 epoll,sunos 使用的是 evport,则默认使用 select,从效率上来看是:evport > epoll > kqueue > select
源码中是这么标注的

#if defined(__FreeBSD__) || defined(__APPLE__)
#define HAVE_KQUEUE
#elif defined(__linux__)
#define HAVE_EPOLL
#elif defined (__sun)
#define HAVE_EVPORT

在 WRK 中是如何使用的

请求处理:

每个线程创建了一个独立的 aeEventLoop,线程内创建若干 connection(socket),并为每个 socket 句柄注册事件(aeCreateFileEvent),包括:AE_READABLE,AE_WRITABLE
关键代码

flags = AE_READABLE | AE_WRITABLE;
aeCreateFileEvent(loop, fd, flags, socket_connected, c);
统计结果:

每个线程注册定时器(aeCreateTimeEvent),每 100ms 执行一次统计请求和响应结果
关键代码

aeCreateTimeEvent(loop, RECORD_INTERVAL_MS, record_rate, thread, NULL);

第二章可跳转:WRK 源码详解 (第二章:处理连接)


↙↙↙阅读原文可查看相关链接,并与作者交流