Nginx实现高并发及原理

Nginx实现高并发及原理,第1张

1.nginx高并发原理( 多进程(单线程)+epoll 实现高并发)

1.Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程

2.每个子进程只有一个线程,采用的 IO多路复用模型epoll,实现高并发

1.epoll() 中内核则维护一个链表,epoll_wait 方法可以获取到链表长度,不为0就知道文件描述符准备好了

2.在内核实现中 epoll 是根据每个 sockfd 上面的与设备驱动程序建立起来的回调函数实现的

3.某个 sockfd 上的事件发生时,与它对应的回调函数就会被调用,来把这个 sockfd 加入链表,其他处于“空闲的”状态的则不会

4.epoll上面链表中获取文件描述,这里使用内存映射(mmap)技术, 避免了复制大量文件描述符带来的开销

内存映射(mmap):内存映射文件,是由一个文件到一块内存的映射,将不必再对文件执行I/O *** 作

(1)nginx相对于apache的优点

1.轻量级,同样起web 服务,比apache 占用更少的内存及资源

2.抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能

3.高度模块化的设计,编写模块相对简单,社区活跃,各种高性能模块出品迅速啊

(2)apache相对于nginx的优点

1.apache 更为成熟,少 bug ,稳定性好

2.rewrite ,比nginx 的rewrite 强大

3.模块超多,基本想到的都可以找到

Nginx 采用的是多进程(单线程) &多路IO复用模型。使用了 I/O 多路复用技术的 Nginx,就成了”并发事件驱动“的服务器。

异步非阻塞

1、Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程。

2、接收来自外界的信号,向各worker进程发送信号,每个进程都有可能来处理这个连接。

3、 master 进程能监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动启动新的 worker 进程。

worker 进程数,一般会设置成机器 cpu 核数。因为更多的worker 数,只会导致进程相互竞争 cpu,从而带来不必要的上下文切换

惊群现象

主进程(master 进程)首先通过 socket() 来创建一个 sock 文件描述符用来监听,然后fork生成子进程(workers 进程),子进程将继承父进程的 sockfd(socket 文件描述符),之后子进程 accept() 后将创建已连接描述符(connected descriptor)),然后通过已连接描述符来与客户端通信。

那么,由于所有子进程都继承了父进程的 sockfd,那么当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。大量的进程被激活又挂起,只有一个进程可以accept() 到这个连接,这当然会消耗系统资源。

Nginx对惊群现象的处理

Nginx 提供了一个 accept_mutex 这个东西,这是一个加在accept上的一把共享锁。即每个 worker 进程在执行 accept 之前都需要先获取锁,获取不到就放弃执行 accept()。有了这把锁之后,同一时刻,就只会有一个进程去 accpet(),这样就不会有惊群问题了。accept_mutex 是一个可控选项,我们可以显示地关掉,默认是打开的。

主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

worker进程工作流程

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

什么是IO多路复用呢?

对于 *** 作系统而言,IO多路复用就是要完成 *** 作系统IO的请求。对于IO文件的请求,当一个IO流要进行文件处理的时候,要获取一组文件的描述符,当文件描述符还没有就绪时,那么它就在等待,直到描述符一旦就绪,马上上报系统通知的机制,告诉应用程序我准备就绪,你可以来 *** 作了。这就是IO多路复用的方式。

这种机制处理起来就很高效,多路复用就是在一个线程里,交替并发的完成。复用的就是一个线程。

对于一些服务器流量异常、负载过大,甚至是大流量的恶意攻击访问等,进行并发数的限制(共享内存和并发限制需结合系统定制)

limit_conn_zone 设置共享内存区域参数

limit_conn 设置共享内存区域和给定键值的最大允许连接数

limit_conn_log_level 日志可以调整级别,默认 error

limit_conn_status 返回状态码响应拒绝请求,默认 503

示例

限制来自单个IP地址的请求处理频率,每秒固定处理请求数,推迟过多请求。以此来防止应用层的 DDOS 攻击(共享内存和请求频率需结合系统定制)

limit_req_zone 设置共享内存区域参数

limit_req 设置共享内存区域、突发大小、延时

limit_req_log_level 日志可以调整级别,默认 error

limit_req_status 返回状态码响应拒绝请求,默认 503

示例


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/6370213.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-21
下一篇 2023-03-21

发表评论

登录后才能评论

评论列表(0条)

保存