nginx 是如何分配 worker 進程連接數的


客戶端連接過來后,多個空閑的進程,會競爭這個連接,很容易看到,這種競爭會導致不公平,如果某個進程得到 accept 的機會比較多,它的空閑連接很快就用完了,如果不提前做一些控制,當 accept 到一個新的 tcp 連接后,因為無法得到空閑連接,而且無法將此連接轉交給其它進程,最終會導致此 tcp 連接得不到處理,就中止掉了。很顯然,這是不公平的,有的進程有空余連接,卻沒有處理機會,有的進程因為沒有空余連接,卻人為地丟棄連接。那么,如何解決這個問題呢?首先,Nginx 的處理得先打開 accept_mutex 選項,此時,只有獲得了 accept_mutex 的進程才會去添加accept事件,也就是說,Nginx會控制進程是否添加 accept 事件。Nginx 使用一個叫 ngx_accept_disabled 的變量來控制是否去競爭 accept_mutex 鎖。在第一段代碼中,計算 ngx_accept_disabled 的值,這個值是 Nginx 單進程的所有連接總數的八分之一,減去剩下的空閑連接數量,得到的這個 ngx_accept_disabled 有一個規律,當剩余連接數小於總連接數的八分之一時,其值才大於 0,而且剩余的連接數越小,這個值越大。再看第二段代碼,當 ngx_accept_disabled 大於 0 時,不會去嘗試獲取 accept_mutex 鎖,並且將 ngx_accept_disabled 減 1,於是,每次執行到此處時,都會去減 1,直到小於 0。不去獲取 accept_mutex 鎖,就是等於讓出獲取連接的機會,很顯然可以看出,當空余連接越少時,ngx_accept_disable 越大,於是讓出的機會就越多,這樣其它進程獲取鎖的機會也就越大。不去 accept,自己的連接就控制下來了,其它進程的連接池就會得到利用,這樣,Nginx 就控制了多進程間連接的平衡了。

 

白話說就是,nginx 會設置一個 單個進程的可連接總數的 八分之一 作為切換連接的標准, 當這個標准 減去 單個進程的剩余連接數 大於0 時,即所剩的連接數已經小於 總連接數的八分之一時,會讓該進程讓出 連接機會,即在該進程連接數所剩不多時,切換連接進程。

上代碼

ngx_accept_disabled = ngx_cycle->connection_n / 8
        - ngx_cycle->free_connection_n;

    if (ngx_accept_disabled > 0) {
        ngx_accept_disabled--;

    } else {
        if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
            return;
        }

        if (ngx_accept_mutex_held) {
            flags |= NGX_POST_EVENTS;

        } else {
            if (timer == NGX_TIMER_INFINITE
                    || timer > ngx_accept_mutex_delay)
            {
                timer = ngx_accept_mutex_delay;
            }
        }
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM