从技术的角度剖析Nginx框架


众所周知,nginx 性能高,而 nginx 的高性能与其架构是分不开的。

1、nginx 多进程模式架构

nginx 启动后,会有一个master 进程和多个 worker 进程。

master 进程用来管理 worker 进程,功能包含:接收来自外界的信号,向各个worker 进程发送信号,监控woker进程的运行状态。

当worker 进程退出(异常退出),会自动重启启动新的worker 进程。

worker 进程:处理基本的网络事件。多个worker 进程之间对等。同等竞争来自客户端的请求,各进程独立。每个请求只能在一个worker 进程中处理,每个进程不会处理其他进程请求。

worker的个数可以设置,一般设置为cpu核数一致。


在这里插入图片描述


2、nginx 多进程模型的优势

那么,nginx 采用这种进程模型有什么好处呢?

  • 首先,对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查上时,也会方便很多。
  • 其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快重新启动新的 worker 进程,降低了风险。

3、worker 进程处理请求流程

nginx 在 0.8 版本之后,引入了一系列命令行参数,来方便我们管理。

例如:

重启 nginx:

./nginx -s reload   

停止 nginx:

./nginx-s stop

我们执行命令时,启动了一个新的 nqinx 进程,新的 nginx 进程在解析到reload 参数后,就控制 nginx 重新加载配置文件,它会向 master 进程发送信号。


那么worker 进程又是如何处理请求的呢?

假如:我们提供 80 端口的 http 服务,一个连接请求过来,每个进程都有可能处理这个连接,怎么做到的呢?

首先,在 master 进程里面,先建立好需要 listen 的 socket ,然后再 fork 出多个 worker 进程。

这样每个 worker 进程都可以去 accept 这个 socket (每个进程的socket 会监控在同一个 ip 地址与端口,这个在网络协议里面是允许的)。

当一个连接进来后,所有在 accept 在这个 socket 上面的进程,都会收到通知,而只有一个进程可以accept 这个连接,其它的则 accept 失败,这是所谓的惊群现象。


nginx 是怎么来解决惊群现象呢?

nginx提供了一个 accept mutex,从名字上,我们可以知道这是一个加在 accept 上的共享锁。同一时刻,就只会有一个进程在 accpet 连接。accept mutex 是一个可控选项,默认是打开,我们可以显示地关掉。

当一个 worker 进程在 accept 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这就是一个完整的请求。

由此正如前面所说:一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。


4、nginx如何处理事件?

上面说了很多关干的进程模型,接下来,我们来看看 nginx的是如何处理事件的。

可能有人会问:nginx 采用多 worker 的方式来处理请求,每个 worker 里面只有一个主线程,那高并发处理怎么做到的?

nginx非常高明,采用了异步非阻塞的方式来处理请求,可以同时处理成千上万个请求


nginx 异步非阻塞到底是怎么回事呢?

前面所说,请求的完整过程如下:

首先,请求过来,要建立连接,然后再接收数据,接收数据后,再发送数据。

具体到系统底层,就是读写事件,而当读写事件没有准备好时,必然不可操作。

如果不用非阻塞的方式来调用,那就得阻塞调用,事件没有准备好,那就只能等了,等事件准备好了,再继续。阻塞调用会进入内核等待,cpu 利用率自然上不去了,更别谈高并发了。在 nginx 里面,最忌讳阻寒的系统调用。不要阻塞那就非阻塞。非阻塞就是,事件没有准备好,马上返回 EAGAIN,告诉你,事件还没准备好,过会再来。过一会,再来检查一下事件,直到事件准备好了为止,在这期间,可以先去做其它事情,然后再来看看事件好了没。

虽然不阻塞了,但你得不时地过来检査一下事件的状态,你可以做更多的事情了,但带来的开销也是不小的。

所以,才会有了异步非阻塞的事件处理机制

异步非阻塞的事件处理机制,具体到系统调用就是像 selectpoll/epoll/kgueue 这样的系统调用 ,可以同时监控多个事件,调用他们是阻塞的,但可以设置超时时间,在超时时间之内,如果有事件准备好了,就返回。


这种机制正好解决了我们上面的两个问题。

以epoll 为例 ,当事件没准备好时,放到epoll 里面,事件准备好了,我们就去读写,当读写返回 EAGAIN 时,我们将它再次加入到 epoll 里面。这样,只要有事件准备好了,我们就去处理它,只有当所有事件都没准备好时,才在 epol 里面等着。这样,我们就可以并发处理大量的并发。


当然,这里的并发请求,是指未处理完的请求,线程只有一个,所以同时能处理的请求只有一个,只是在请求间进行不断地切换而已,切换也是因为异步事件未准备好,而主动让出。这里的切换是没有任何代价,可以理解为循环处理多个准备好的事件。

与多线程相比,这种事件处理方式是有很大的优势的,不需要创建线程,每个请求占用的内存也很少,没有上下文切换,事件处理非常的轻量级。并发数再多也不会导致无谓的资源浪费(上下文切换)。更多的并发数,只是会占用更多的内存而已。


有人对连接数进行过测试,在 24G 内存的机器上,处理的并发请求数达到过 200万。

这也是 nginx 性能高效的主要原因。


我们之前说过,推荐设置 worker 的个数为 cpu 的核数,在这里就很容易理解了,过多的 worker 数,只会导致进程来竞争 cpu 资源,从而带来不必要的上下文切换。


而且,nginx为了更好的利用多核特性,提供了cpu 亲缘性的绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来 cache 的失效。


像这种小的优化在 nginx 中非常常见,同时也说明了 nginx 作者在性能优化上的深厚造诣。比如,nginx 在做 4个字节的字符串比较时,会将 4个字符转换成一个 int 型,再作比较,以减少 cpu 的指令数等等。

至此,相信大家应该都清楚 nginx 什么会选择这样的进程模型与事件模型了吧~


5、nginx如何处理信号与定时器?


对于一个 web 服务器来说,事件通常有三种类型,网络事件、信号、定时器。通过上面的讲解,网络事件通过异步非阻塞事件机制可以很好的解决掉。


(1)、nginx如何处理信号

首先,信号的处理。对nginx 来说,有一些特定的信号,代表着特定的意义。信号会中断掉程序当前的运行在改变状态后,继续执行。如果是系统调用,则可能会导致系统调用的失败,需要重入。

对于 nginx来说,如果nginx 正在等待事件(epoll wait 时),如果程序收到信号,在信号处理函数处理完后,epoll wait 会返回错误,然后程序可再次进入 epoll wait 调用。


(2)、nginx如何处理定时器

我们再来看看定时器。

由于 epoll wait 等函数在调用的时候,可以设置一个超时时间,所以 nginx 借助这个超时时间来实现定时器。

nginx里面的定时器事件是放在一个最小堆里面,每次在进入 epoll wait 前,先从最小堆里面拿到所有定时器事件的最小时间,在计算出 epoll wait 的超时时间后进入 epoll wait。

所以,当没有事件产生,也没有中断信号时,epoll wait 会超时,也就是说,定时器事件到了。这时,nginx 会检查所有的超时事件,将他们的状态设置为超时,然后再去处理网络事件。

由此可以看出,当我们写 nginx 代码时,在处理网络事件的回调函数时,通常做的第一个事情就是判断超时,然后再去处理网络事件。


  • 41
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据提供的引用内容,可以了解到Nginx是一个高性能的Web服务器和反向代理服务器,它可以处理大量并发连接,并具有低内存消耗。Nginx技术框架主要包括以下几个方面: 1. 服务器架构:Nginx采用了事件驱动的异步非阻塞架构,通过使用少量的线程和内存来处理大量的并发连接请求,提高了服务器的性能和吞吐量。 2. 反向代理:Nginx可以作为反向代理服务器,将客户端的请求转发给后端的多个服务器,实现负载均衡和高可用性。 3. 静态文件服务:Nginx可以直接提供静态文件的访问,通过配置合适的缓存策略和压缩算法,提高了静态文件的传输效率。 4. 动态请求处理:Nginx可以与各种动态语言应用(如PHP、Python、Java等)进行集成,通过FastCGI、uWSGI等协议与后端应用服务器进行通信,实现动态请求的处理。 5. 负载均衡:Nginx支持多种负载均衡算法,如轮询、IP哈希、最少连接等,可以根据实际需求将请求分发给后端的多个服务器,提高系统的可扩展性和稳定性。 6. 缓存和压缩:Nginx可以通过配置缓存策略和压缩算法,提高静态文件的传输效率,减少网络带宽的占用。 7. 安全性:Nginx提供了多种安全功能,如访问控制、SSL/TLS加密、防止DDoS攻击等,保护服务器和应用的安全。 8. 日志和监控:Nginx可以记录访问日志和错误日志,通过监控工具可以实时监控服务器的状态和性能指标,帮助管理员及时发现和解决问题。 9. 扩展性:Nginx支持模块化的架构,可以通过编写自定义模块来扩展功能,满足特定的需求。 总结起来,Nginx技术框架包括了高性能的服务器架构、反向代理、静态文件服务、动态请求处理、负载均衡、缓存和压缩、安全性、日志和监控以及扩展性等方面的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w风雨无阻w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值