异步非阻塞
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多路复用的方式。
这种机制处理起来就很高效,多路复用就是在一个线程里,交替并发的完成。复用的就是一个线程。
昨晚(2020-07-09)八点左右,生产运行的APP大面积上报请求超时,无法获取数据,显示网络连接错误等。经过简单测试,发现并不是如用户所说的APP完全无法与服务器通讯,偶尔请求又能正常返回。
登录后台后,直接查看系统连接数,发现并发数较高,等待处理的请求也很多,造成了网络阻塞;
分析可能是有类似爬虫的程序在对我们的系统进行扫描。由于系统并没有特别高并发的需求(小众应用),所以没有所谓的高并发架构,但应用服务端采用的是Nginx,故决定限制一下限制客户端的访问频次和访问次数。
Nginx可以通过 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 配置来限制ip在同一时间段的访问次数:
可以根据设定的条件来限定客户端(单一ip)的 并发访问 ,使用limit_conn_zone和limit_conn指令。
可以根据设定的条件来限定客户端(单一ip)的 访问频率 ,使用limit_req_zone和limit_req指令。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)