分布式系统架构:技术栈详解与快速进阶
上QQ阅读APP看书,第一时间看更新

第4章
分布式架构Nginx

Nginx是一个高性能的HTTP和反向代理Web服务器。Nginx可以作为一个HTTP服务器进行网站的发布处理,也可以作为反向代理进行负载均衡的实现,由于其占用内存少,并发能力强,所以可以广泛应用在互联网中。

本章重点内容如下:

  • Nginx工作原理
  • Nginx源码编译安装
  • Nginx配置
  • Nginx代理&负载均衡
  • Nginx缓存
  • Nginx限流
  • Nginx屏蔽
  • Nginx优化
  • Nginx高可用

4.1 Nginx工作原理

Nginx进程模型,如图4-1所示。

066-1

图4-1 Nginx进程模型

注意

Nginx默认采用多进程工作方式,其中Master负责对进程进行监护,管理Worker进程以实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能,而Worker用来处理基本的网络事件。

Nginx启动后,会生成一个Master进程和多个Worker进程。

Master进程工作原理:Master主进程充当整个进程组与用户的交互接口,同时管理Worker子线程,包括接收信号并将信号发送给Worker进程;监听Worker进程工作状态;当Worker进程非正常退出时,启动新的Worker进程。多个Worker进程之间是平等的,共同竞争来自客户端的请求,各进程之间相互独立,一个请求被一个Worker进程处理。

当Master进程收到重新加载的信号,如(./nginx -s reload),Master会重新加载配置文件,然后启动新的Worker进程来接收请求,并通知老的Worker进程。老的Worker进程处理完手中正在处理的请求就会退出。

Worker进程工作原理:Master会根据配置文件生成一个监听相应端口的Socket,然后复制多个Worker子进程,每个Worker子进程都可以监听Socket的消息。当一个连接过来时,每一个Worker都能收到通知,但是只有一个Worker能与这个连接建立关系,其他的Worker都会连接失败,而Nginx会提供一个互斥锁(accept_mutex),当连接过来时,只有一个Worker去接收这个连接。当一个Worker进程接收到accept连接之后,就开始读取、解析并处理请求,产生数据后,再返回给客户端,最后才断开连接。

那么互斥锁(accept_mutex)如何控制Worker进程接收并处理请求呢?

只有获得了accept_mutex的进程才会去添加accept事件。Nginx使用变量ngx_accept_disabled来控制是否去竞争accept_mutex锁(ngx_accept_disabled = Nginx单进程的所有连接总数/8 -空闲连接数量),当ngx_accept_disabled大于0时,不会去尝试获取accept_mutex锁,ngx_accept_disable越大,让出的机会就越多,这样其他进程获取锁的机会也就越大。不添加accept,每个Worker进程的连接数就控制下来了,其他进程的连接池就会得到充分利用,这样,Nginx就控制了多进程间连接的平衡。

为什么多个Worker进程能够同时接受上万个请求呢?

传统Web服务器,每个消费者独占一个线程,当并发量规模到十万及以上时,由于线程数目过多,会频繁消耗CPU资源,而当线程堵塞时,会挂载或睡眠,严重消耗服务器的资源,久而久之会到达服务器瓶颈。

Nginx服务器采用无阻塞事件驱动模型,它不会为每个消费事件创建一个进程或线程,不会由于进程间频繁切换占用CPU而产生瓶颈。Nginx将一个请求分为多个阶段来异步处理,每个阶段只处理请求的一部分,当请求的这部分发生阻塞,Nginx将不会等待,继续处理其他请求的某部分内容,当该阶段任务完成后再进入下一阶段。