当前位置: 首页 > 科技观察

中间件--WebServer--Nginx

时间:2023-03-12 03:54:36 科技观察

Ngnix一直是I/O密集型服务的最佳选择。今天就把这两天关于Ngnix的基础知识整理一下,学习一下。如有错误,请指出,谢谢批评指正。Nginx通过异步非阻塞的事件处理机制实现高并发。Apache每次请求都占用一个线程,对系统资源的消耗很大。事件驱动适合IO密集型服务(Nginx),多进程或多线程适合CPU密集型服务(Apache),所以Nginx适合做反向代理,不适合web服务器。基本架构设计1.接口设计所有模块都遵循相同的ngx_module_t接口设计规范。2、Ngnix核心及其公共模块设计关系共有四个模块。首先是配置模块。配置模块是所有模块的基础。它实现了最基本配置项的解析功能。nginx定义了一个基本的模块类型:核心模块,模块类型为NGX_CORE_MODULE。定义核心模块的目的是让非模块化的框架代码只关注如何调用这6个核心模块。事件模块、HTTP模块、邮件模块的共同点是在核心模块中各有一个模块作为自己的代言人,核心业务和管理功能模块各有一个同类模块。事件模块是HTTP模块和邮件模块的基础。Nginx核心进程模型首先,nginx在正常执行时会有多个进程,最基本的是master进程(监控进程,也叫主进程)和woker进程(工作进程),可能还有缓存相关的进程。1、master进程监控进程作为整个进程组与用户的交互接口,同时对进程进行监控。不需要处理网络事件,不负责业务执行。它只管理worker进程实现重启服务、平滑升级、更改日志文件、配置文件实时生效等功能。TIPS:在master进程的for(::)死循环中有一个关键的sigsuspend()函数调用。这个函数调用意味着master进程大部分时间是挂起的,直到master进程收到信号。2、worker进程的基本网络事件都在worker进程中处理。wenkor之间的进程是对等的,只能在同一个wenkor中处理。一个wenkor进程是不可能处理其他进程的请求的。wenkors的个数一般设置为与cpu个数相同,所以我们在8080端口提供http请求服务时,每个进程都可能在一个请求到来时处理链接。因为worker多了只会导致进程之间相互竞争cpu资源,导致不必要的上下文切换3.进程master(master进程会先建立一个需要监听的socket)——fork生成子进程worker,继承socket(此时worker和子进程继承了父进程master的所有属性,当然也包括建立的socket,当然不是同一个socket,但是每个进程的socket都会被监听在相同的ip地址和端口,这在网络协议中是允许的)-当连接进来时,会发生令人震惊的群体现象。惊群现象:一般来说,当一个连接进来的时候,所有在这个socket上接受的进程都会收到一个通知,只有一个进程可以接受这个连接,其他的都接受不了。Nginx对触目惊心现象的处理:当一个worker进程接受连接后,开始读取请求,解析请求,处理请求,生成数据,然后返回给客户端,最后断开连接,一个完整的请求。一个请求完全由工作进程处理,并且只在一个工作进程中处理。Nginx的事件处理机制:首先,对于一个web服务器来说,基本的事务类型有:网络事件、信号和定时器。1、Ngnix采用异步非阻塞事件处理机制,循环处理多个准备好的事件,实现高并发和轻量级。2、使用信号事务机制通知worker进行详细工作:以epoll为例:当事件没有准备好时,放入epoll。如果事件准备就绪,则处理它;如果事件返??回EAGAIN,则继续放入epoll。所以,只要一个事件准备好了,我们就去处理她,所有的时间都没有准备好,才在epoll中等待。这样我们就可以并发处理大量的并发。当然,这里的并发请求是指未处理的请求。只有一个线程,那么当然同一时间只能处理一个请求,但是请求是不断切换的。就这样,因为异步事件没有准备好,switch也主动放弃了。在这里切换是免费的。你可以理解为循环处理多个准备好的事件。题外话。Nginx和Apache对于高并发处理的区别对于Apache来说,每个请求都会独占一个工作线程。当并发数达到几千小时的时候,同时处理请求的线程有上千个。对于操作系统来说,这会占用大量内存,线程上下文切换带来的CPU开销也很大,难以提升性能。同时,这些开销是完全没有意义的。对于Nginx,一个进程只有一个主线程。通过异步非阻塞的事件处理机制,实现多个准备好的事件的循环处理,从而达到轻量级和高并发。Nginx对比Apache:事件驱动适用于IO密集型服务,多进程或线程适用于CPU密集型服务1.Nginx主要用作反向代理而不是Web服务器。它的网络模式是事件驱动的(select、poll、epoll)。2.事件驱动的本质还是IO事件。应用程序在多个IO句柄之间快速切换,实现所谓的异步IO。3、事件驱动的服务器最适合这种IO密集型的工作,比如反向代理,充当客户端和WEB服务器之间的数据中转。纯IO操作,不涉及复杂的计算。.4.反向代理是事件驱动的,明显更好。一个工作进程可以在没有进程和线程管理开销的情况下运行,CPU和内存消耗小。5.当然Nginx也可以是多进程+事件驱动的模式。几个进程运行libevent,不需要像Apache那样上百个进程。6、Nginx在处理静态文件方面也很有效,因为静态文件本身也是磁盘IO操作,处理过程也是一样的。至于有多少万并发连接,这个是没有意义的。我可以轻而易举地写出一个能处理几万个7)并发的网络程序,但如果大部分客户端都堵在那里,那价值不大。查看Apache或Resin等应用程序服务器。它们之所以被称为应用服务器,是因为它们确实需要运行特定的业务应用程序,例如科学计算、图形、数据库读写等。它们很可能是CPU密集型服务,事件驱动不适合。1、比如一个计算需要2秒,那么这2秒就完全阻塞,不使用任何事件。想想如果MySQL改成事件驱动会怎么样,一个大的join或者sort会阻塞所有的clients。2、这时候多进程或者线程就体现出了它的优势。每个进程各干各的,互不阻塞,互不干扰。当然,现代的CPU越来越快,单次计算阻塞的时间可能很少,但是只要有阻塞,事件编程就没有优势了。因此,进程、线程等技术并不会消失,而是与事件机制相辅相成,长期存在。综上所述,事件驱动适用于IO密集型服务,多进程或线程适用于CPU密集型服务。各有各的优势,没有相互替代的趋势。