中间件--Web Server--Nginx

栏目: 后端 · 发布时间: 5年前

内容简介:Ngnix一直以来都是I/O密集性服务的不二选择,今天就把这两天整理学习关于Ngnix的基本知识整理下,如果有错误,请大家指出,谢谢批评。Nginx 通过异步非阻塞的事件处理机制实现高并发。Apache 每个请求独占一个线程,非常消耗系统资源。事件驱动适合于IO密集型服务(Nginx),多进程或线程适合于CPU密集型服务(Apache),所以Nginx适合做反向代理,而非web服务器使用。

Ngnix一直以来都是I/O密集性服务的不二选择,今天就把这两天整理学习关于Ngnix的基本知识整理下,如果有错误,请大家指出,谢谢批评。

Nginx 通过异步非阻塞的事件处理机制实现高并发。Apache 每个请求独占一个线程,非常消耗系统资源。

事件驱动适合于IO密集型服务(Nginx),多进程或线程适合于CPU密集型服务(Apache),所以Nginx适合做反向代理,而非web服务器使用。

中间件--Web Server--Nginx

基本的架构设计

1、接口设计

所有的模块都遵循着同样的ngx_module_t接口设计规范。

2、Ngnix核心及其常用模块设计关系

中间件--Web Server--Nginx

总共有四个模块。

首先是配置模块,配置模块是所有模块的基础,他实现了最基本的配置项的解析功能。

nginx定义了一种基础类型的模块:核心模块,模块类型是NGX_CORE_MODULE。定义核心模块的目的是使得非模块化的框架代码只关注与如何调用6个核心模块。

事件模块、HTTP模块、mail模块这三种模块的共性是:实际上它们在核心模块中各有1个模块作为自己的代言人,并在同类模块中有1个作为核心业务与管理功能的模块。

事件模块是HTTP模块和mail模块的基础。

Nginx核心进程模型

首先,正常执行中的nginx会有多个进程,最基本的有master process(监控进程,也叫做主进程)和woker process(工作进程),还可能有cache相关进程。

1、master进程

监控进程充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。

TIPS:master进程中for(::)无限循环内有一个关键的sigsuspend()函数调用,该函数调用是的master进程的大部分时间都处于挂起状态,直到master进程收到信号为止。

2、worker进程

基本的网络事件,是放在worker进程中来处理的,wenkor之间的进程是对等的,只可能在相同的wenkor中处理,一个wenkor进程不可能处理其他进程的请求。

wenkor的个数,一般来说设置与cpu的个数相同,所以当我们提供8080端口的http请求服务时,一个请求过来,每个进程都有可能处理这个链接。因为更多的worker数,只会导致进程相互竞争cpu资源,从而带来不必要的上下文切换

3、处理过程

master(master进程会先建立好需要listen的socket)——–fork生成子进程workers,继承socket(此时workers子进程们都继承了父进程master的所有属性,当然也包括已经建立好的socket,当然不是同一个socket,只是每个进程的这个socket会监控在同一个ip地址与端口,这个在网络协议里面是允许的)——当一个连接进入,产生惊群现象。

惊群现象:一般来说,当一个连接进来后,所有在accept在这个socket上面的进程,都会收到通知,而只有一个进程可以accept这个连接,其它的则accept失败。

Nginx对惊群现象的处理:

当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,一个完整的请求。一个请求,完全由worker进程来处理,而且只在一个worker进程中处理。

Nginx的事件处理机制:

首先,对于一个web服务器来说,基本事务类型是:网络事件、信号、定时器。

1. Ngnix采用的是异步非阻塞的事件处理机制,由进程循环处理多个准备好的事件,从而实现高并发和轻量级。

2. 采用信号事务机制通知worker进行工作

详解: 以epoll为例:当事件没有准备好时,就放入epoll里面。如果有事件准备好了,那么就去处理;如果事件返回的是EAGAIN,那么继续将其放入epoll里面。从而,只要有事件准备好了,我们就去处理她,只有当所有时间都没有准备好时,才在epoll里面等着。这样,我们就可以并发处理大量的并发了,当然,这里的并发请求,是指未处理完的请求,线程只有一个,所以同时能处理的请求当然只有一个了,只是在请求间进行不断地切换而已,切换也是因为异步事件未准备好,而主动让出的。

这里的切换是没有任何代价,你可以理解为循环处理多个准备好的事件

题外问题

Nginx与Apache对于高并发处理上的区别

对于Apache,每个请求都会独占一个工作线程,当并发数到达几千时,就同时有几千的线程在处理请求了。这对于操作系统来说,占用的内存非常大,线程的上下文切换带来的cpu开销也很大,性能就难以上去,同时这些开销是完全没有意义的。

对于Nginx来讲,一个进程只有一个主线程,通过异步非阻塞的事件处理机制,实现了循环处理多个准备好的事件,从而实现轻量级和高并发。

Nginx比较Apache:事件驱动适合于IO密集型服务,多进程或线程适合于CPU密集型服务

1. Nginx更主要是作为反向代理,而非Web服务器使用。其网络模式是事件驱动(select、poll、epoll)。

2. 事件驱动的本质还是IO事件,应用程序在多个IO句柄间快速切换,实现所谓的异步IO。

3. 事件驱动服务器,最适合做的就是这种IO密集型工作,如反向代理,它在客户端与WEB服务器之间起一个数据中转作用,纯粹是IO操作,自身并不涉及到复杂计算。

4. 反向代理用事件驱动来做,显然更好,一个工作进程就可以run了,没有进程、线程管理的开销,CPU、内存消耗都小。

5. 当然,Nginx也可以是多进程 + 事件驱动的模式,几个进程跑libevent,不需要Apache那样动辄数百的进程数。

6. Nginx处理静态文件效果也很好,那是因为静态文件本身也是磁盘IO操作,处理过程一样。至于说多少万的并发连接,这个毫无意义。我随手写个网络程序都能处理几万7)的并发,但如果大部分客户端阻塞在那里,就没什么价值。

再看看Apache或者Resin这类应用服务器,之所以称他们为应用服务器,是因为他们真的要跑具体的业务应用,如科学计算、图形图像、数据库读写等。它们很可能是CPU密集型的服务,事件驱动并不合适。

1、例如一个计算耗时2秒,那么这2秒就是完全阻塞的,什么event都没用。想想 MySQL 如果改成事件驱动会怎么样,一个大型的join或sort就会阻塞住所有客户端。

2、这个时候多进程或线程就体现出优势,每个进程各干各的事,互不阻塞和干扰。当然,现代CPU越来越快,单个计算阻塞的时间可能很小,但只要有阻塞,事件编程就毫无优势。所以进程、线程这类技术,并不会消失,而是与事件机制相辅相成,长期存在。

总结之,事件驱动适合于IO密集型服务,多进程或线程适合于CPU密集型服务,它们各有各的优势,并不存在谁取代谁的倾向。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

High Performance Python

High Performance Python

Andrew Lewis / O'Reilly Media, Inc. / 2010-09-15 / USD 34.99

Chapter 1. Introduction Section 1.1. The High Performance Buzz-word Chapter 2. The Theory of Computation Section 2.1. Introduction Section 2.2. Problems Section 2.3. Models of Computati......一起来看看 《High Performance Python》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具