Nginx 技术调研
经常听说NGINX,出于好奇心研究一下。
1. 基本功能
nginx的基本定位是http服务器,要注意和tomcat等应用服务器区分开。虽然他们都能提供基于http的静态资源的访问,我发现一篇文章写的还是很清楚。就引用下它的一段话:
nginx常用做静态内容服务和代理服务器,直接外来请求转发给后面的应用服务器(tomcat,Django等),tomcat更多用来做一个应用容器,让java web app泡在里面的东西。严格意义上来讲,Apache和nginx应该叫做HTTP Server,而tomcat是一个Application Server是一个Servlet/JSP应用的容器。客户端通过HTTP Server访问服务器上存储的资源(HTML文件,图片文件等),HTTP Server是中只是把服务器上的文件如实通过HTTP协议传输给客户端。应用服务器往往是运行在HTTP Server的背后,执行应用,将动态的内容转化为静态的内容之后,通过HTTP Server分发到客户端
nginx的基本功能就是负载均衡和反向代理,负责流量分发,过滤等,不负责对请求做处理,这些是Tomcat之类的去做的。
2. 原理
2.1 事件驱动模型
从根本上来说,NGINX和其他服务器诸如Apache最根本的区别是,它是基于事件驱动的。参考文章【1】中讲的,NGINX在一台机器上启动,有几个CPU就启动几个Worker线程(负责干活的),还有一个Master进程负责管理啥的(这不是重点!)。重要的是Worker线程的工作方式。
连接(Connection)会被放到一个队列里面,队列里面的每个连接都是活着的,且都会建立一个套接字,称为连接套接字,但是不一定有请求。这个连接套接字需要和Worker线程的“监听套接字”区分开,监听套接字是负责监听新的连接到来,连接套接字是监听已连接用户的请求。一个图解释下:
上面的图中左半部分是新的连接到来的流程,走的是Worker进程的监听端口;右半部分是已经和服务器建立连接的用户发送新的HTTP请求的时候走的流程。
其实很多场景下,用户和服务器建立了HTTP连接,很少发送请求,就是偶尔刷新下。这些连接都是inactive的,即活动不频繁的。NGINX将这些inactive的已建立用户连接到一个列表中,哪个用户有请求就搞哪个!相对一个连接对应一个线程的模型来说,省了资源不说,还极大的增加了效率。
下面是文章【2】描述的连接进入NGINX时的整体流程:
你可以看到NGINX的worker线程(负责监听新连接的进程)就是一个状态机,状态机内部机制可以这张图的Life of HTTP Request部分。大致意思是要不生成响应给用户,要不就是重定向到上游应用。途中进行负载均衡,限流,验证之类的事情。
2.2 端口占用
刚才说到,Worker线程需要为已建立连接用户分配一个端口,实际上不是每个用户连接建立一个连接套接字,而是共享。
可以参考:Socket Sharding in NGINX Release 1.9.1
3. Complete-NGINX-Cookbook
3.1 负载均衡应该考虑的问题
- 会话保持
有状态应用需要用户的多个请求分发到同一个服务器上面 - 上游应用服务器的健康检查
nginx 开源版的检测方式,当用户发送请求时才会检查上游应用服务器的状态,这种检测方式成为被动检测方式。
主动检测方式是nginx主动周期检测上游服务器,但是只有在收费版nginx plus中可用。