初探Nginx架构
nginx在启动后,在unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。我们也可以手动地关掉后台模式,让nginx在前台运行,并且通过配置让nginx取消master进程,从而可以使nginx以单进程方式运行。很显然,生产环境下我们肯定不会这么做,所以关闭后台模式,一般是用来调试用的,在后面的章节里面,我们会详细地讲解如何调试nginx。所以,我们可以看到,nginx是以多进程的方式来工作的,当然nginx也是支持多线程的方式的,只是我们主流的方式还是多进程的方式,也是nginx的默认方式。nginx采用多进程的方式有诸多好处,所以我就主要讲解nginx的多进程模式吧。
nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。
nginx的进程模型,可以由下图来表示:
Nginx 的负载均衡策略
负载均衡技术少不了相关的均衡策略,Nginx 中提供了 4 种均衡策略,我们可以根据具体的业务场景选择合适的均衡策略。下面分别介绍这 4 中均衡策略:
1 基于轮询的均衡策略
轮询嘛,就是说对进到nginx的request按照遍历的方式进行分发,如果request 1 分发到 Server A,那么request 2将被分发到 Server B,……以此循环类推。
2 基于最少连接数的均衡策略
最少连接,也就是说nginx会判断后端集群服务器中哪个Server当前的 Active Connection 数是最少的,那么对于每个新进来的request,nginx将该request分发给对应的Server。
3 基于ip-hash的均衡策略
我们都知道,每个请求的客户端都有相应的 IP 地址,该均衡策略中,nginx将会根据相应的hash函数,对每个请求的 IP 作为关键字,得到的hash值将会决定将请求分发给相应Server进行处理。
4 基于加权轮询的均衡策略
加权轮询,很显然这个策略跟我们开题引入的场景是一样的,nginx会给Server配置相应的权重,权重越大,接收的request数将会越多。
惊群现象
主进程(master 进程)首先通过 socket() 来创建一个 sock 文件描述符用来监听,然后fork生成子进程(workers 进程),子进程将继承父进程的 sockfd(socket 文件描述符),之后子进程 accept() 后将创建已连接描述符(connected descriptor),然后通过已连接描述符来与客户端通信。
那么,由于所有子进程都继承了父进程的 sockfd,那么当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。大量的进程被激活又挂起,只有一个进程可以accept() 到这个连接,这当然会消耗系统资源。
Nginx对惊群现象的处理
Nginx 提供了一个 accept_mutex 这个东西,这是一个加在accept上的一把共享锁。即每个 worker 进程在执行 accept 之前都需要先获取锁,获取不到就放弃执行 accept()。有了这把锁之后,同一时刻,就只会有一个进程去 accpet(),这样就不会有惊群问题了。accept_mutex 是一个可控选项,我们可以显示地关掉,默认是打开的。
Nginx的应用场景
- 高性能HTTP服务器(动静分离)
- 反向代理(Reverse Proxy)服务器(负载均衡)
- 正向代理服务器
高性能HTTP服务器
Nginx可以作为一个高性能的HTTP服务器,以向用户提供静态资源。
反向代理(Reverse Proxy)服务器(负载均衡)
**反向代理(Reverse Proxy)**方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
通过一个反向代理服务器实现负载均衡是一个很常见的场景。
即,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。
反向代理的用途
**隐藏服务器真实IP:**使用反向代理,可以对客户端隐藏服务器的IP地址。
**负载均衡:**反向代理服务器可以做负载均衡,根据所有真实服务器的负载情况,将客户端请求分发到不同的真实服务器上。
**提高访问速度:**反向代理服务器可以对于静态内容及短时间内有大量访问请求的动态内容提供缓存服务,提高访问速度。
**提供安全保障:**反向代理服务器可以作为应用层防火墙,为网站提供对基于Web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等。还可以为后端服务器统一提供加密和SSL加速(如SSL终端代理),提供HTTP访问认证等。
正向代理(Forward Proxy)服务器
正向代理(Forward Proxy)通常都被简称为代理,就是在用户无法正常访问外部资源,比方说受到GFW的影响无法访问twitter的时候,我们可以通过代理的方式,让用户绕过防火墙,从而连接到目标网络或者服务。
正向代理的工作原理就像一个跳板,比如:我访问不了google.com,但是我能访问一个代理服务器A,A能访问google.com,于是我先连上代理服务器A,告诉他我需要google.com的内容,A就去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录,有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站。
结论就是,正向代理是一个位于客户端和原始服务器(origin server)之间的服务器。为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
正向代理的用途
**突破访问限制:**通过代理服务器,可以突破自身IP访问限制,访问国外网站,教育网等。
**提高访问速度:**通常代理服务器都设置一个较大的硬盘缓冲区,会将部分请求的响应保存到缓冲区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。
**隐藏客户端真实IP:**上网者也可以通过这种方法隐藏自己的IP,免受攻击。
Reference
- 《Nginx开发从入门到精通》 - http://tengine.taobao.org/book/index.html#id3
- Nginx 学习系列(二) ————- 负载均衡 - https://juejin.im/post/5b6a45d5f265da0f9402d118
- 理解Nginx工作原理 - https://www.jianshu.com/p/6215e5d24553
- 所有和Java中代理有关的知识点都在这了。 - https://mp.weixin.qq.com/s?__biz=MzI3NzE0NjcwMg==&mid=2650121631&idx=1&sn=c6cfbf6aaaf01899a1d36b562e881f11&chksm=f36bb8bec41c31a865ee13a40fbfa2636328651df3c6af13dd7378511d67eda0dfcc48ec732c&scene=21#wechat_redirect