Nginx (engine x) 是一个轻量级,高性能的 HTTP 和 反向代理 服务,也是一个IMAP/POP3/SMTP服务。因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。
nginx的优点:
1、高并发,高性能(单机环境下参考服务器配置,并发连接数在7000+到8000左右。集群模式20000+)
2、高可靠。可以7*24小时不间断运行
3、可扩展性强。模块化设计,使得添加模块非常的平稳。
4、支持热部署。可以在不停止服务器的情况下升级nginx
5、BSD许可证。nginx不止开源免费的,我们还可以更具实际需求进行定制修改源代码
最大的区别:事件驱动模型不一样,nginx使用的是异步非阻塞模式,apache使用的同步阻塞模式。
特性 | Nginx | Apache |
---|---|---|
请求管理 | 事件驱动模型,使用异步套接字处理,占用较少的内存和CPU开销 | 同步套接字、进程和线程每个请求都要使用一个单独的进程或线程,使用同步套接字 |
设计语言 | C | C、C++ |
可移植性 | 多平台 | 多平台 |
诞生时间 | 2002 | 1994 |
功能 | Nginx | Apache |
---|---|---|
HTTPS支持 | 作为模块支持 | 作为模块支持 |
虚拟主机 | 原生支持 | 原生支持 |
CGI支持 | 仅支持FastCGI | 支持CGI和FastCGI |
系统模块 | 静态模块系统 | 动态模块系统 |
FastCGI的介绍
快速通用网关接口(Fast Common Gateway Interface/FastCGI)是通用网关接口(CGI)的改进,描述了客户端和服务器程序之间传输数据的一种标准。
FastCGI致力于减少Web服务器与CGI程序之间互动的开销,从而使服务器可以同时处理更多的Web请求。
与为每个请求创建一个新的进程不同,FastCGI使用持续的进程来处理一连串的请求。这些进程由FastCGI进程管理器管理,而不是web服务器。
从以上功能上的对比,我们很难发现哪些功能Apache无法实现。
从技术层面深度剖析nginx程序的设计思想
多并发在生活中的案例:超市收银口的收银员,将每个收银口看成一个处理请求的线程,当人数不多的时候,开一个收银口一个收银员就能应付,但是当人数多起来了,一个收银口应付不来那么多人了(对应的是海量的请求),这时就需要开启多个收银口来应对大量的顾客,而顾客则可以根据收银员的忙碌程度进程自由选择的排队
一个请求到来了,nginx使用epoll接收请求的过程是怎样的?
- select,poll,epoll 都是I/O多路复用的具体的实现,其实是他们出现是有先后顺序的。
- I/O多路复用这个概念被提出来以后, 相继出现了多个方案,但是都需要linux内核支持
- select是第一个实现 (1983 左右实现的)。 select 被实现以后,很快就暴露出了很多问题。
- select 任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数据,于是你只能自己一个一个的找,10几个sock可能还好,要是几万的#sock每次都找一遍就跟快递员送快递一样,每次快递到了都得你自己去快递箱里面找,可想而知多麻烦
- select 只能监视1024个链接。
- select 线程不是安全的。
- 于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的很多问题,比如
- poll 去掉了1024个链接的限制,于是可以有多个连接进来。?但是poll仍然线程不是安全的,这就意味着,不管服务器有多强悍,也只能在一个线程里面处理一组I/O流。
- epoll:可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题,比如
- epoll 现在是线程安全的。
- epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。
ngnix会有很多连接进来, 默认采用epoll会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相应的代码处理。
//查看服务器中nginx的worker进程
# yum -y install psmisc
# pstree |grep nginx
|-+= 81666 root nginx: master process nginx
| |--- 82500 nobody nginx: worker process
| \--- 82501 nobody nginx: worker process
//1个master进程和n个work进程
每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?
处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。
那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是【异步】。
此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是【异步回调】。
当我们使用一个简单的读取文件的操作来举例说明:
同步和异步是针对程序等待操作完成的方式,阻塞和非阻塞是针对程序等待I/O操作完成的方式。