nginx详情介绍
Nginx的功能【重点记住】:
1、高性能的HTTP Server,解决C10k的问题(PS:如果没有这么高的并发量都不会有运维这个行业) apache 200 2000
2、高性能的反向代理服务器(负载均衡器),代理web服务器(用的最多)
3、IMAP/POP3/SMTP服务器(基本不使用)
nginx的反向代理介绍:
架构:
client nginx http http http http
PHP PHP PHP PHP
client访问nginx就可以访问到后端web服务器。访问静态页面直接代理到http,访问动态页面就代理到PHP上。nginx对操作系统本身的性能消耗是非常小的,所以由它来接收客户端连接,可以增加客户端的访问速度。另nginx支持缓存功能,客户端访问网站的首页比较多,如果同时有5000个客户端请求,没有缓存会增加nginx代理和web的交互,但是有缓存就可以加快访问速度。大多数加快网站的访问速度的方法都是缓存,当然缓存不仅仅可以使用nginx服务器,还可以专门搭建一个缓存服务器。
Nginx的发展
netcraft.net网站每个月统计一次全球网站使用的软件
Nginx的特性:
apache的功能nginx都具有,且配置简单,但其稳定性没有apache好
轻量级、高性能:对cpu等硬件资源消耗小(在早期官网上测试:10000个非活跃的HTTP KEEPALIVE连接仅占用2.5M内存);taobao和阿里曾对nginx做过测试,最多支持5万个并发连接(apache的并发量为200,到达2000就变得很慢,通过集群,并发量可以达到2万左右))
基于模块化设计
基于EPOLL事件驱动模型,所以是高性能 select epoll
重新加载配置及在线升级时,不需要中断正在处理的请求(nginx热部署),可以做到平滑升级
带缓存的日志写操作,支持日志是最基本的功能
URL重写(rewrite)模块
支持验证HTTP referer,实现反倒链机制。所谓反倒链就是网站上的某一个页面只允许在该网站上点击此超链接跳转,不允许别人仿照写的页面跳转到我们的超链接,apache没有这个功能。
支持sendfile,将数据在内核中直接封装响应客户端,不需要将数据复制到进程地址空间。sendfile是linux进程内核里面的一种机制,这个机制也是为了加快网站服务器的访问速度。
支持缓存功能
事件驱动模型
这是nginx比apache更优秀的原因,在说事件驱动模型之前先了解以下几个概念:同步和异步,阻塞和非阻塞
同步机制和异步机制:
用于描述网络中的主机通信的模式
同步机制
发送方发送请求后,需要等待接收方回应,才会继续发送下一个请求,效率不高
异步机制
发送方发送请求后,不等待接收文回应,继续发送下一个请求
阻塞和非阻塞:
用于描述进程处理IO调用的方式 (和磁盘打一次交道就是一次IO)
阻塞机制
调用结果返回前,进程会从运行状态切换到挂起状态,待调用结果返回后,进程再次进入就绪状态,获取CPU后继续执行
非阻塞机制
调用结果如果不能及时返回,进程也不会进入挂起状态,而是开始处理下一个请求,待调用结果返回时,进程暂停运行该任务,开始继续处理上一个任务
Nginx上面的某一个进程收到客户端的一个访问请求,无论客户端访问的是哪个页面,进程都要去本地的磁盘找到网页文件,找到之后给客户端响应,但是nginx进程没有权限操纵硬件寻找网页,所以进程要先将请求转交给内核,由kernel去磁盘中搜索这个文件,找到文件将文件返回给进程,再由进程返回给客户端,所谓阻塞指的是:进程将请求转交给内核之后进程会一直等待内核返回给它结果才会接收其他的访问请求,而这段期间进程就处于sleeping的状态;而非阻塞指的是进程不会等待内核,而是可以继续接收下一个请求,当内核将第一个请求的结果返回给进程之后,进程会暂停当前正在接收的请求,来响应内核返回给它的结果。
软件处理事件有以下四种模式:
同步阻塞
同步非阻塞
异步阻塞
异步非阻塞(效率最高,nginx默认使用此种模式工作)
事件驱动模型
对于非阻塞来说让进程知道某一次请求的文件准备好的方法就叫做计算机内部的事件驱动模型;所谓驱动就是内核和进程之间的通讯模式
早期的事件驱动方式:
1、select事件驱动模型
进程每隔一段时间会问一下kernel,文件是否准备好?询问是要产生cpu上下文切换,内部中断等,需要消耗硬件资源,且效率不高,apache默认使用此种事件驱动模型。
2、epoll驱动模型
进程不询问,由kernel主动通知进程,节省资源消耗且效率高,是内核2.5之后才有的,在centos和rhel的linux里面的nginx的每一个进程在处理非阻塞的方式的时候就使用的是epoll
常见事件驱动模型介绍
在不同的操作系统上部署nginx时,需要选择相应的事件驱动,不能乱用,否则nginx启动不起来。且选好事件驱动,nginx的效率才会高。
SELECT
Linux, windows平台支持的事件驱动模型
首先,创建所关注事件的描述符集合。对于每一个描述符,需要关注其上面的读事件,写事件,异常事件;所以要创建三类事件描述符集合
调用底层以的select()函数,等待事件发生
轮询所有事件描述符,检查是否有事件发生,如果有,就进行处理
POLL
Linux平台支持的事件驱动模型,2.1.23版本内核中引入
和select一样,需要创建 一个关注事件的描述符集合,等待事件发生,轮询描述符集合,检测有没有事件发生,如果有,就执行
不一样的是,select需要创建三类描述符集合,而poll只需要创建一类集合,在每个描述符下分别创建读、写、异常事件,最后轮询时,可同时轮询
epoll(RHEL, CentOS)
Linux 2.5.44内核后引入
把描述符列表的管理交由内核负责,一旦有某种事件发生,内核把发生事件的描述符列表通知给进程,避免轮询减少系统开销
kqueue
支持BSD(free BSD)系列平台的高效事件驱动模型
/dev/poll
支持UNIX衍生平台(unix, IBM的AIX, hp-unix用在小型机的服务器上,价格昂贵)的高效事件驱动模型
eventport
支持Solaris linux10及以上版本平台的高效事件驱动模型。国内这个系统比较少,国外的多
================================================
select, poll, epoll小历史
都是内核支持的I/O多路复用的具体的实现,其实是他们出现是有先后顺序的。
I/O多路复用这个概念被提出来以后, select是第一个实现 (1983 左右在BSD里面实现的)。
select 被实现以后,很快就暴露出了很多问题。
• select 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的。
• select 如果任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数据,于是你只能自己一个一个的找,10几个sock可能还好,要是几万的sock每次都找一遍...
• select 只能监视1024个连接。
• select 不是线程安全的,如果你把一个sock加入到select, 然后突然另外一个线程发现,这个sock不用,要收回,这个select 不支持的,如果你丧心病狂的竟然关掉这个sock, select的标准行为是不可预测的
于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的很多问题,比如
• poll 去掉了1024个链接的限制,于是要多少连接呢, 主人你开心就好。
• poll 从设计上来说,不再修改传入数组,不过这个要看你的平台了,所以行走江湖,还是小心为妙。
其实拖14年那么久也不是效率问题, 而是那个时代的硬件实在太弱,一台服务器处理1千多个链接简直就是神一样的存在了,select很长段时间已经满足需求。但是poll仍然不是线程安全的, 这就意味着,不管服务器有多强悍,你也只能在一个线程里面处理一组I/O流。你当然可以那多进程来配合了,不过然后你就有了多进程的各种问题。
于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll.
epoll 可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比如:
• epoll 现在是线程安全的。
• epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。
=================================================
IO多路复用
方式1:最传统的多进程并发模型(每进来一个indexI/O流会分配一个新的进程管理)
方式2:I/O多路复用(单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流。发明它的原因是尽量多的提高服务器的吞吐能力。在同一个县城里面,通过拨开关的方式,来同时传输多个I/O流)
IO多路复用的具体实现技术是:epoll
Nginx的优势[重点]:
1、IO多路复用
2、高并发
3、epoll
4、异步
5、非阻塞
Nginx进程介绍:
Nginx启动时会启动一个master主进程及一个或多个worker子进程(worker通常和cpu的个数相同);配置缓存功能之后还会启动cache load和cache manager进程。所有进程以"共享内存"机制完成进程间通信;master进程以特权用户运行,其他进程以非特权用户运行。master进程本身不负责响应客户端的请求,而是由worker负责。
master主进程主要完成如下工作:
1、读取并验证配置文件是否有语法错误
2、创建、绑定、及关闭套接字socket(有这个套接字文件存在,客户端的请求进来才能访问)
3、启动、终止及维护worker进程的个数
4、无须中止服务而重新配置工作特性,可以做nginx的升级和老版本的回退
5、控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本
6、负责重新打开日志文件,记录日志
7、编译嵌入式perl脚本,如果nginx内部有perl语言写的脚本,脚本的执行也是master负责
worker进程主要完成如下工作:
nginx的每一个进程都是以异步非阻塞的方式工作的,指的是worker进程
1、接收、传入并处理客户端的连接
2、提供反向代理及过滤功能
3、IO调用,获取响应数据
4、与后端服务器通信,接收后端服务器处理结果
5、数据缓存、访问缓存索引、查询和调用缓存数据 -----> 提供缓存功能
6、发送请求结果,响应客户端请求
7、接收主程序指令,比如重启、退出、升级等
worker进程处理request并不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果(上游服务器)upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。
cache load进程主要完成的工作:
1、检查缓存存储中的缓存对象,以缓存数据响应客户端
2、使用缓存元数据建立内存数据库
cache manager进程的主要工作:
1、检查缓存的有效期,清理过期缓存
2、为了加快缓存数据的查找速度,使用manager进程给缓存数据生成索引。
=================================================
nginx比apache效率高的原因:
一、占用的资源少
二、使用的事件驱动模型比apache效率高