前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nginx惊群问题

nginx惊群问题

作者头像
用户1215536
发布2019-07-23 14:15:47
9140
发布2019-07-23 14:15:47
举报

什么是nginx惊群问题?

了解惊群问题首先要了解下nginx进程部署架构:nginx进程主要是一个主进程(master)和多个工作进程(worker)。master进程并不处理网络请求,主要负责初始化和调度工作进程,如加载配置、启动工作进程 ,升级等,worker进程用来处理网络请求,并且一个连接的多个阶段处理都在同一个worker中进行。既然是多个worker同时等待同一个socket事件,当这个事件发生时,所有worker同时唤醒,但最终只能有一个进程能建立成功,其他进程都会失败,造成了资源的浪费。

nginx解决惊群到方法

简单总结就是同一时刻保证只有一个worker在监听。那么这个是如何做到呢?其实也很简单,增加一个ngx_use_accept_mutex锁,各个worker在监听socket事要先拿到这个锁,而同一时刻保证只有一个worker拿到。

很多操作系统已经在epoll阶段解决了这个问题,为什么nginx还要做?

1、跨平台,有些不支持

2、实现各个worker负载均衡

为了使各个worker上的连接达到负载均衡,定义了全局变量ngx_accept_disabled,其为值为连接总数的1/8-剩余连接数,即初始化时为负值,拿ngx_use_accept_mutex锁的时候,会判断该值是否为正,如果为正就建立连接而是将值减1,也就是说在worker上连接数目达到规格的7/8时才开始负载均衡。

ngx_accept_disabled = ngx_cycle->connection_n / 8
                              - ngx_cycle->free_connection_n;
void
ngx_process_events_and_timers(ngx_cycle_t *cycle)
{
    。。。
    //ngx_use_accept_mutex表示是否需要通过对accept加锁来解决惊群问题。当nginx worker进程数>1时且配置文件中打开accept_mutex时,这个标志置为1
    if (ngx_use_accept_mutex) {
            //ngx_accept_disabled表示此时满负荷,没必要再处理新连接了,我们在nginx.conf曾经配置了每一个nginx worker进程能够处理的最大连接数,当达到最大数的7/8时,ngx_accept_disabled为正,说明本nginx worker进程非常繁忙,将不再去处理新连接,这也是个简单的负载均衡
        if (ngx_accept_disabled > 0) {
            ngx_accept_disabled--;
 
        } else {
                //获得accept锁,多个worker仅有一个可以得到这把锁。获得锁不是阻塞过程,都是立刻返回,获取成功的话ngx_accept_mutex_held被置为1。拿到锁,意味着监听句柄被放到本进程的epoll中了,如果没有拿到锁,则监听句柄会被从epoll中取出。
            if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
                return;
            }
 
               //拿到锁的话,置flag为NGX_POST_EVENTS,这意味着ngx_process_events函数中,任何事件都将延后处理,会把accept事件都放到ngx_posted_accept_events链表中,epollin|epollout事件都放到ngx_posted_events链表中
            if (ngx_accept_mutex_held) {
                flags |= NGX_POST_EVENTS;
 
            } else {
                    //拿不到锁,也就不会处理监听的句柄,这个timer实际是传给epoll_wait的超时时间,修改为最大ngx_accept_mutex_delay意味着epoll_wait更短的超时返回,以免新连接长时间没有得到处理
                if (timer == NGX_TIMER_INFINITE
                    || timer > ngx_accept_mutex_delay)
                {
                    timer = ngx_accept_mutex_delay;
                }
            }
        }
    }

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档