您的位置:首页 > 运维架构 > Nginx

Nginx初探之二

2016-09-06 16:21 183 查看

Nginx初探之二

​ 老版本的Nginx在配置文件修改之后,想让配置生效就需要使用kill向Master进程发送HUP信号,后续的版本对此也进行了优化,添加了一些Nginx支持的命令,如nginx -s reload,可以重启或重载配置文件,nginx -s stop,可以用来停止Nginx的运行。并且在实际执行时,过程也与kill -HUP pid不太一样。nginx -s command在执行时,是首先创建一个新的进程,用以解析处理command,之后再根据command的内容向Master进程发送相应的信号,如此看来,这样操作会更显一致。

​ 之前也好奇过,Nginx使用上篇中说到的那种进程模式为何会有比采用更轻量的线程模式的Apache更高效呢?了解过Nginx处理事件的方式之后,也就渐渐清楚了。Nginx采用了异步非阻塞的方式处理事件,要理解这种方式,可以先看两个问题:

对于一个请求的完整处理过程,首先,先建立一个连接,然后接收数据,接收完之后再发送相应的反馈。更直观的说法就是I/O,对于大多数系统I/O函数,都是阻塞式的,当读写事件/读写设备未准备好时,必然是无法将函数执行下去的,这样就只能等待阻塞、等待事件/设备准备好,CPU此时就会让出去,如果大部分进程都阻塞,那就会造成CPU利用率低,对于需要并发量很大的应用,CPU利用率低就限制了并发量;

如果将上面说到的阻塞式改成非阻塞式,如果事件/设备未准备好,立即返回EAGAIN,这样就需要时常去check事件/设备是否准备好,这样额外的开销也不小。

异步非阻塞方式就很好地解决了上述两个问题,具体到系统调用来说,使用了如select/poll/epoll/kqueue之类的系统调用,以epoll为例,epoll保存未准备好的事件,epoll可以设置超时时间,在超时时间内有准备好的事件,就返回,就可以去进行读写了,调用epoll是阻塞的,但这不重要,Nginx中处理请求的进程是多个Worker进程,只要有准备好的时间,Worker进程就可以去竞争互斥锁,获取连接进行请求的处理。对于问题1,epoll返回时,该事件已经可读写,解决了;对于问题2,设置了超时时间,epoll有高效的实现,代替我们去做check,解决了。

​ Nginx的Worker进程相较于Apache来说,如此之少,为何效率更高?很大一部分原因还是减少进程/线程上下文切换的开销,对于Nginx,有进程的切换,但因为数量少,而且因为更多的切换是请求间的切换,切换是因为事件未准备好,可以理解为循环地去处理已准备好的事件,进程上下文切换频率不高,开销很小。反观Apache,大量的线程,提升了切换的频率,这里的切换又是上下文的切换,开销也就很大了。并且Nginx可以设置CPU的亲缘性绑定,将进程绑定在CPU的某个核上,如果Nginx进程数刚好等于CPU核数,这样就能更好地减少不必要的进程上下文切换了,还减少了一些cache的重复写入操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nginx 优化