nginx笔记(杂乱版一)

nginx笔记(杂乱版一)

网址:http://tengine.taobao.org/book/chapter_02.html#id1

阅读源码,调试代码是一个非常重要的手段,非常快

一般我们会设置与机器cpu核数一致

主要是因为这样不容易发生CPU迁移,CPU绑核是常用服务器优化手段。

MASTER+WORKER=NUM(CPU)

从容地重启,这个是一个比较神奇的特性,IPVS并没有

从容重启原理:master进程在接收到HUP信号后是怎么做的呢?首先master进程在接到信号后,会先重新加载配置文件,然后再启动新的worker进程,并向所有老的worker进程发送信号,告诉他们可以光荣退休了。(Q:已经负载的链接按照这个说法没法读取啊,那么重复的。。岂不是要重新连接?不过连接也可以写配置文件,如果把连接写入配置文件,就可以通过读取配置文件,获取现有的链接,保证不掉线。。。)

不过确实大多数是这么做

处理请求的机会也是一样的

所有worker进程的listenfd会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有worker进程在注册listenfd读事件前抢accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接。

nginx进程模型的好处。:

首先,对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的worker进程。当然,worker进程的异常退出,肯定是程序有bug了,异常退出,会导致当前worker上的所有请求失败,不过不会影响到所有请求,所以降低了风险。当然,好处还有很多,大家可以慢慢体会。

nginx采用了异步非阻塞的方式来处理请求:poll/epoll的方式

apache的常用工作方式:多线程(并发多吃不消)每个请求会独占一个工作线程,当并发数上到几千时,就同时有几千的线程在处理请求了。这对操作系统来说,是个不小的挑战,线程带来的内存占用非常大,线程的上下文切换带来的cpu开销很大
go服务器:goroutine轻量级线程,所以现在外国服务器端以Go搭建居多(还有一个原因,写的快啊)

为什么nginx可以采用异步非阻塞的方式来处理呢:

因为03年那时候,没有轻量级线程,只有epoll/poll比较好用(C++/C):P

在nginx里面,最忌讳阻塞的系统调用

(建议查看select/poll/epoll原理,这样容易理解。)

有趣的数据:epoll更多的并发数,只是会占用更多的内存而已。

我(作者)之前有对连接数进行过测试,在24G内存的机器上,处理的并发请求数达到过200万。

像这种小的优化在nginx中非常常见,同时也说明了nginx作者的苦心孤诣:所以应该仔细学习这种小优化(md实际上效果并不小,光这个性能可以提升3/2倍。。。)

nginx在做4个字节的字符串比较时,会将4个字符转换成一个int型,再作比较,以减少cpu的指令数等等。

对于一个基本的web服务器来说,事件通常有三种类型,网络事件、信号、定时器。

信号看什么书????

定时器数据结构一般不是最小堆么???nginx里面的定时器事件是放在一颗维护定时器的红黑树里面,每次在进入epoll_wait前,先从该红黑树里面拿到所有定时器事件的最小时间
(代码确认一下)

在写nginx代码时,在处理网络事件的回调函数时,通常做的第一个事情就是判断超时,然后再去处理网络事件。

我们可以用一段伪代码来总结一下nginx的事件处理模型:

while (true) {
    for t in run_tasks:
        t.handler();
    update_time(&now);
    timeout = ETERNITY;
    for t in wait_tasks: /* sorted already */
        if (t.time <= now) {
            t.timeout_handler();
        } else {
            timeout = t.time - now;
            break;
        }
    nevents = poll_function(events, timeout);
    for i in nevents:
        task t;
        if (events[i].type == READ) {
            t.handler = read_handler;
        } else { /* events[i].type == WRITE */
            t.handler = write_handler;
        }
        run_tasks_add(t);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值