Nginx---惊群

首先,简单了解一下nginx。大家知道Nginx(engine x)是一个轻量级高性能的HTTP和反向代理服务器,特点是占用内存少,并发能力强。而且,在实际生产环境中,nginx的并发能力确实在同类的网页服务器中变现较好,像中国的百度,京东,新浪,网易,淘宝等用的都是nginx作为自己的网站。
然后,nginx的应用场景,主要有三个,静态中资源服务,反向代理服务,API服务。

问题一:Nginx为什么高效?
我总结了三点,网络,内存,进程的管理调度方式。
1 网络,nginx采用的epoll网络模型,异步非阻塞。多进程处理请求。master进程先创建好需要的listen的soclet后,然后在fork出多个worker进程,这样每个worker进程都可以去accept。当一个client连接到来时,所有sccept进程都会受到通知,但只有一个进程可以accept成功,其他的则会accept失败。这里会有一个惊群的问题,后面说。
2 内存,这里nginx会用到内存池,nginx的内存池分为两个部分,一种是小块内存,一种是大块内存,小块内存指的是last所指向的位置,大块内存则需要重新开辟,有large指向。在需要开辟新的内存时,当传入内存大小大于max值时,在large中查找,反之,在last所指内存中查找,当小块内存不够时,会开辟新的内存块,有next指针指向。当需要销毁内存时,大块内存直接用ngx_free释放,小块则不作处理,只有在销毁整个内存池是才会处理。每个连接请求会匹配一个内存池,而且每个内存池只对单个连接有效,连接会向内存池请求内存资源,用完再返回给内存池
3 进程的管理调度方式
在这里插入图片描述
master进程管理woeker进程,主要功能是接受来自外界的信号;向各worker进程发送信息;监控worker进程的运行状态;当worker进程退出后,会自动重新启动worker进程。
woker进程主要用来处理网络事件,各个worker进程之间是对等且独立的,它们同等竞争来自客户端的请求,一个进程只能在一个worker进程中处理,worker进程个数一般设置为服务器CPU核心数。

问题二:多进程的epoll惊群
这里说一下惊群的概念,惊群是指,当一个连接请求进来,多个进程多来等处理请求信息,就会消耗服务器资源。当一个client连接到来时,所有sccept进程都会受到通知,但只有一个进程可以accept成功,其他的则会accept失败。
master --> listen(sockfd,backlog)
worker --> 继承master的fd(五元组信息,sip,sport,dip,dport,proto)
所有的worker进程的fd都可以捕获的客户端的连接

问题三:集群是fd惊群还是epoll惊群?
当客户请求进来时,worker进程会将fd信息推送到epoll进行管理。客户端连接的时候,多个进程中的epoll_wait会返回,源码如下:

 while(1){
    
    
   epoll_wait()
 }

所以说,nginx惊群是epoll环节的惊群

问题四:如何解决nginx的惊群?
加锁。我们只需要确定在某一时刻只有一个进程的fd被加入到epoll里,可以用多进程加共享锁的方法来做。epoll循环的时候,在fd加入epoll之前,判断共享锁时候被使用。这里又会有一个问题,fd使用水平触发还是边缘触发的方式(LT/ET)? listen的fd的时候采用水平触发,如果用边缘触发的话会漏掉一些fd。

补充:
epoll的两种工作方式:1.水平触发(LT)2.边缘触发(ET)
LT模式:若就绪的事件一次没有处理完要做的事件,就会一直去处理。即就会将没有处理完的事件继续放回到就绪队列之中(即那个内核中的链表),一直进行处理。
ET模式:就绪的事件只能处理一次,若没有处理完会在下次的其它事件就绪时再进行处理。而若以后再也没有就绪的事件,那么剩余的那部分数据也会随之而丢失。
由此可见:ET模式的效率比LT模式的效率要高很多。只是如果使用ET模式,就要保证每次进行数据处理时,要将其处理完,不能造成数据丢失,这样对编写代码的人要求就比较高。
注意:ET模式只支持非阻塞的读写:为了保证数据的完整性。

猜你喜欢

转载自blog.csdn.net/qq_51574197/article/details/113733785