惊群现象:

惊群现象是指由多个worker进程监听同一个Socket事件时,当事件发生时,相关的所有进程被惊醒,但最终只能有一个进程对该事件进行处理,其他进程会重新休眠,从而导致系统资源的浪费和系统性能的下降。惊群包含accept惊群和epoll惊群。

惊群的本质:睡眠和唤醒问题,属于典型的观察者模式,进程通过等待事件,挂载关注的对象的等待队列上,但对象有资源时就唤醒等待队列上的进程,至于是否产生惊群关键在于wake_up_common 是否无差别地唤醒等待队列上的进程


Epoll惊群的处理:


(1)Accpet_mutex

通过开启accept_mutex锁,每个Worker进程都会去抢自旋锁,只有抢到自旋锁的才能将Socket加入到Epoll中,Accept新的请求,然后释放锁

(2)EPOLLEXCLUSIVE

linux4.5以后内核版本中,增加了EPOLLEXCLUSIVE,该选项可以通过EPOLL_CTL_ADD对要监控的fd添加EPOLLEXCLUSIVE标记,这样fd的epoll entry就带上了EPOLLEXCLUSIVE标记。当有事件到来时,唤醒第一个带有此标记的epoll entry就退出唤醒过程。通过增加这样一个标记,多线程共用同一个epoll的惊群现象得到了解决。

(3)SO_REUSEPORT

SO_REUSEPORT 是惊群最好的解决方法,Nginx 在 1.9.1 中加入了这个选项,每个 worker 进程都有自己的 socket,这些 socket 都 bind 同一个端口。当新请求到来时,内核根据四元组信息进行负载均衡,非常高效


Accpet惊群的处理


当多个进程/线程调用accept监听同一个socket上时,一个新连接的到来就会导致所有阻塞在该socket上的进程/线程都被唤醒,但是最后只有一个进程/线程可以accept成功,其余的又会重新休眠,这样就产生了惊群现象。通过维护一个等待队列(队列的元素为进程),使用WQ_FLAG_EXCLUSIVE标志位(互斥标志位),非exclusive元素会加在等待队列的前面,而exclusive元素会加在等待队列的末尾,当有新连接到来时,会遍历等待队列,并且只唤醒第一个exclusive进程(非互斥的进程由于排在队列前面也会被唤醒)就退出遍历,阻塞在accept上的进程都是互斥的(也就是WQ_FLAG_EXCLUSIVE标志位会被置位),因此现在的linux内核调用accept时,多个进程/线程只有一个会被唤醒并建立新连接

Nginx惊群现象的两种解决办法的更多相关文章

  1. [Android]Eclipse 安装 ADT[Android Development Tooling] 失败的两种解决办法

    原因 最近想在新装的 Win7 里搭建一下 Android 的开发环境,虽然现在有 Android Studio 了,不过还是习惯 Eclipse 一点.众所周知的原因,Eclipse 直接安装 AD ...

  2. win10应用程序添加到开机启动项的两种解决办法

    原文 win10应用程序添加到开机启动项的两种解决办法 在windows10系统中,如果想让应用程序在开机之后自动运行起来,可以怎么做呢? 方法一: 1.首先创建应用程序的快捷方式 找到自己想加入开机 ...

  3. Linux下面使用命令如何运行.sh文件的两种解决办法

    Linux下面用命令如何运行.sh文件的方法,有两种方法: 一.直接./加上文件名.sh,如运行hello.sh为./hello.sh[hello.sh必须有x权限] 二.直接sh 加上文件名.sh, ...

  4. Eclipse 配置spring boot pom.xml第1行报错的两种解决办法

    现象 通过spring boot项目导入eclipse后,pom.xml文件的第一行总是报错.这里使用的spring版本是2.1.5,2.1.4以前的版本等其他版本的spring没有这个问题. 解决办 ...

  5. Slave_SQL_Running:No的两种解决办法

    进入slave服务器,运行: mysql> show slave status\G ....... Relay_Log_File: localhost-relay-bin. Relay_Log_ ...

  6. MySQL同步故障:" Slave_SQL_Running:No" 两种解决办法

    进入slave服务器,运行: mysql> show slave status\G Relay_Log_File: localhost-relay-bin.000535 Relay_Log_Po ...

  7. bug_ _ java.lang.IllegalArgumentException: pointerIndex out of range 问题的两种解决办法

    ========== 4     如何解决java.lang.IllegalArgumentException: pointerIndex out of range? 今天遇到一个bug:java.l ...

  8. Oracle中除数为0的两种解决办法(decode与nullif)

    Oracle中Decode函数,语句DECODE(tag,''ZCGS'',0,1)=decode(''@corp-No@'',''6010'',1,0) decode(字段或字段的运算,值1,值2, ...

  9. python学习笔记30(全局变量的两种解决办法)

    先看程序: >>> count = 0 >>> def fuc(count): print count count +=1 >>> for i i ...

  10. 关于新版SDK报错You need to use a Theme.AppCompat theme的两种解决办法

    android的一个小问题: Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme ( ...

随机推荐

  1. Linux下C语言实现贪吃蛇

    简单记录下贪吃蛇小游戏. 以下是源码: 1 #include <curses.h> 2 #include <stdlib.h> 3 #include <pthread.h ...

  2. 离线安装mysql报错解决方法:/usr/sbin/mysqld: error while loading shared libraries: libaio.so.1: cannot open sha --九五小庞

    Linux:centos 7.6 64位 mysql:5.6使用离线方式安装:rpm -ivh --nodeps mysql* ,执行 systemctl start mysqld.service发现 ...

  3. Redis缓存同步1-策略介绍

    缓存数据同步策略示意图 在大多数情况下,我们通过浏览器查询到的数据都是缓存数据,如果缓存数据与数据库的数据存在较大差异的话,可能会产生比较严重的后果的.所以,我们应该也必须保证数据库数据.缓存数据的一 ...

  4. REST API 设计最佳实践:为什么不要在URI中使用动词?

    总的来说,HTTP协议出现以来Web服务也就存在了.但是,自从云计算出现后,才成为实现客户端与服务和数据交互的普遍方法. 作为一名开发者,我很幸运能够在工作中使用一些仍然存在的SOAP服务.但是,我主 ...

  5. vlan与单臂路由

    vlan 1,什么是vlan vlan叫做虚拟局域网 (VLAN, Virtual LAN) 虚拟局域网(VLAN)是一组逻辑上的设备和用户,这些设备和用户并不受物理位置的限制,可以根据功能.部门及应 ...

  6. python将print的打印内容保存到日志

    将python程序中的所有打印内容都输出到日志文件中,在程序执行完成后,方便查询程序运行过程是否出现异常. 1. 将打印内容输出到日志文件 1.1 代码实现: sys.stdout = open('s ...

  7. 4.2 C++ Boost 内存池管理库

    Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量.可移植.高效的C应用程序.Boost库可以作为标准C库的后备,通常被称为准标准 ...

  8. Redis专题-秒杀

    Redis专题-并发/秒杀 开局一张图,内容全靠"编". 昨天晚上在群友里看到有人在讨论库存并发的问题,看到这里我就决定写一篇关于redis秒杀的文章. 1.理论部分 我们看看一般 ...

  9. Badusb制作,远程别人电脑

    Badusb制作 插一下U盘黑一台电脑,插了我的U盘你可就是我的脑了,(▽) 理论准备 我们要用它就应该知道他的工作原理是怎么样的,方便我们去发散思维去使用它. Badusb的原理是利用HID(Hum ...

  10. 深入理解Linux内核——内存管理(1)

    提要:本系列文章主要参考MIT 6.828课程以及两本书籍<深入理解Linux内核> <深入Linux内核架构>对Linux内核内容进行总结. 内存管理的实现覆盖了多个领域: ...