Apache-2.2

使用 Varnish 和大量 ram 優化繁忙的網站

  • October 29, 2012

$$ Updated to be much more consise! $$ 我對優化網路伺服器以適應大量流量的世界很陌生,但這就是我現在要做的事情。

週一,我們的網路伺服器被“劃點”——我們的流量激增(一個小時左右有 85,000 名訪問者),即使我們執行 Varnish 和 nginx(它們的工作正常),Apache 方面的事情確實在那裡掙扎是根據某些請求生成的一些動態內容。

伺服器目前有 8GB 的​​ RAM,它很快就會升級到 32GB,所以我真的需要 32GB 系統的配置幫助。目前執行64位centos。

我已經研究了清漆和 nginx 設置,它們很好 - 明智的設置(靜態內容直接由 nginx 拋出,許多動態內容由清漆拋出,如果它不在清漆中,則請求將傳遞給 apache。)

等到 Apache .. 我們正在使用 MPM prefork 模組,每個 apache 程序似乎都消耗了很多記憶體:

前三名:

S    48 20961  2965  0  75   0 187128 128307 ?    ?        00:05:25 httpd
S    48 20959  2965  0  75   0 249788 143435 ?    ?        00:05:55 httpd
S    48 18581  2965  0  75   0 314564 157747 ?    ?        00:06:40 httpd

底部3:

S     0  2965     1  0  78   0 15132 89017 stext  ?        00:00:00 httpd
S    48 20947  2965  0  75   0 38492 93001 ?      ?        00:00:00 httpd
S    48 20945  2965  0  75   0 43300 93897 ?      ?        00:00:01 httpd

我不完全確定,但我認為一個程序 = 一個客戶端 = 一個連接到一個人的瀏覽器。我想我的第一個問題是有人可以確認嗎?是的,我們在同一台伺服器上執行 php 和 zend 框架,MySQL 作為數據庫後端。

目前配置(伺服器目前有 8GB 記憶體):

MaxKeepAliveRequests 100

KeepAliveTimeout 2

<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      200
MaxClients       200
MaxRequestsPerChild  500
</IfModule>

我的想法是目前 Apache 理論上可以嘗試使用這種配置在最壞的情況下使用大約 63GB 的記憶體。例如 315MB 程序 * 200 maxclients = 大量記憶體。我不完全確定它是這樣工作的,但如果有人可以確認它也會有所幫助!

我想做的是獲得一些關於我應該注意哪些事情的建議——我們希望伺服器能夠隨時處理另一波請求,並利用我們獲得的所有新 RAM . 如果我自己無法弄清楚,我將在另一個問題中開始優化 MySQL,但這裡是 conf,以防萬一有所作為: http: //pastebin.com/GbJU7AxY

大大加油!約翰。

每天 85,000 的訪客人數到底是多少?唯一身份訪問者、HTTP 總點擊量,還有其他什麼?

只要可以從記憶體中提供請求,Varnish 應該能夠每秒處理數千次點擊,只需很少的 CPU 和記憶體。尤其是在 Slashdotted 時,因為大多數人會尋找完全相同的內容。不過確實需要微調。預設情況下它非常保守,因為它對通過的內容知之甚少。它根據它看到的標頭和一個簡單的規則集做出決定。例如,預設情況下,Varnish 記憶體對象 2 分鐘,但前提是請求中不存在 cookie,並且對象的 TTL 大於 0,等等。檢查預設 VCL(特別是vcl_recvvcl_fetch)以確定預設邏輯,並確保你理解它。

因此,在您的域上設置的單個 Google Analytics cookie 會導致所有請求傳遞到後端,即使 GA cookie 不是由您的後端伺服器處理,而是由 Google 的 javascript 處理。WordPress 應用程序設置了各種類型的 cookie,其中大部分僅適用於動態內容,瀏覽器在每次請求時都會返回這些內容。如果您的頁麵包含 49 個靜態資源和 1 個動態頁面,這意味著這些靜態資源都不會被記憶體,因為請求包含您不關心的 cookie。只有動態請求上的 cookie 才能通過。像這樣的錯誤基本上會禁用 Varnish。此外,您的程式碼返回的各種記憶體控制(和相關)HTTP 標頭也很重要。如果您的應用程序聲稱 Varnish 從後端檢索的對像已經過期,例如過去帶有 Expires 標頭,

換句話說,您需要調整您的應用程序以發出正確的標頭,以便允許客戶端(Varnish 和瀏覽器)記憶體返回的內容。任何你不能在你的應用程序中更正的東西,你都可以在 Varnish 的 VCL 中覆蓋。

例如,這是我的程式碼,用於刪除各種客戶端跟踪 cookie,使其無法到達伺服器。這屬於vcl_recv

# Remove tracking cookies. The server doesn't need to see them.
if (req.http.Cookie) {
   # Remove has_js and Google Analytics __* cookies.
   set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js|sifrFetch)=[^;]*", "");
   # Remove a ";" prefix, if present.
   set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
   # Remove cookie header if empty
   if (req.http.Cookie == "") {
       remove req.http.Cookie;
   }
}

同樣,我將傳入的 cookie 刪除到某些路徑,以使這些請求可記憶體:

if  ( req.url ~ "^/cms/cms_files/(?:css|img|js)/" ||  #CMS1
     req.url ~ "^/site_files/(?:css|img|imgc|js|swf|uploads|xml/.+\.xml$)" ||  #CMS1
     req.url ~ "^/(?:images|stylesheets|javascripts|swf|site_files/js_libs|site/image|favicon\.ico$|robots\.txt$)" ||  #CMS2
     ( req.http.host ~ "(?:shop\.example\.com|www\.example\.nl)"  &&  #Magento
       req.url ~  "^/(?:404|js|media|skin|favicon\.ico$)" ) || #Magento
) {
   unset req.http.cookie;
}

我在 vcl_fetch 中使用了一個類似的節,unset beresp.http.cookie;而是防止後端在我不想要的路徑上設置任何 cookie。

您可以添加一些調試標頭,為您提供有關 varnish 如何處理請求的資訊。使用 Firebug 查看這些內容,您會更加了解您的應用。另一個很好的資訊來源是Varnish Book。例如,參見:https ://www.varnish-software.com/static/book/VCL_Basics.html

我們的大部分動態內容都記憶體了 60 秒,足以抵禦踩踏事件。如果您需要一些單獨的內容,但頁面上的大部分內容都是靜態的,請查看 Varnish 的ESI(edge-side-includes),它允許您為頁面的不同部分指定不同的記憶體 TTL。

現在您已將後端請求減少到最低限度,請優化這些請求。分析您的應用程序,查找並解決問題。

你是對的: MaxClients x (maximum physical memory per Apache process) = (total memory Apache can use)

那是物理記憶體,而不是您提到的虛擬記憶體。在頂部,res列顯示了每個程序使用的物理記憶體。每個 Apache 程序都會增長到您的站點執行的最大腳本。將 MaxClients 限制為您的伺服器可以處理的數量。接受您沒有資源的請求是沒有意義的。一旦你開始交換,你就輸了。增加 Apache 預分叉的程序(伺服器)的數量,因為分叉是一項繁重的操作,您希望在它已經很忙時執行此操作。ServerLimit 行是多餘的。禁用 KeepAlive 或將其設置為 1-2 秒。

如果您提供許多靜態資產,請考慮從 mod_php 切換到 PHP-FPM。這使您的 Apache 程序保持輕量級。

引用自:https://serverfault.com/questions/431819