概述
發起一個http請求的過程就是建立一個socket通信的過程。
我們可以模仿瀏覽器發起http請求,譬如用httpclient工具包,curl命令等方式。
curl "http://www.baidu.com" 返回頁面數據
curl -I "http://www.baidu.com" -I查看http響應頭的信息
curl -I "http://www.baidu.com" -H "Cookie=......; Accept-Charset=...." -H添加請求頭的信息
HTTP解析
http header控制着互聯網上成千上萬的用戶的數據的傳輸。最關鍵的是,它控制着用戶瀏覽器的渲染行為和服務器的執行邏輯。
firefox可用firebug查看,httpfox工具,fidder工具,chrome&ie自帶調試工具等都可以查看。
HTTP請求頭
Accept-Language: zh-cn,zh;q=0.5
Accept-Language表示瀏覽器所支持的語言類型,分別是中文和簡體中文,優先支持簡體中文。
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Accept-Charset告訴 Web 服務器,瀏覽器可以接受哪些字符編碼,分別是 GB2312、utf-8 和任意字符,優先順序是 GB2312、utf-8、*。
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept表示瀏覽器支持的 MIME 類型,分別是 text/html、application/xhtml+xml、application/xml 和 */*,優先順序是它們從左到右的排列順序。
Accept-Encoding: gzip, deflate
Accept-Encoding表示瀏覽器有能力解碼的編碼類型,壓縮編碼是 gzip 和 deflate。
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
User-Agent(用戶代理),簡稱 UA,它是一個特殊字符串頭,使得服務器能夠識別客戶端使用的操作系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等
Host: 域名
Host表示請求的服務器網址;
Connection: Keep-Alive
Connection表示客戶端與服務連接類型,Keep-Alive表示持久連接;
HTTP響應頭
Server:Apache/1.3.6
使用的服務器名稱
Content-Type:text/html;charset=GBK
用來指明接受者的實體正文的媒體類型
Content-Encoding:gzip
與請求報頭Accept-Encooding對應,告訴瀏覽器服務端采用的是什么壓縮編碼
Content-Language:zh-cn
貌似了資源所用的自然語言,與Accept-Language對應
Content-Length:10527
指明實體正文的長度
Keep-Alive:timeout=5,max=120
保持連接的時間
HTTP狀態碼
200 客戶端請求成功
302 臨時跳轉,跳轉的地址通過location指定
400 客戶端請求語法錯誤,不能被服務器識別
403 服務器收到請求,但是拒絕服務
404 請求的資源不存在
500 服務器發生不可預期的錯誤
瀏覽器緩存機制
瀏覽一個網頁時發現有異常的情況下,通常考慮的是是不是瀏覽器做了緩存,一般的做法可以通過ctrl+F5組合鍵重新請求這個頁面,重新請求的頁面肯定是最新的頁面。

Cache-Control
must-revalidation/proxy-revalidation 如果緩存失敗,請求必須發送到服務器進行重新驗證,請求頭中設置
no-cache 所有內容都不會被緩存,請求頭或者響應頭中設置
public 所有內容都將被緩存,響應頭中設置
private 內容只緩存到私有緩存中,響應頭中設置
no-store 所有內容都不會被緩存到緩存或internet臨時文件中,響應頭中設置
max-age=10 緩存內容在10秒后失效,只在http1.1中可用和last-modified一起使用時優先級較高,響應頭中設置
Pragma
no-cache 請求頭中設置,no-cache這個名字有一點誤導。設置了no-cache之后,並不是說瀏覽器就不再緩存數據,只是瀏覽器在使用緩存數據時,需要先確認一下數據是否還跟服務器保持一致。如果設置了no-cache,而ETag的實現沒有反應出資源的變化,那就會導致瀏覽器的緩存數據一直得不到更新的情況。
<META HTTP-EQUIV="Pragma" CONTENT="no-cache"> html頁面中寫入(部分瀏覽器可以支持,所有緩存代理服務器都不支持,代理不解析HTML內容本身。)
Expires

Date頭域表示消息發送的時間,時間的描述格式由rfc822定義
Web服務器告訴瀏覽器在2012-11-28 03:30:01這個時間點之前,可以使用緩存文件。發送請求的時間是2012-11-28 03:25:01,即緩存5分鍾。
Expires 是HTTP 1.0的東西,現在默認瀏覽器均默認使用HTTP 1.1,所以它的作用基本忽略。
Cache-Control策略導向圖

Last-Modified/If-Modified-Since
Last-Modified/If-Modified-Since要配合Cache-Control使用。
Last-Modified:標示這個響應資源的最后修改時間。web服務器在響應請求時,告訴瀏覽器資源的最后修改時間。
If-Modified-Since:當資源過期時(使用Cache-Control標識的max-age),發現資源具有Last-Modified聲明,則再次向web服務器請求時帶上頭 If-Modified-Since,表示請求時間。web服務器收到請求后發現有頭If-Modified-Since 則與被請求資源的最后修改時間進行比對。若最后修改時間較新,說明資源又被改動過,則響應整片資源內容(寫在響應消息包體內),HTTP 200;若最后修改時間較舊,說明資源無新修改,則響應HTTP 304 (無需包體,節省瀏覽),告知瀏覽器繼續使用所保存的cache。
Etag/If-None-Match(優先級比last-modified高,緩存過期后先判斷有沒有etag聲明再判斷有沒有last-modified聲明)
Etag/If-None-Match也要配合Cache-Control使用。
Etag:web服務器響應請求時,告訴瀏覽器當前資源在服務器的唯一標識(生成規則由服務器覺得)。Apache中,ETag的值,默認是對文件的索引節(INode),大小(Size)和最后修改時間(MTime)進行Hash后得到的。
If-None-Match:當資源過期時(使用Cache-Control標識的max-age),發現資源具有Etage聲明,則再次向web服務器請求時帶上頭If-None-Match (Etag的值)。web服務器收到請求后發現有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決定返回200或304。
PS
使用Last-Modified已經足以讓瀏覽器知道本地的緩存副本是否足夠新,為什么還需要Etag(實體標識)呢?HTTP1.1中Etag的出現主要是為了解決幾個Last-Modified比較難解決的問題:
- Last-Modified標注的最后修改只能精確到秒級,如果某些文件在1秒鍾以內,被修改多次的話,它將不能准確標注文件的修改時間
- 如果某些文件會被定期生成,當有時內容並沒有任何變化,但Last-Modified卻改變了,導致文件沒法使用緩存
- 有可能存在服務器沒有准確獲取文件修改時間,或者與代理服務器時間不一致等情形
Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的唯一標識符,能夠更加准確的控制緩存。Last-Modified與ETag是可以一起使用的,服務器會優先驗證ETag,一致的情況下,才會繼續比對Last-Modified,最后才決定是否返回304。
DNS域名解析
術語解釋:
根域,就是所謂的“.”,其實我們的網址www.baidu.com在配置當中應該是www.baidu.com.(最后有一點),一般我們在瀏覽器里輸入時會省略后面的點,而這也已經成為了習慣。根域服務器我們知道有13台,但是這是錯誤的觀點。根域服務器只是具有13個IP地址,但機器數量卻不是13台,因為這些IP地址借助了任播的技術,所以我們可以在全球設立這些IP的鏡像站點,你訪問到的這個IP並不是唯一的那台主機。
域名后綴,國際頂級域名,有兩種划分方式,一種互聯網剛興起時的按照行業性質划分的com.,net.等,一種是按國家划分的如cn.,jp.,等。每個域都會有域名服務器,也叫權威域名服務器。
頂級域或者叫做一級域,baidu.com就是一個頂級域名,而www.baidu.com卻不是頂級域名,他是在baidu.com 這個域里的一叫做www的主機。
二級域,三級域,只要我買了一個頂級域,並且我搭建了自己BIND服務器(或者其他軟件搭建的)注冊到互聯網中,那么我就可以隨意在前面多加幾個域了(當然長度是有限制的)。比如a.www.baidu.com,在這個網址中,www.baidu.com變成了一個二級域而不是一台主機,主機名是a。
域名服務器,能提供域名解析的服務器,上面的記錄類型可以是A(address)記錄,NS記錄(name server),MX(mail),CNAME等。
A記錄,A代表的是address,用戶可以在此設置子域名並指向到自己的目標主機地址上,從而實現通過域名找到服務器。指向的目標主機地址類型只能使用IP地址,如將taobao.com域名下的item.taobao.com指定到115.238.33.11,order.taobao.com指定到112.134.22.34。A記錄可以將多個域名解析到一個IP地址,但不能將一個域名解析到多個IP地址。
MX記錄,表示的是Mail Exchange(郵件交換記錄),用於將以該域名為結尾的電子郵件指向對應的郵件服務器以進行處理。如:用戶所用的郵件是以域名mydomain.com為結尾的,則需要在管理界面中添加該域名的MX記錄來處理所有以@mydomain.com結尾的郵件。
說明:MX記錄可以使用主機名或IP地址;·MX記錄可以通過設置優先級實現主輔服務器設置,“優先級”中的數字越小表示級別越高。也可以使用相同優先級(即隨機)達到負載均衡的目的;·如果在“主機名”中填入子域名則此MX記錄只對該子域名生效。
CNAME記錄,全稱是Canonical Name(別名解析)。可以為一個域名設置一個或者多個別名。
說明:CNAME的目標主機地址只能使用主機名,不能使用IP地址;·主機名前不能有任何其他前綴,如:http://等是不被允許的;A記錄優先於CNAME記錄。即如果一個主機地址同時存在A記錄和CNAME記錄,則CNAME記錄不生效。
NS記錄,解析服務器記錄,為某個域名指定DNS解析服務器,也就是這個域名由指定的IP地址的DNS域名服務器去解析。例如用戶希望由12.34.56.78這台服務器解析news.mydomain.com,則需要設置news.mydomain.com的NS記錄。
說明:“優先級”中的數字越小表示級別越高;·“IP地址/主機名”中既可以填寫IP地址,也可以填寫像ns.mydomain.com這樣的主機地址,但必須保證該主機地址有效。如將news.mydomain.com的NS記錄指向到ns.mydomain.com,在設置NS記錄的同時還需要設置ns.mydomain.com的指向,否則NS記錄將無法正常解析;NS記錄優先於A記錄。即,如果一個主機地址同時存在NS記錄和A記錄,則A記錄不生效。這里的NS記錄只對子域名生效。
TXT記錄,為某個主機名或域名設置說明,如可以為taobao.com設置TXT記錄為“天下第一”這樣的說明。
DNS解析過程
當用戶在瀏覽器中輸入域名並按下回車鍵后
第一步:瀏覽器會檢查緩存中有沒有這個域名對應的解析過的IP地址,如果有,這個解析過程就結束了,直接拿到IP進行訪問。這個瀏覽器緩存域名是有限制的,除了緩存大小有限制,緩存的時間也有限制,通常情況下由TTL屬性來設置。
第二步:如果用戶瀏覽器緩存中沒有,瀏覽器會查找操作系統中是否有這個域名對應的DNS解析結果。windows中c:/windows/system32/drivers/etc/hosts文件設置,linux中/etc/hosts文件中設置。當解析到這個配置文件中的某個域名時,操作系統會在緩存中緩存這個解析結果。(修改文件后不立即生效的原因)
第三步:在網絡配置中都會有“DNS服務器地址”這一項,當前面兩步都不能解析時,操作系統會把這個域名發送給設置的DNS服務器(簡稱LDNS)-local縮寫,一般是本地區的域名服務器也可以是自己設置的域名服務器地址,如果命中,那解析就此結束並返回IP並標記為非權威服務器的應答。如是學校的互聯網,那么你的DNS服務器肯定在你的學校,如果你是一個小區接入互聯網,那這個DNS就是提供給你接入互聯網的應用供應商,即電信或聯通。windows中能用ipconfig查看DNS服務器地址,linux中cat /etc/resolv.conf查看DNS Server。
第四步:如果LDNS沒有命中,LDNS就會向Root Server域名服務器請求解析。LDNS會從配置文件里面讀取13個根域名服務器的地址(這些地址是不變的,直接在BIND的配置文件中),然后像其中一台發起請求。
第五步:根服務器拿到這個請求后,知道他是com.這個頂級域名下的,所以就會返回com.域中的NS記錄,一般來說是13台主機名和IP(主域名服務器地址即gTLD-國際頂級域名服務器地址),返回給本地域名服務器即LDNS,
第六步:LDNS再向上一步返回的其中一台gTLD服務器發送請求。com.域的服務器(gTLD)發現你這請求是baidu.com這個域的,一查發現了這個域的NS(一般就是你注冊的域名服務器),那就返回給你,你再去查。
第七步:LDNS接受gTLD返回的域服務器地址(即域名服務提供商的域服務器)並向其中一台再次發起請求,在baidu.com的域下面查了下有www的這台主機,就把這個IP返回給你了。
第八步:LDNS接受返回的IP和TLL值
第九步:LDNS緩存這個域名和IP的對應關系,緩存時間有TLL控制
第十步:LDNS把解析的結果返回給用戶,用戶根據TLL值緩存在本地系統緩存中,域名解析結束。
ps:
一般經歷從根域名(.)到gTLD Server(.com.)到Name Server(taobao.com.)
DNS的服務器有多個備份,可以從任何一台查詢到解析結果。
跟蹤域名解析過程的命令
nslookup 查詢域名的解析結果 linux&windows
dig host +trace 查詢DNS的解析過程 linux
清除緩存的域名
ipconfig /flushdns 刷新緩存 windows
/etc/init.d/nscd restart 重啟 linux
JVM也會緩存DNS的解析結果,這個緩存是在InetAddress類中完成的,而且這個緩存時間比較特殊,它有兩種策略:一種是正確解析結果緩存,另一種是失敗的解析結果緩存。這兩個緩存時間由兩個配置項控制,配置項在%JAVA_HOME%\lib\security\java.security文件中。兩個配置項分別是networkaddress.cache.ttl和networkaddress.cache.negative.tll,默認值分別是-1(永不失效)和10(緩存10秒)。
-Dsun.net.inetaddr.tll=***可以來修改默認值,InetAddress類也可以動態修改。
CDN(Content Delivery Network)
CDN也就是內容分布網絡(Content Delivery Network),它是構築在現有 Internet 上的一種先進的流量分配網絡。其目的是通過在現有的 Internet 中增加一層新的網絡架構,將網站的內容發布到最接近用戶的網絡"邊緣",使用戶可以就近取得所需的內容,提高用戶訪問網站的響應速度。有別於鏡像,它比鏡像更智能,可以做這樣一個比喻:CDN = 鏡像(Mirror)+ 緩存(Cache)+ 整體負載均衡(GSLB)。因而,CDN 可以明顯提高 Internet中信息流動的效率。
目前CDN都以緩存網站中的靜態數據為主,如CSS、JS、圖片和靜態頁面等數據。用戶在從主站服務器請求到動態內容后再從CDN上下載這些靜態數據,從而加速網頁數據內容的下載速度,如淘寶有90%以上的數據都是由CDN來提供的。
CDN架構

一個用戶訪問某個靜態文件(如CSS文件),這個靜態文件的域名假如是cdn.taobao.com,那么首先要向Local DNS服務器發起請求,一般經過迭代解析后回到這個域名的注冊服務器去解析,一般每個公司都會有一個DNS解析服務器。這時這個DNS解析服務器通常會把它重新CNAME解析到另外一個域名,重新從.(根域名)發起對這個域名的解析,而這個域名最終會被指向CDN全局中的DNS負載均衡服務器,再由這個GTM來最終分配是哪個地方的訪問用戶,返回給離這個訪問用戶最近的CDN節點。
拿到DNS解析結果,用戶就直接去這個CDN節點訪問這個靜態文件了,如果這個節點中所請求的文件不存在,就會再回到源站去獲取這個文件,然后再返回給用戶。
負載均衡
負載均衡(Load Balance)就是對工作任務進行平衡、分攤到多個操作單元上執行,如圖片服務器、應用服務器等,共同完成工作任務。它可以提高服務器響應速度及利用效率,避免軟件或者硬件模塊出現單點失效,解決網絡擁塞問題,實現地理位置無關性,為用戶提供較一致的訪問質量。
通常有三種負載均衡架構,分別是鏈路負載均衡、集群負載均衡和操作系統負載均衡。
鏈路負載均衡也就是前面提到的通過DNS解析成不同的IP,然后用戶根據這個IP來訪問不同的目標服務器。負載均衡是由DNS的解析來完成的,用戶最終訪問哪個Web Server是由DNS Server來控制的,在這里就是由Global DNS Server來動態解析域名服務。這種DNS解析的優點是用戶會直接訪問目標服務器,而不需要經過其他的代理服務器,通常訪問速度會更快。但是也有缺點,由於DNS在用戶本地和Local DNS Server都有緩存,一旦某台Web Server掛掉,那么很難及時更新用戶的域名解析結構。如果用戶的域名沒有及時更新,那么用戶將無法訪問這個域名,帶來的后果非常嚴重。

集群負載均衡是另外一種常見的負載均衡方式,它一般分為硬件負載均衡和軟件負載均衡。
硬件負載均衡一般使用一台專門硬件設備來轉發請求,硬件負載均衡的關鍵就是這台價格非常昂貴的設備,如F5,通常為了安全需要一主一備。它的優點很顯然就是性能非常好,缺點就是非常貴,一般公司是用不起的,還有就是當訪問量陡然增大超出服務極限時,不能進行動態擴容。

軟件負載均衡是使用最普遍的一種負載方式,它的特點是使用成本非常低,直接使用廉價的PC就可以搭建。缺點就是一般一次訪問請求要經過多次代理服務器,會增加網絡延時。兩台是LVS,使用四層負載均衡,也就是在網絡層利用IP地址進行地址轉發。下面三台使用HAProxy進行七層負載,也就是可以根據訪問用戶的HTTP請求頭來進行負載均衡,如可以根據不同的URL來將請求轉發到特定機器或者根據用戶的Cookie信息來指定訪問的機器。

操作系統負載均衡,就是利用操作系統級別的軟中斷或者硬件中斷來達到負載均衡,如可以設置多隊列網卡等來實現。
CDN動態加速
CDN動態加速技術原理是在CDN的DNS解析中通過動態的鏈路探測來尋找回源最好的一條路徑,然后通過DNS的調度將所以請求調度到選定的這條路徑上回源,從而加速用戶訪問的效率。
由於CDN節點是遍布全國的,所有用戶接入一個CDN節點后可以選擇一條從離用戶最近的CDN節點到原站鏈路最好的路徑讓用戶走。一個簡單的原則就是從源站上下載一個指定大小的文件,看哪個鏈路耗時最短,這樣可以構成一個鏈路列表然后綁定到DNS解析上,更新到CDN的LDNS。
