配置完成,是时候增加一些客户端来确认一下配置是否正确。首先,我们发送一个不被限流的请求,这意味着这个 URL 在数据库中没有限流规则。
client c1 {
txreq -url "/"
rxresp
expect resp.status == 200
expect resp.http.X-RateLimit-Limit == <undef>
expect resp.http.X-RateLimit-Counter == <undef>
expect resp.http.X-RateLimit-Period == <undef>
} -run
我们知道客户端发送的下一个请求的 URL 与限制数据库是匹配的,我们希望设置速率限制报头,对/search的限制规则是3r5,也就是说在5秒的时间段内,前三个请求应该是成功的(返回状态码200),当第四次请求时,就应该被限制了(返回状态码429)。
client c2 {
txreq -url "/search?id=123&type=1"
rxresp
expect resp.status == 200
expect resp.http.X-RateLimit-Limit == "3"
expect resp.http.X-RateLimit-Counter == "1"
expect resp.http.X-RateLimit-Period == "5"
txreq -url "/search?id=123&type=2"
rxresp
expect resp.status == 200
expect resp.http.X-RateLimit-Limit == "3"
expect resp.http.X-RateLimit-Counter == "2"
expect resp.http.X-RateLimit-Period == "5"
txreq -url "/search?id=123&type=3"
rxresp
expect resp.status == 200
expect resp.http.X-RateLimit-Limit == "3"
expect resp.http.X-RateLimit-Counter == "3"
expect resp.http.X-RateLimit-Period == "5"
txreq -url "/search?id=123&type=4"
rxresp
expect resp.status == 429
expect resp.http.X-RateLimit-Limit == "3"
expect resp.http.X-RateLimit-Counter == "4"
expect resp.http.X-RateLimit-Period == "5"
} -run
在这一点,我们知道请求将会被限制,为了确定限制时间结束之后新的请求将会被允许,在我们发送下一个和最后一个请求之前,我们添加了一个延迟。这个请求应该是成功的,因为我们已经进入了一个新的限制窗口期。
delay 5;
client c3 {
txreq -url "/search?id=123&type=4"
rxresp
expect resp.status == 200
expect resp.http.X-RateLimit-Limit == "3"
expect resp.http.X-RateLimit-Counter == "1"
expect resp.http.X-RateLimit-Period == "5"
} -run
要运行测试文件,先要确保 memcached 服务正在运行,然后执行:
$ varnishtest example.vtc
# top TEST example.vtc passed (6.533)
添加 -v 选项启用详细模式,从运行测试中获得更多的信息。
对我们示例应用发送请求,将会接收到如下的响应头。第一个表示请求被接受,第二个表示请求被限制。
$ curl -iI
HTTP/1.1 200 OK
Age: 6
Content-Length: 936
X-RateLimit-Counter: 1
X-RateLimit-Limit: 3
X-RateLimit-Period: 5
X-Varnish: 32770 3
Via: 1.1 varnish-plus-v4
$ curl -iI
HTTP/1.1 429 Too many requests
Content-Length: 273
X-RateLimit-Counter: 4
X-RateLimit-Limit: 3
X-RateLimit-Period: 5
X-Varnish: 32774
Via: 1.1 varnish-plus-v4
完整的 throttle.vtc 文件将会在 VMOD 处理前后输出时间戳信息,用以给出 Memcached 和 SQLite 查询引入 VMOD 的开销数据。在一个本地虚拟机上运行着 Memcached 服务的 varnishtest 上运行60个请求,返回如下的每个操作的时间信息(单位 ms):
•SQLite SELECT,最大:0.32,最小:0.08,平均值:0.115
• Memcached incr_set(),最大:1.23,最小:0.27平均值:0.29
这并不是个科学的结果,但是暗示了在大多数情况下,性能并不高。性能也是关于水平的能力。本文中给出的简单示例在需要的情况下,通过一个使用 Memcached 实例池的全局计数器,它的性能将会有规模性的扩展。
延伸阅读