1.1 简介
NGINX是一个轻量级高性能WEB、反向代理、邮件代理服务软件。NGINX的特点就是占内存少、并发能力强。
1.1.1 常见的WEB服务软件简介
1、Apache
Apache是一个老牌的、重量级WEB服务软件,Apache拥有非常丰富的模块,可以通过这些模块实现各种各样的WEB功能,运行非常稳定,但是相比其他WEB服务软件要消耗更多的内存和CPU资源。
2、Lighttpd
Lighttpd也是一个非常轻量级的WEB服务软件,其目标是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的WEB Server环境。它内存开销低、CPU占用率低、高性能。Lighttpd和NGINX都属于轻量级WEB服务软件,两者不相上下,也是我们一个不错的选择哦。
3、Tomcat
Tomcat是一个专门用于运行Servlet和JSP WEB应用的基于JAVA的WEB应用服务软件。Tomcat也支持对静态文件的处理,但是相对前两者并发能力较弱。
4、Microsoft IIS
Microsoft IIS是微软公司集成于Windows Server系统中的一个WEB服务软件,由于Windows系统用于运行服务较不稳定,相对于其他WEB服务软件,很少有人采用。
1.1.2 NGINX的优点
1、高并发
NGINX采用最新的EPOLL(Linux2.6内核)高效事件驱动模型,异步非阻塞型处理请求连接,官方测试NGINX能够支撑5万的并发连接数,在实际生产环境中可支撑2~4万并发连接数。其工作效率是Apache的5倍以上。
服务器配置清单:双核CPU 5140@2.33GHz,4GB内存。
2、轻量级
实际数据测试,NGINX+PHP(FastCGI)环境下的服务器在3万并发连接下,开启的10个NGINX进程才消耗150MB内存,开启的64个PHP-CGI进程消耗了1280MB内存,在加上系统自身消耗的内存,总共消耗不到2GB的内存。
服务器配置清单:双核CPU 5140@2.33GHz,4GB内存。
3、其他优点
NGINX配置文件通俗易懂、支持Rewrite地址重写、支持七层和四层的负载均衡、健康检查、会话保持、传输压缩等等各种丰富的功能。
1.1.3 事件驱动模型
我们将请求和响应的总和称之为一个事件。事件驱动模型就是从套接字获取请求、处理请求、发送响应的方法。
套接字(Socket)是用于不同主机进程之间网络通信的系统机制。不同主机进程与进程之间想要进行网络通信(消息交换)就必须通过套接字来完成。套接字工作在应用层和传输层之间,我们可以理解为是一个抽象接口层。
理解:
同一台机器两个进程之间相互分享数据、传输信息,可以通过共享内存的方式来完成,而不同主机两个进程之间相互交换信息就需要使用套接字,当需要发生消息传递时,客户端主机的进程将消息写入客户端的套接字然后传递给服务端主机,服务端主机实时监听端口,当有消息传输时则读取并将消息写入到自己的套接字中,然后服务端主机的进程读取自己的套接字即可完成消息的交换。
套接字通信过程:
那么事件是如何触发的那?
当NGINX服务运行时,会创建服务端的套接字,套接字绑定IP+端口,当客户端请求时,客户端的套接字信息会传入服务端的套接字中,事件驱动模型实时监控服务端的套接字文件描述符(句柄),当文件描述符发生了变化,就触发了事件,然后会分配一个线程去处理。
在Linux操作系统中,NGINX支持三种事件驱动模型:Select、Poll、EPOll。EPOll在三者中是最高效的事件驱动模型,NGINX的高并发也得益于它。
Select模型是最早的事件驱动模型,几乎兼容所有的系统平台,Select在监听套接字时,它会循环遍历所有的套接字文件描述符(句柄),当那个套接字发生变化的时候才会触发事件去处理,而且Select只支持一个进程同时打开1024个文件描述符,所以你想要实现100万的并发处理,则需要开启100个进程才可以实现,因此效率是非常低的。
Poll模型是在Select模型上的优化版,它的工作原理和Select一样,但是没有了文件描述符的限制。
EPOll模型是最高效的事件驱动模型,需要在Linux内核版本2.6以上的操作系统才可以使用,它是Poll模型的升级版,EPOll模型不需要遍历所有的套接字文件描述符,是基于事件响应的,当有套接字发生变化则立即处理,也没有文件描述符的限制,因此效率是非常高效的。
理解:
在一个学校中,有很多个教师,若我想找一个人,则需要一个教室一个教室的去找,非常耗时,这既是Select/Poll模型,而EPOll模型则会把每个教室的人的名单记录到一个本子上,当我要找时直接对应名单就可以立即知道这个人在那个教室,这样效率非常高。Select/Poll模型无参照物,而EPOll模型有参照物,直接进行对比出结果。
1.1.4 响应传输方式
线程在处理响应时,需要叫内存去硬盘中拿取数据,然后数据加载到内存中,线程读取内存中的响应数据,将其传递给用户。NGINX对于线程从硬盘中读取响应数据的处理方法有两种:AIO和Sendfile。
1、AIO(异步非阻塞)
当请求来时,内存需要去硬盘拿数据,这个时候线程无需等待(非阻塞),它会去做其他的事情,当数据完全接受了,会重新分配一个新的线程去做响应处理(异步),对于要传输大型文件时,我们可以采用此种传输方式。
2、Sendfile(高效传输模式)
当请求来时,直接叫线程去硬盘中读取响应数据,并传递给用户,对于一些小型的WEB应用,小型文件传输则考虑采用此种传输方式,传输效率更高,但是在高并发的场景下要考虑磁盘IO的并发负载量。