Java必备技能之源码篇(Nginx源码研究之nginx限流模块)

2.2 nginx事件处理简单介绍

假设nginx使用的是epoll 【不同linux发行版本不同,centos是epoll的IO模型】。

nginx需要将所有关心的fd(file describe 文件描述符【linux基于文件表示网络io资源】)注册到epoll,添加方法声明如下:

static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

方法第一个参数是ngx_event_t结构体指针,代表关心的一个读或者写事件;nginx为事件可能会设置一个超时定时器,从而能够处理事件超时情况;定义如下:

struct ngx_event_s {

ngx_event_handler_pt handler; //函数指针:事件的处理函数

ngx_rbtree_node_t timer; //超时定时器,存储在红黑树中(节点的key即为事件的超时时间)

unsigned timedout:1; //记录事件是否超时

};

一般都会循环调用epoll_wait监听所有fd,处理发生的读写事件;epoll_wait是阻塞调用,最后一个参数timeout是超时时间,即最多阻塞timeout时间如果还是没有事件发生,方法会返回;

nginx在设置超时时间timeout时,会从上面说的记录超时定时器的红黑树中查找最近要过时的节点,以此作为epoll_wait的超时时间,如下面代码所示;

ngx_msec_t ngx_event_find_timer(void)

{

node = ngx_rbtree_min(root, sentinel);

timer = (ngx_msec_int_t) (node->key - ngx_current_msec);

return (ngx_msec_t) (timer > 0 ? timer : 0);

}

同时nginx在每次循环的最后,会从红黑树中查看是否有事件已经过期,如果过期,标记timeout=1,并调用事件的handler;

void ngx_event_expire_timers(void)

{

for ( ;; ) {

node = ngx_rbtree_min(root, sentinel);

if ((ngx_msec_int_t) (node->key - ngx_current_msec) <= 0) { //当前事件已经超时

ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));

ev->timedout = 1;

ev->handler(ev);

continue;

}

break;

}

}

nginx就是通过上面的方法实现了socket事件的处理,定时事件的处理;

ngx_http_limit_req_module模块解析

ngx_http_limit_req_module模块是对请求进行限流,即限制某一时间段内用户的请求速率;并且使用的是令牌桶算法;

3.1配置指令

ngx_http_limit_req_module模块提供一些配置指令,供用户配置限流策略

//每个配置指令主要包含两个字段:名称,解析配置的处理方法

static ngx_command_t ngx_http_limit_req_commands[] = {

//一般用法:limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

//$binary_remote_addr表示远程客户端IP;

//zone配置一个存储空间(需要分配空间记录每个客户端的访问速率,超时空间限制使用lru算法淘汰;注意此空间是在共享内存分配的,所有worker进程都能访问)

//rate表示限制速率,此例为1qps

{ ngx_string(“limit_req_zone”),

ngx_http_limit_req_zone,

},

//用法:limit_req zone=one burst=5 nodelay;

//zone指定使用哪一个共享空间

//超出此速率的请求是直接丢弃吗?burst配置用于处理突发流量,表示最大排队请求数目,当客户端请求速率超过限流速率时,请求会排队等待;而超出burst的才会被直接拒绝;

//nodelay必须与burst一起使用;此时排队等待的请求会被优先处理;否则假如这些请求依然按照限流速度处理,可能等到服务器处理完成后,客户端早已超时

{ ngx_string(“limit_req”),

ngx_http_limit_req,

},

//当请求被限流时,日志记录级别;用法:limit_req_log_level info | notice | warn | error;

{ ngx_string(“limit_req_log_level”),

n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值