nginx运行模式

nginx 淘宝团队。
nginx启动后回忆daemon的方式运行,后台进程包括一个master进程和多个worker进程。已多进程的方式来工作。当然,nginx也是支持多线程的~~
worker进程的个数一般与机器cpu核心数一致

nginx 启动后,master来管理worker。 master接收到来自外界发来的信号,再根据信号做不同的事。 eg 通过kill向master发送信号, kill -HUP pid 告诉nginx从容的重启nginx。
每个worker进程都是master进程fork过来,当一个请求过来,master首先需要建立好listen的socket再fork出多个worker,nginx提供一个accept_matex的 accept共享锁,有了这个锁,同一时刻,就只会有一个进程在accept连接。 这样的好处worker的异常不会影响到别的进程。
apache每个请求会独占一个工作线程,当并发上几千的时候,就同时有几千的线程在处理请求。对于操作系统来说,线程带来的内存占用非常大,线程上下文切换带来的cpu开销也很大。
nginx采用异步非阻塞的方式来处理事件。

(PS 关于CPU上下文切换
一个进程存储在处理器各寄存器中的中间数据叫做进程的上下文,所以进程切换的实质就是被终止运行进程与待运行进程上下文切换。
让进程来占用处理器,实质上是把某个进程存放在私有堆栈中寄存器的数据(前一次本进程被中止时的中间数据)再恢复到处理器的寄存器中去,并把待运行进程的断点送入处理器的程序指针PC,于是待运行进程就开始被处理器运行了,也就是这个进程已经占有处理器的使用权了。 )
进程类型:Linux调度算法中,分为两类 I/O 消耗型和CPU消耗型

运行队列
  每个CPU都会维持一个运行队列,理想情况下,调度器会不断让队列中的进程运行。进程不是处在sleep状态就是run able状态。如果CPU过载,就会出现调度器跟不上系统的要求,导致可运行的进程会填满队列。队列愈大,程序执行时间就愈长。

关于时间片和动态优先级
    时间片对于CPU来说是很关键的参数,如果时间片太长,就会使系统的交互性能变差,用户感觉不到并行。如果太短,又会造成系统频繁的上下文切换,使性能 下降。对于IO Bound的系统来讲并不需要太长的时间片,因为系统主要是IO操作;而对于CPU Bound的系统来说需要长的时间片以保持cache的有效性。)

事件没有准备好,那只能等,等事件准备好了,再继续。阻塞调用会进入内核等待,CPU就会空出来给别人用,对于单线程的worker来说不合适,当网络事件越多时,cpu空闲下来每人用,cpu利用率自然就上不去了。更别谈高并发。如果加进程数====apache。
nginx,当事件没有准备好,马上返回GAGAIN,系统会时不时过来检查一下事件的状态,知道事件准备好了位置,在这期间你可以做更多别的事情。
eg : epoll 当事件没有准备好时,放到epoll里面,事件准备好了,我们就去读,当返回EAGAIN时,我们将它再次加入epoll里面等着。这样,我们就可以处理并发处理大量的请求了,线程只有一个,所以同时能处理的求情当然只有一个,只是请求之间不断的切换而已。切换也是因为异步事件未准备好而主动让出的。这里的切换是没有代价的,与多线程相比,这种事件处理方式是有很大优势的,不需要创建线程,每个请求占用的内存也很少,没有上下文切换,事件处理轻量级,再多的并发数,只会占用更多的内存而已。
  1. worker_processes 1;
所以,worker的个数为cpu的核心数,更多的worker数只会导致进程竞争cpu资源,带来不必要的上下文切换。
(nginx可以将某一进程绑定到一个核上,这样就不会因为进程切换带来cache的实效。又比如nginx在做4个字节的字符串比较时会将4个字符串转换为一个int型,在做比较,减少cpu的指令数)

在web服务器中,事件通常有 网络事件,信号,定时器 。网络事件可以同过异步非阻塞很好的解决掉。 信号处理: 如果程序收到信号,在信号处理函数处理完毕之后,epool_wait 会返回错误,然后程序可再次进入epoll_wait调用。
定时器, epoll_wait等函数在调用的时候可以设置一个超时时间,ngixn里面的定时器放在一个最小的堆里面,每次进入epoll_wait前,先从最小的堆里面拿到定时器设置的最小时间,在计算出epoll_wait的超时时间后进入epoll_wait,所以当没有时间产生也没有中断信号,会将他们的状态设为超时,然后再去处理网络请求、

master 产生和销毁=>worker =》》 每个worker中采用异步非阻塞的方式监控事件请求
因此可以并发量比较大。



connection 针对tcp连接封装,包括http请求和socket

ngixn每个进程都有一个最大连接数的上限。
nginx通过设置worker_connections 来设置每个进程可以使用的最大连接数。nginx是通过一个连接池来管理的,每个worker进程都有一个独立的连接池。nginnx会通过一个链表,free_connection来保存所有的空吸纳的ngx_connection_t 每次获取一个连接时,就从空闲的链表中获取一个,用完以后再放回空闲链表里面。
nginx的处理得先打开accept_mutex选项,(竞争accept_mutex锁)因此只有获得了accept_mutex的进程才会去添加accept事件。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值