当前位置:首页 > 培训认证 > 计算机图书

nginx架构札记1

优良自学吧提供nginx架构札记1,nginx架构笔记1转载请注明: TheViper http://www.cnblogs.com/TheViper  摘自<<深入理解nginx模块开发与架构解析>> Nginx进程间关系 nginx使用一个master进程管

nginx架构笔记1

转载请注明: TheViper http://www.cnblogs.com/TheViper 

摘自<<深入理解nginx模块开发与架构解析>>

Nginx进程间关系

nginx使用一个master进程管理多个worker进程。一般情况下,worker进程数与服务器的cpu核心数相等。worker进程提供真正的服务,master进程只负责监控管理worker进程。

master-worker方式启动多个进程的好处:

1.由于master进程仅专注于自己的管理工作,可以完全的管理worker进程,当任意一个worker进程发生错误,master进程可以立刻启动新的worker进程继续服务。

2.多个worker进程充分利用现在的多核架构,实现微观上真正的多核并发处理。把worker进程数设置成与服务器的cpu核心数相等,是因为更多的worker数,只会导致进程来竞争cpu资源了,从而带来不必要的上下文切换。而且,nginx为了更好的利用多核特性,提供了cpu亲缘性的绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。另外,一个worker进程可以同时处理的请求数只受限于内存大小,不同的worker进程间处理并发请求时几乎没有同步锁的限制,worker进程通常不会进入睡眠状态。由此,进程间切换的代价最小。

优化性能的配置项

1.nginx worker进程数

默认:worker_processes 1;

2.绑定nginx worker进程到指定cpu内核(配置仅对linux系统有效)

为什么要绑定?假定每个worker进程都是非常繁忙的,如果多个worker进程都在抢同一个cpu,就会出现同步问题。反之,如果每个worker进程都独享一个cpu,就在内核的调度策略上实现了完全的并发。

例如,有4个cpu内核,可以配置成:

worker_processes 4;

worker_cpu_affnity 1000 0100 0010 0001

3.ssl硬件加速

语法:ssl_engine_device;

可以使用openssl engine -t 查看是否有ssl硬件加速设备

4.系统调用gettimeofday的执行频率

语法:timer_resolution t;

默认情况下,每次内核事件调用(epoll,select,poll,kquene等)返回时,都会执行一次gettimeofday,实现用内核的时钟来更新nginx中的缓存时钟。

5.nginx worker进程优先级设置

语法:worker_priority nice;

默认:worker_priority 0;

在unix系统中,当许多进程都处于可执行状态时,将按照所有进程的优先级来决定本次内核选择哪一个进程执行。进程所分配的cpu时间片大小也与进程优先级有关。优先级越高,进程分配到的时间片也越大。这样,优先级高的进程会占有更多的系统资源。

优先级由静态优先级和内核根据进程执行情况所做的动态调整共同决定。nice值是进程的静态优先级,取值范围是-20到+19,-20是最高优先级。因此,如果希望nginx占有更多的系统资源,可以把值设置的小一些,但不建议比内核进程的nice值(通常为-5)更小。

事件驱动架构

定义:由一些事件发生源产生事件,由一个或多个事件收集器来收集,分发事件,然后很多事件处理器会注册自己感兴趣的事件,进而消费这些事件。

对于nginx,一般由网卡,磁盘产生事件,nginx的事件模块负责事件的收集,分发。而所有的模块都可能是事件的消费者,它们首先需要向事件模块注册感兴趣的事件类型,这样,当有事件产生时,事件模块会把事件分发到相应的模块中进行处理。

对于传统的web服务器,一个连接建立之后,在其关闭之前的所有操作,是按序执行每个操作的批处理模式,这样每个请求在连接建立后都将始终占据系统资源,直到连接关闭才会释放资源。而占据的这段时间可能会非常长,而且这段时间占用着内存,cpu等资源也许并没有意义,这就造成服务器资源的极大浪费,影响系统可以处理的并发数。传统服务器把一个进程或线程作为事件的消费者.

nginx采用了异步非阻塞的方式来处理请求,事件消费者是某个模块。只有事件收集,分发器才有资格占用进程资源,它们会在分发某个事件时调用事件消费模块使用当前占用的进程资源。

从上面可以看到两者的区别:传统服务器的每个事件消费者独占一个进程资源,nginx的事件消费者只是被事件分发器进程短期调用而已,这样每个用户的请求所产生的事件会被及时响应,服务器吞吐量也大大增加,但要注意,每个事件消费者不能有阻塞行为,否则会导致长时间占用事件分发者进程,使其他事件得不到及时响应。

这里对"事件"的描述可能有点晦涩,可以参见nginx和apache的原理。其中的那个对比apache和nginx工作原理的例子说的很好。本屌简要的复述下其中关于nginx异步非阻塞这种工作流程的要点。

nginx把一个完整的连接请求处理都划分成了事件,一个一个的事件。比如accept(), recv(),磁盘I/O,send()等,每部分都有相应的模块去处理,一个完整的请求可能是由几百个模块去处理。这些模块中真正的核心是事件收集和分发模块,这就是管理所有模块的核心。只有核心模块才能调度其他模块,让对应的模块占用CPU资源,从而处理请求。

比如一个http请求进入nginx,首先在事件收集分发模块注册感兴趣的监听事件,然后第一个模块开始处理该请求,这个过程是异步非阻塞的,此时这个worker进程就不用去管这个正在被处理的请求了,去处理其他被注册好的请求。然后当第一个请求由第一个模块处理完成后,便通知worker,可以开始由第二个模块处理了。。。。这样一直到被所有模块处理完。这过程中,只要请求开始被其中一个模块处理,worker就不管该请求,不再被该请求占用,而是去看其他请求中有没有刚刚被模块处理完,准备好被下一个模块处理的请求,而被某一模块处理好的请求会通知worker我准备好了,worker一旦有空就又会去调度它,进入下一个模块进行处理。

可以看到上面过程中,nginx始终在100%的运行,没有被I/O操作阻塞,耽误时间。

如果您觉得本文的内容对您有所帮助,您可以打赏我:

nginx架构札记1


(本文来自互联网,不代表搜站(http://www.ylzx8.cn/)的观点和立场)
本站所有内容来自互联网,若本站收录的信息无意侵犯了贵司版权,请给我们来信(ylzx8cn@163.com),我们会及时处理和回复,谢谢