nginx代码分析之(一)——初探

发现 nginx是无意间在浏览器中看到新浪的一个错误页面“nginx ...”,不由起了好奇心。google了一把,发现这是一个支持负载均衡的反向代理服务器,俄罗斯人开发的,虽然没有走GNU或BSD的License,但是也算是一个开源软件。

用工具确认了一下,新浪blog应该是用的nginx没错,下面是执行curl -I http://blog.sina.com.cn/ 的结果
HTTP/1.1 200 OK
Via: 1.1 ISASERVER
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 365631
Expires: Wed, 07 Nov 2007 09:31:17 GMT
Date: Wed, 07 Nov 2007 09:26:17 GMT
Content-Type: text/html
Server: nginx/0.5.32
~~~~~~~~~~~~~~~~这一行
Last-Modified: Wed, 07 Nov 2007 09:18:01 GMT

Cache-Control: max-age=300
X-Via: Tj-206
Accept-Ranges: bytes
X-Via: Proxy by Tj-197


开源代理服务器最熟悉的还是 SquidApache,但这两者都是正反向代理通吃的,而作为反向代理,实际上和正向代理有较大的差别。我想既然新浪也用它,那自然有它的独到之处。查了一下,中文的网页上说它的HTTP性能可以达到13000TPS以上,但是没有说明数据的出处,国外的网站上暂时找不到相应的数据,但很多人拿它和 lighttpd相比。

很快下载了 nginx 0.5.32版本的代码,代码不多,才8万多行,在 openssl的基础上支持HTTPS。和 Apache的30多万行相比,精简了很多,

作为web server或反向代理,要的就是一个快,要做到快,除了精简的代码之外,更关键的一点就是并发模型。

Apache的弱点就在于它的并发模型是普通的进程/线程池,连接数和进程/线程数是1:1的,因此无论是prefork还是worker模式,都将每一个连接对应到一个独立的进程/线程。

这样的并发模型在连接数不太多(1000以内)时还算可以,但在大规模并发时,其进程/线程总数会非常多。由于 Apache本身也比较吃内存,所以到了1000以上的并发时,服务器的内存基本上也就被吃的差不多了,操作系统也在频繁地做进程/线程的切换,非常吃力。

相比之下,更高级的大型网络服务系统(如电信的智能网系统)一般采用进程/线程池+状态机的模型——也即接数和进程/线程数是m:n的,这样进程/线程总数就不会由于连接的增多而增多,避免了内存和调度切换的开销,但这种做法对程序逻辑的要求较高,需要一个连接拆分为多个逻辑状态(创建,读,写,关闭等,根据实际业务还可以更加细化)每个进程/线程处理完某一种状态后,需要改变该连接的状态值,后续状态由下一个空闲的进程/线程处理。

nginx就采用了这样的并发模型,对于连接状态的存储,nginx主要采用了这样一个复杂结构。
struct ngx_connection_s {
    void               *data;
    ngx_event_t        *read;
    ngx_event_t        *write;
    ...
};

结构ngx_event_t存储了连接IO状态的详细信息,同时所有的ngx_event_t组成了两个全局的链表,以便进行存取操作。

在这两个数据结构的基础上,nginx使用了下面这两个函数来完成每个进程/线程的循环
1. ngx_locked_post_event
这个函数负责更新某一个连接的状态,在检查到连接IO状态改变(比如通过select)后被调用。

nginx以module的方式提供了select语义的多种实现:
poll
devpoll
epoll
eventport
kqueue
rtsig
后面4种,都是BSD/Linux为加速IO操作而提供的异步IO模型

2. ngx_event_thread_process_posted
这个函数检查event表,并调用event对应的handler函数,每次处理1个event。

这两个函数组合使用,就实现了最基本的m:n并发模型。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值