歡迎您光臨本站 註冊首頁

HTTP Header about on LoadBalance and Reverse Proxy environment

←手機掃碼閱讀     火星人 @ 2014-03-05 , reply:0

HTTP Header about on LoadBalance and Reverse Proxy environment

HTTP Header about on LoadBalance and Reverse Proxy environment
http://atman.memoab.com/articles/92


Summary

在負載均衡環境中有關HTTP Header的注意事項和在反向代理中的相關項.

Matter

用戶體驗在用戶輸入你的網址和按下回車的剎那即顯效果,速度是不可或缺的因素之一. 本文中不會涉及到網路帶寬伺服器架構或是css和javascripts的合併或分割. 只對工作中因負載均衡環境下影響和制約到包括網站頁面本地緩存和過期時間的闡述, 我們知道多個HTTP請求和內容壓縮將造成伺服器CPU的上揚和進程/線程的消耗,但原則上只讓用戶與伺服器群體傳輸盡量少的數據流,只傳輸更新的內容,且讓靜態數據貯存在用戶本地.

在傳輸資料前,TCP做的SYN/ACK建立連接需要消耗大半的時間,


http://atman.memoab.com/wp-content/uploads/2007/04/http1.jpg

所以我們可在後半用併發連接和持續連接在提速,表現在Apache 的配置方式可在httpd.conf中找到答案:
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves

# worker MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves

# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to 「Off」 to deactivate.
#
KeepAlive On|Off

多道處理模塊(MPM)中的預先派生進程比worker的線程與進程混合模式要穩定,但接受的請求海量大. 可在安裝Apache Web使用configure腳本時用–with-mpm=worker來選擇worker或者默認使用Prefork的預先派生進程模式.

一個Worker MPM的樣例:

http://atman.memoab.com/wp-content/uploads/2007/04/worker.PNG
#后一個為改善後的worker.c 的樣式

持續連接在HTTP/1.0和HTTP 1.1中參數實現不同,而在RFC2616中建議一個連接對某伺服器或反向代理最多兩個持續連接,故避免在用戶等待下載html時而Load 不出圖片的方式是將圖片交由另外的圖片伺服器來完成.

壓縮帶給數據傳輸的幫助是巨大的,在舊的Apache版本中多使用mod_gzip,現今在 Apache中已有mod_deflate代替. 瀏覽下概述:
概述

mod_deflate模塊提供了DEFLATE輸出過濾器,允許伺服器在將輸出內容發送到客戶端以前進行壓縮,以節約帶寬。

大半用戶使用的瀏覽器(IE,Firefox) 在使用HTTP Watch時你可查看到瀏覽器能接受的內容編碼:

Accept-Encoding: gzip,deflate

我們的一個結果是讓數據傳輸量少了3/4, 呵呵. 值得讚歎.

在你的配置文件中請注意提防那些「自以為是」的瀏覽器, 它們 不能很好的理解壓縮數據.


# 插入過濾器
SetOutputFilter DEFLATE

# Netscape 4.x 有一些問題…
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 有更多的問題
BrowserMatch ^Mozilla/4\.0 no-gzip

# MSIE 會偽裝成 Netscape ,但是事實上它沒有問題
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# 不壓縮圖片
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary

# 確保代理不會發送錯誤的內容
Header append Vary User-Agent env=!dont-vary

但在使用如Squid等反向代理中時注意附加Vary header對代理伺服器的影響

mod_deflate模塊發送一個」Vary: Accept-Encoding「HTTP應答頭以提醒代理伺服器:只對發送了正確」Accept-Encoding「頭的客戶端發送緩存的應答。這樣可以防止不能正確處理壓縮內容的瀏覽器接受到經過壓縮的內容。

如果你按照某些特殊的條件拒絕了某些客戶端的訪問(比如User-Agent頭),你必須手動配置一個額外的Vary頭提醒代理伺服器做額外的限制。比如,在一個典型的配置中的某處,如果額外的DEFLATE過濾器是否生效取決於User-Agent頭,你應當在此處添加:
Header append Vary User-Agent

如果依照除請求頭以外的其他條件決定是否使用壓縮(例如:HTTP版本),你必須設置Vary頭的值為」*「來完全阻止代理伺服器的緩存。
示例

Header set Vary *

在Squid 2.6中對經過壓縮的數據能Cache, 來提高 緩存命中率.
# TAG: cache_vary
# Set to off to disable caching of Vary:in objects.
#
#Default:
# cache_vary on

即當你的前端代理伺服器實行加速WEB行為需要確認Cache_vary為開狀態.

我們需要作些改變來合理使用Apache Modules, 對於頻繁變動的頁面內容我們可以在程序設置header來不緩存. Cal Henderson充分利用了Http 1.1規範的Last-Modified和ETag 來Cache內容.
3.11 Entity Tags

Entity tags are used for comparing two or more entities from the same requested resource. HTTP/1.1 uses entity tags in the ETag (section 14.19), If-Match (section 14.24), If-None-Match (section 14.26), and If-Range (section 14.27) header fields. The definition of how they are used and compared as cache validators is in section 13.3.3. An entity tag consists of an opaque quoted string, possibly prefixed by a weakness indicator.

entity-tag = [ weak ] opaque-tag
weak       = "W/"
opaque-tag = quoted-string

A 「strong entity tag」 MAY be shared by two entities of a resource only if they are equivalent by octet equality.

A 「weak entity tag,」 indicated by the 「W/」 prefix, MAY be shared by two entities of a resource only if the entities are equivalent and could be substituted for each other with no significant change in semantics. A weak entity tag can only be used for weak comparison.

An entity tag MUST be unique across all versions of all entities associated with a particular resource. A given entity tag value MAY be used for entities obtained by requests on different URIs. The use of the same entity tag value in conjunction with entities obtained by requests on different URIs does not imply the equivalence of those entities.

簡單的說ETag Header是文件修改時間、文件大小和inode號生成的校驗和(checksum),那在多台伺服器的負載均衡環境下會因部署內容的時間差異造成ETag的不同,故雖然請求同一個數據但會因不同機器的ETag而影響了響應. 具體表現為用戶在第一次請求某一內容時下載而再次時瀏覽器會發現ETag不同而再次請求下載. [使用HTTP Watch查看,再次刷新時查看是否響應碼為:304]

那可有對策? 嘿嘿, 試用下萬能的Apache 核心指令FileEtag吧 .
top
FileETag 指令
說明         用以創建ETag應答頭的文件的屬性
語法         FileETag component …
默認值         FileETag INode MTime Size
作用域         server config, virtual host, directory, .htaccess
覆蓋項         FileInfo
狀態         核心(C)
模塊         core

FileETag指令配置了當文檔是基於一個文件時用以創建ETag(實體標籤)應答頭的文件的屬性(ETag的值用於進行緩衝管理以節約網路帶寬)。在Apache1.3.22及以前,ETag的值總是由文件的inode(索引節點)、大小、最後修改時間決定。FileETag指令可以讓您選擇(如果您想進行選擇)這其中哪些要素將被使用。主要關鍵字如下:

INode
    文件的索引節點(inode)數
MTime
    文件的最後修改日期及時間
Size
    文件的位元組數
All
    所有存在的域,等價於:
    FileETag INode MTime Size
None
    如果一個文檔是基於文件的,則不在應答中包含任何ETag頭

可以在INode, MTime, Size前加上」+「或」-「以改變由上層繼承下來的默認值。任何沒有上述前綴的關鍵字將立刻完全取消繼承下來的設置。

如果一個目錄的配置包含了」FileETag INode MTime Size「而其一個子目錄包含了」FileETag -INode「那麼這個子目錄的設置(並會被其下任何沒有進行覆蓋的子目錄繼承)將等價於」FileETag MTime Size「。

OK, 因我們的不同伺服器上的文件大小是一樣的, 我們可以讓創建的ETag基於數據大小.

FileETag MTime Size

這裡不得不提的另一個機制Last-Modified.

        * 頁面必須包含Last-Modified: 標記
          一般純靜態頁面本身都會有Last-Modified信息,動態頁面需要通過函數強制加上,比如在PHP中:
          // always modified now
          header(」Last-Modified: 」 . gmdate(」D, d M Y H:i:s」) . 」 GMT」);

            我們用Apache mod_expires對text和image類型文件加有效期,控制應答時的Expires頭內容和Cache-Control頭的max-age指令. 這樣客戶端瀏覽器從緩存請求數據而不是伺服器端. 當緩存中數據失效或過期,才決定從伺服器更新數據.

            示例:

            # 啟用有效期控制
            ExpiresActive On
            # GIF有效期為1個月
            ExpiresByType image/gif A2592000
            # HTML文檔的有效期是最後修改時刻后的一星期
            ExpiresByType text/html M604800

            動態數據的過期定義如PHP可在程序行中加入:

            //一個月過期

            header("Expires: ".gmdate("D, d M Y H:i:s", time()+2592000)." GMT");
            header("Cache-Control: max-age=2592000");

Resource
Squid Vary header support
Squid ETag header support

Cal Henderson 《Serving JavaScript Fast》

Jennifer Vesperman 《Cache-Friendly Web Pages》
HTTP Header 文檔

[ 本帖最後由 銘文龍羽 於 2007-4-10 14:51 編輯 ]

[火星人 ] HTTP Header about on LoadBalance and Reverse Proxy environment已經有143次圍觀

http://coctec.com/docs/service/show-post-39900.html