1. 引入
Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器。特点是占有内存少,并发能力强,事实上 Nginx 的并发能力确实在同类型的网页服务器中表现较好。
Nginx 以“事件驱动”的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡。其拥有匹配 Lighttpd 的性能,同时还没有 Lighttpd 的内存泄漏问题,而且 Lighttpd 的 mod_proxy 也有一些问题并且很久没有更新。
Nginx 做为 HTTP 服务器,有以下几项基本特性:
- 处理静态文件,索引文件以及自动索引;打开文件描述符缓冲。
- 无缓存的反向代理加速,简单的负载均衡和容错。
- FastCGI,简单的负载均衡和容错。
- 模块化的结构。包括 gzipping,byte ranges,chunked responses,以及 SSI-filter 等 filter。如果由 FastCGI 或其它代理服务器处理单页中存在的多个 SSI,则这项处理可以并行运行,而不需要相互等待。
- 支持 SSL 和 TLSSNI。
Nginx 可以作为静态页面的 web 服务器,同时还支持 CGI 协议的动态语言,比如 perl、php 等。但是不支持 Java(Java 程序只能通过与 tomcat 配合完成)。
Nginx 专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率。它支持内核 poll 模型,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。Nginx 具有很高的稳定性。其它 HTTP 服务器,当遇到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应,只能重启服务器。例如当前 apache 一旦上到 200 个以上进程,web 响应速度就明显非常缓慢了。而 Nginx 采取了分阶段资源分配技术,使得它的 CPU 与内存占用率非常低。Nginx 官方表示保持 10,000 个没有活动的连接,它只占 2.5M 内存,所以类似 DOS 这样的攻击对 Nginx 来说基本上是毫无用处的。就稳定性而言,Nginx 比 lighthttpd 更胜一筹。
Nginx 支持热部署。它的启动特别容易, 并且几乎可以做到 7*24 不间断运行,即使运行数个月也不需要重新启动。你还能够在不间断服务的情况下,对软件版本进行进行升级。
Nginx 采用 master-slave 模型,能够充分利用 SMP 的优势,且能够减少工作进程在磁盘 I/O 的阻塞延迟。当采用 select()/poll() 调用时,还可以限制每个进程的连接数。
2. 相关概念
2.1 正向代理
Nginx 不仅可以做反向代理,实现负载均衡。还能用作正向代理来进行上网等功能。
如果把局域网外的 Internet 想象成一个巨大的资源库,则局域网中的客户端要访问 Internet,则需要通过代理服务器来访问,这种代理服务就称为"正向代理"。
2.2 反向代理
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,再返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器 IP 地址。
2.3 负载均衡
客户端发送多个请求到服务器,服务器处理请求,有一些可能要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。
这种架构模式对于早期的系统相对单一,并发请求相对较少的情况下是比较适合的,成本也低。但是随着信息数量的不断增长,访问量和数据量的飞速增长,以及系统业务的复杂度增加,这种架构会造成服务器相应客户端的请求日益缓慢,并发量特别大的时候,还容易造成服务器直接崩溃。很明显这是由于服务器性能的瓶颈造成的问题,那么如何解决这种情况呢?
我们首先想到的可能是升级服务器的配置,比如提高 CPU 执行频率,加大内存等提高机器的物理性能来解决此问题,但是我们知道摩尔定律的日益失效,硬件的性能提升已经不能满足日益提升的需求了。最明显的一个例子,天猫双十一当天,某个热销商品的瞬时访问量是极其庞大的,那么类似上面的系统架构,将机器都增加到现有的顶级物理配置,都是不能够满足需求的。那么怎么办呢?
上面的分析我们去掉了增加服务器物理配置来解决问题的办法,也就是说纵向解决问题的办法行不通了,那么横向增加服务器的数量呢?这时候集群的概念产生了,单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的 "负载均衡"。
2.4 动静分离
为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。
3. 安装
3.1 所需安装包
- pcre-8.37.tar.gz
- openssl-1.0.1t.tar.gz
- zlib-1.2.8.tar.gz
- nginx-1.12.2.tar.gz
3.2 逐个安装
- 安装 pcre 依赖
tar -xvf pcre-8.37.tar.gz cd pcre-8.37/ ./configure make && make install pcre-config --version [查看版本]
- 安装 openssl 、zlib 、 gcc 依赖
yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
- 安装 nginx
tar -xvf nginx-1.12.2.tar.gz cd nginx-1.12.2/ ./configure make && make install
3.3 有关命令
前提:均要在 /usr/local/nginx/sbin 目录下执行!
- 【启动】
./nginx
- 【关闭】
./nginx -s stop
- 【重启】
./nginx -s reload
- 【查看版本】
./nginx -v
3.4 访问测试
启动之后,通过 Win 浏览器访问报 404。
- 确认 nginx 配置是否 OK
- 确认网络是否可达。根据报错原因,继而又通过
netstat -anp | more
查看端口监听情况,nginx 确实在监听 80 端口。
- 是否受防火墙安全控制 ← 404 原因!
- 排除以上原因之后,远程实际再测试。
4. 配置文件
4.1 文件所在位置
4.2 文件内容结构
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
根据上述文件,我们可以很明显的将 nginx.conf 配置文件分为 3 部分。
4.3 全局块
从配置文件开始到 events 块之间的内容,主要会设置一些影响 Nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。
比如上面第一行配置的:worker_processes 1;
这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约。
4.4 events 块
events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word process 可以同时支持的最大连接数等。
上述例子就表示每个 work process 支持的最大连接数为 1024,这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。
4.5 http 块
这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。
需要注意的是:http 块也可以包括 http 全局块、server 块。
4.5.1 http 全局块
http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。
4.5.2 server 块
这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机;而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。
【全局 server 块】最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。
【location 块】一个 server 块可以配置多个 location 块。这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是 IP 别名)之外的字符串(例如前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
5. 原理
5.1 工作模式
5.2 相关问题
1. Master-Workers 的机制的好处
首先,对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。
其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快启动新的 worker 进程。
当然,worker 进程的异常退出,肯定是程序有 bug 了,异常退出会导致当前 worker 上的所有请求失败,不过不会影响到所有请求,所以降低了风险。
2. 需要设置多少个 worker?
Nginx 同 Redis 类似都采用了 IO 多路复用机制,每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话下。每个 worker 的线程可以把一个 CPU 的性能发挥到极致。所以 worker 数和服务器的 CPU 数相等是最为适宜的。设少了会浪费 CPU,设多了会造成 CPU 频繁切换上下文带来的损耗。
3. 连接数 worker_connection
这个值是表示每个 worker 进程所能建立连接的最大值,所以,一个 Nginx 能建立的最大连接数,应该是 worker_connections * worker_processes
。
当然,这里说的是最大连接数,对于 HTTP 请求本地资源来说 , 能够支持的最大并发数量是 worker_connections * worker_processes
;如果是支持 HTTP 1.1 的浏览器每次访问要占两个连接,所以普通的静态访问最大并发数是: worker_connections * worker_processes / 2
;
而如果是 HTTP 作为反向代理来说,最大并发数量应该是 worker_connections * worker_processes / 4
。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,也会占用 2 个连接。