此文是根據馬濤在【QCon高可用架構群】中的分享內容整理而成,轉發請註明出處。
馬濤,前迅雷網絡CDN系統研發工程師,也曾任EMC/Pivotal大數據處理系統Hawq研發工程師。從事CDN之前主要做資料庫內核,平時關注大數據處理、並行系統容錯和優化、後臺服務性能優化。
1.CDN系統工作原理1.1 DNS解析方式客戶網站使用CDN加速應用或其他下載類資源:
客戶域名: example.com
客戶加速域名: cdn.example.com
CDN 廠商加速域名: cdn.com
CDN 廠商 CNAME 域名: example.com.cdn.com
上圖是不使用CDN加速的情況。解析DNS是由客戶的權威伺服器完成的。要使用CDN加速,客戶需要在自己的權威 dns 中配置:cdn.example.com => example.com.cdn.com,然後用戶只需要將需要加速的文件掛上cdn.example.com就可以自動使用CDN系統加速了。
用戶請求客戶頁面的流程如下:
www.example.com => 解析返回客戶 http server ip
頁面中嵌入的 cdn.example.com => 解析返回 CDN 的域名 example.com.cdn.com => 經過 CDN 廠商 + DNS 調度後, 返回指向某個特定的 IP(這個過程可能經歷了多次 CNAME 跳轉)。
用戶通過建立 http 連接, 請求伺服器下載資源。
下面的圖,是加入了CDN系統的請求流程,因為中間加入了CNAME跳轉,在客戶端就可以無縫同時訪問多個伺服器展示信息。
優點:
缺點:
功能限制: 只能根據域名解析 ip 地址, 不能進行額外的優化
容易被影響: 不遵守 DNS 解析 TTL 的代理伺服器, DNS一些常見的劫持問題
這是傳統的CDN加速方式,也是市面上最常見的方式。優缺點很明顯,這裡我就簡單列舉出來。
1.2 非DNS解析方式客戶通過嵌入SDK, 不經過傳統 DNS 解析方式來使用 CDN 資源. 例如:HttpDns。
客戶在自己的程序中嵌入一個查詢模塊,任何查詢域名的操作都經過該模塊代理完成。協議可以是自定義的, 加密可以單獨控制, 查詢的內容也可以定製化。剛好周一分享過 HttpDns Lib 的內容(可關注本公眾號,查看歷史文章),我這裡也就一筆帶過了。
優點:
功能強大: 可以根據資源, 甚至其他信息來允許調度程序進行額外的優化工作
傳輸協議靈活: 可以是標準的自定義 tcp/udp 協議, 也可以是 http 協議
不容易被影響: 報文可以加密, 協議為自定義協議, 不容易被劫持和緩存
缺點:
目前很多視頻播放軟體都是採用第二種方案進行,因為這種方案可以對資源進行準確定位,提高資源命中率。
對大家來說,CDN系統是一個比較透明的系統,這也是為什麼很多人可能不知道CDN系統的原因。那麼下面,我來簡單介紹下,CDN廠商自己的CDN系統架構。
上是China Cache分享的架構圖,大部分 CDN 系統在組成上沒有本質區別。但是組成的方式,模塊間的互動設計影響著各個功能的實時性/可靠性/可擴展性。
運營系統模塊
主要包含元數據,和一些最外層的控制展現。客戶需要簡單的訪問一些接口,配置需要加速的域名,防盜鏈信息,查看流量監控信息等。同時,CDN 廠商也需要在這裡管理用戶的各種內部配置,幫助用戶處理一些疑問。傳統解決方案都是動態頁面配合資料庫進行的。
當然目前更好的方案是,運營模塊只保留展示層,核心部分可以考慮抽象為獨立的http api服務,通過這種思路,甚至允許更好的與第三方進行對接配合,分攤一些對於配置關聯監控的需求給客戶自己去做。
目前 http api 網關還有微服務架構都很火,實際上CDN廠商的技術大部分還比較陳舊。不過也在慢慢的更新。如果打個比方,運營系統類似快遞中的下訂單部分,用戶給出要投遞的信息,結帳,查看投遞信息。
網絡管理系統
CDN 系統往往都有成百上千(甚至上萬)的節點組成,這樣一個龐大的網絡系統,小到單機可用性,大到網絡拓撲,節點間連通性,互備設置,應急處理都需要跟蹤和處理。網絡管理系統需要能夠跟蹤所有接入的系統的伺服器,監控伺服器的狀態,能夠根據伺服器狀態/連路狀態自動生成維護工單,向外提供的節點可用性信息,鏈路狀況等數據給調度系統。
CDN中運維是一個很重要的角色,自動化運維,智能化運維。藉助雲架構來改進CDN韻味水平也是很重要的工作。類似的比喻就是快遞系統中,對於運輸工具的管理和路由通道的監控。例如:北京到武漢的貨運/鐵路/航運/空運的動向和可用車次。
負載均衡系統
一個好的 CDN 系統,負載均衡系統也就是調度系統是核心模塊,也是含金量最高的模塊之一。稍後再單獨說一些調度系統。快遞系統中,保證快遞時效,降低物流成本,提高運輸系統的效率,這些都是快遞中非常重要的模塊。這部分主要都是自行研發, 配合一些開源軟體。
分發服務系統
最後一個模塊就是真正的分發系統了,我們可以想像成,快遞員和分揀員。如果數據還沒有緩存在本地,分發服務系統能夠將請求數據從上層取回,並發送給請求者。對於惡意攻擊,需要做基本的防範。
還要進行相應的請求權限檢查(防盜鏈)。最後記錄每個請求和相關信息,用於最後的計費,質量跟蹤和其他統計。這裡比較成熟的開源軟體包括:squid/apache/nginx。
一般傳統的 CDN 系統在介紹時,沒有涉及過多的「數據」作用。其實這也是很正常的,因為傳統系統中,「數據」大部分時候被鎖死在資料庫中。而線上日誌有時候為了性能而被關閉!但是隨著硬體和數據分析技術的成熟和普及,我相信越來越多的 CDN 廠商早就利用數據來幫助自己的完善自己系統。數據主要可以幫助分發服務系統進行預先的推送,另外也可以優化調度系統,將部分負載搞過的節點流量遷移到低負載節點上。
1.4 調度在任何一個 CDN 系統中, 調度模塊都是最核心的部分,調度模塊承載。而大部分的調度是通過 DNS 解析實現的,這就要求DNS在解析時, 可以智能地進行調度工作。
調度一般會考慮很多因素
地域,線路,數據中心負載,請求優先級(當系統負載過高時,優先響應哪些請求),應急流量調度(流量暴漲後,將流量導向到其他位置的選擇),成本考慮調度(考慮帶寬成本)。除此之外,調度自身的性能,容錯,防攻擊都是這裡需要考慮和解決的。
調度中兩個很重要的信息就是ip庫的構建和伺服器信息的採集。一個質量好的 ip 庫可以讓調度程序更準確選擇地域和ISP。並在異常情況下更好的進行特殊處理。而合理及時的伺服器信息,可以幫助調度程序更好的平衡複雜,提高系統整體服務質量,這些信息可以是通過第三方探測的數據,也可以是伺服器自身的真實數據。
實際上ip庫可以從網上下載:純真ip庫,還可以在ip138上抓取,最後還有公開的 BGP 網絡協議。通過綜合運用上面的信息,一般都可以得到一個質量比較高的ip庫。當然,國內主要的下載軟體廠商信息非常大,能獲得很多外界無法得到的鏈路信息和ip信息。這也是下載廠商得天獨厚的優勢之一。
除了IP庫外,如果對複雜需求建模和設計權值來保證調度效果也是CDN系統的核心之一。這部分內容屬於各家廠商最重要的部分,因此我也不方便繼續深入介紹。
除了DNS調度外,如果使用非DNS調度,那麼還可以維護文件和伺服器的映射關係,這樣可以更精確的進行訪問調度,降低流量成本。
1.5 資源的部署方式CDN 系統實際是一種緩存系統, 客戶通過 CDN 系統可以為用戶提供更好的帶寬質量。但是正常情況下,資源是由客戶提供的,因此 CDN 系統會為每個加速域名都記錄相關的原始站點信息。
當 CDN 系統第一次請求響應資源時,首先會根據配置的原始站點,進行「回源」操作。這個操作不難想像,在回源操作時,節點將會緩存資源到本地存儲,並轉發資源給請求方。除了被動的拉取外,一些廠商實現了「推」模式,將預計會成為熱點的資源,提前從用戶站點下載,並分發到各個節點上。對於一些大的 CDN 廠商來說,節點數量非常多(成千上萬),如果同時請求客戶源站,就相當於對客戶發起了DDoS攻擊。因此,基本上CDN系統都會被劃分為多個層級。下圖就是藍迅的3層架構:
為了保證系統的可靠性,每個節點存在多個互相備份的頂層節點。只有這些頂層節點才能真正的向客戶源站發起「回源」請求。「回源」次數本身也作為CDN系統中一個重要指標,來衡量CDN系統的好與差。CDN 系統中,葉子節點,一般稱為邊緣節點,邊緣節點實際是調度程序返回真實ip地址,而邊緣節點可以向上級節點請求資源。下面我簡單給出一個通用的回源模塊的設計圖:
圖中負責回源的模塊, 需要接收請求進來, 然後根據文件是否下載,決定後續的處理. 如果文件已經緩存在本地,則可以直接進入響應隊列。如果沒有緩存,應該進行請求合併,允許多個請求者掛在一個下載任務上。這裡還有很多細節,比如:文件分塊下載,請求是範圍請求,構造請求的合法參數等。
這個回源模塊可以放在 nginx 中做, 並適當刪減一些模塊即可. 通信可以通過 ipc/shared memory 進行數據交換. 也可以將這部分功能獨立為一個進程. nginx 作為代理伺服器, 只做一些數據收集,防盜鏈校驗。
需要注意的是, 後者更適合大文件處理, 例如:百度曾經開源的 OliveHC 就是這個架構。當然不知道為什麼後來連結都被刪除了,我發現github上還有一個repo,後面會給大家連結。小文件加速實際上需要考慮如何提高處理的請求數量,一般追求iops而非吞吐。這裡可以用數學公式計算推滿一個1Gbps/10Gbps網卡需要的請求數量和平均請求大小。
這裡有很多細小的優化工作,例如:為了提高CDN系統一個關鍵參數「首包時間」,CDN系統一般要求資源在「回源」時,必須以流水線方式將資源從上級節點拉取到本地存儲,並轉發給客戶。在多層結構中,每個服務都需要做這樣的流水線操作,才能最小化延遲。
另外,還需要根據相應的統計信息,刪除本地存儲的「冷」資源。目前,隨著大數據推動,系統的優化空間也越來越大。這也是通過大數據分析,優化單獨節點緩存文件策略的一個非常好的切入點。
1.6 對帳,計費和日誌除了分發各種數據外,CDN 系統也要處理對帳,計費和日誌的問題。對帳是為了幫助客戶確認其購買的帶寬,真實有效。防止被其他人盜鏈,或被惡意刷流量。關於防盜鏈,後面會專門介紹。
計費一般相對簡單,就是根據域名進行帶寬的統計,根據每個月的第N峰值(一般是第三峰值)的95%來作為平均流量。這也是常說的95計費。
日誌往往需要為客戶保留下來,客戶可能有自己的反作弊和防盜鏈策略,可以根據保存的日誌信息,進行分析和預警,定期更新相應算法。
1.7 CDN 性能評估對於一些大客戶來說,如何衡量CDN質量成為了一個難題。因為 CDN 系統往往面相全國,甚至世界各地,再加上有不同運營商存在。因此一般簡單的測試方法都不具有實際的代表性,因此作為國內早起專門從事CDN 性能監控的公司:基調網絡,現在好像叫「聽雲」可以為用戶出具詳細的監測報告。幫助客戶了解 CDN 廠商的性能。通過「眾包」測試工作,聽雲在全國布點很多,因此採集的準確度很高。
不過聽雲的監測報告比較貴,對於帶寬需求較低的客戶來說,意義較小。但是,CDN 系統檢測時,隨著CDN系統本身負載不同,不同時間的監測效果可能差距較大。因此,監測報告的數據可以用來參考,但是需要注意其是否真實反映了你關注的需求點。
2 網絡分發過程中 ISP 的影響國內的ISP比較多,大ISP就是電信/聯通。此外還有:移動,鐵通,長寬等等。有超過10家的 ISP 在國內提供服務。雖然移動收購了鐵通,但是鐵通的運營完全是原有架構。也就是說,雖然實際ISP數量這幾年變少了,但是國內網際網路本身,還是有多家ISP存在的。
電信和聯通佔了絕大部分市場,剩下的小ISP佔比很低。這些 ISP 之間如果需要相互訪問流量,是會產生「跨網間結算「的,另外一些地方的IT無倫處於水平還是預算等問題,還會在系統配製時,設置各種」不正常的「參數。
2.1 DNS 緩存劫持DNS 協議是網際網路最重要協議之一, 但是 DNS 本身有很多的缺陷。DNS 緩存本身作為一個非常重要的系統優化,在國內環境中,卻經常帶來問題。
一些小地方的DNS節點,可能會修改用戶指定的 TTL 時間,將這個時間設置的超大,例如:24-48小時。一旦發生這種情況,通過該DNS的請求,將會長時間無法正常的被調度,該地區的流量和容錯都可能受到影響。
但是上面的問題又是無解的,因為這個過程完全是標準流程的結果。為了解決這個問題,才有一些有能力的公司開始使用私有的解析協議,防止 DNS 系統帶來的問題。偶爾運營商還會劫持域名(被攻擊,錯誤配置,插入廣告地址)。
2.2 運行商結算對 HTTP 協議的緩存影響當客戶端終於拿到了 ip 準備連接目標伺服器時,最常用的 HTTP 協議又成為了另一個帶來問題的協議。HTTP協議可以用來傳輸小文件,也可以用來傳輸大文件。同時允許斷點續傳等高級特性。很多 FLASH 瀏覽器就是用 HTTP 協議進行視頻播放的。
上面說到,由於 ISP 之間存在著「跨網間結算」問題,因此一些地方的伺服器(小運營商,小地區)會進行 HTTP 請求緩存。通過在客戶: client == http proxy == server 之間,建立HTTP代理,解析HTTP請求,將請求資源緩存,來節省跨網間結算。這裡, 會產生一些問題,例如:計費丟失,相應結果錯誤,請求錯誤等。
大部分 CDN 廠商通過 server 端日誌進行計費,上面的代理伺服器可以減少真實請求數量,因此實際上降低了實際流量。不過一般這類比較少,所以不是太大問題。一些 http proxy 實現有 bug,例如:對於含有:Range請求的 HTTP 伺服器,該代理丟掉了 range 信息,將整個文件都返回給了客戶,從而造成客戶端請求失敗。投訴 CDN 服務質量不好。
還有一些 http proxy 會把不同 http 請求的頭進行拼裝, 引起伺服器解析錯誤. 例如:一個請求中包含了多個 range 信息. 雖然標準 http 支持,但實際業務層不支持。
對於這類問題,一般可以嘗試在 HTTP 頭和 url 參數中添加隨機信息來避免。但是最好的辦法, 是請求的連結中直接包含隨機路徑,讓上述的緩存伺服器無法緩存所有的信息,還有就是使用https協議。
3 防盜鏈3.1 防盜鏈的目的防盜鏈是一場貓捉老鼠的遊戲。盜鏈的目的只有一個:利潤。通過盜取他人的流量,吸引客戶在自己的網站觀看和點擊廣告,從而實現利潤。而防盜鏈,就是通過創建訪問規則,通過規則來識別請求的「合法性」,來決定如何響應請求。如果想單純通過防盜鏈來保護資源本身,一般是不屬於防盜鏈這個範疇的。
通過上面的介紹,可以將資源分為兩類來對待:帶寬價值較低的資源,例如:網站logo圖片,js腳本等資源。另一類就是帶寬價值較高的:應用,多媒體文件等。對於不同價值的資源,防盜鏈的方法也越來越高級,越來越複雜。
根據 http 請求頭的 referer 信息 正規的瀏覽器, 會在請求頁面時, 將引起該請求的頁面url作為 referer 的值嵌入到 http 請求中。因此, 在伺服器端就可以通過簡單的判斷來決定是否返回資源。以前也有很多網站使用這個信息做權限檢查。referer有兩個問題,導致它一般只用做校驗帶寬價值低的資源。首先是一些防火牆可能會修改 http 請求頭部,導致 referer 信息被設置為空或完全刪除。其次,使用各種第三方工具,例如:curl/wget等,都可以隨意設置 referer。因此, referer不適合被單獨用來保護帶寬價值高的資源。
動態url防盜鏈 動態url是通過程序配合,使某個資源的url在某一次請求或某一段特定時間內合法。換句話說,每個資源的url有一個失效的時間。因此,盜鏈者拿到url後,不能簡單重複的使用。這種方法一般是一些小站使用,因為這個過程往往同時需要動態頁面和後端伺服器配合起來進行操作,一般不適合大規模的資源分發。
動態參數或cookie防盜鏈 目前使用比較多的保護策略是基於動態參數或cookie進行的。在每一次請求資源時,動態頁面會根據用戶信息,時間戳等信息(用戶可以自行編輯規則)動態生成一個請求參數。通過http協議將這個信息發送到伺服器後端,後端會根據同樣的信息計算並驗證請求參數的合法性來決定返回結果。這個生成的規則可能會被破解,也可以適當引入更加複雜的安全校驗來規避風險。另外配合訪問日誌的信息,可以分析流量請求的模式,根據前端SDK信息來分析請求的合法性,定期升級防盜鏈算法和相關參數。
所以防盜鏈本身不難,主要還是設計規則的合理性上。要兼顧性能和安全,切忌殺雞用牛刀。
4 內容分發系統的問題和應對思路4.1 流媒體分發流媒體分發時,一般對於 flv 的支持會更好一些。原因是 flv 是基於文件偏移進行快進和倒退的。而mp4編碼,是根據時間進行快進和倒退的。某些CDN廠商可能對 mp4 的支持不好或者根本不支持。但是 flv 一般是可以直接支持的。實際上flv格式是通過播放器進行了一些偏移計算,因此降低了對分發伺服器的技術要求。這裡的難點,主要是前面講的回源模塊本身複雜帶來的。如果需要額外處理索引,程序層面也會比較複雜。
除此之外,分發的流媒體如果體積比較大,可以考慮主動對文件進行切片(小於100MB)。這樣對於某些配置較差的伺服器,可以做一些優化。例如:沒有陣列或者陣列卡比較差的機器上,避免將一個大文件放置在一個單獨磁碟,從而可以最大化的從多個磁碟上讀取該文件,有效提高吞吐。
前端 SDK 最好能夠收集數據,例如:發起客戶ip,連接伺服器的ip,解析伺服器ip的時間開銷。連接伺服器ip的時間開銷,首包時間開銷,數據中斷比例。伺服器返回狀態值,數據傳輸時間等。因為在整個網絡中,存在一些「代理伺服器」,因此,某些請求可能根本沒有到達伺服器或請求被修改過。通過前後端共同保留日誌,可以更佳清晰的分析結果,以便改進方法,提高用戶的體驗。數據是推動系統進步的一個非常重要的組成部分。
防盜鏈的設計應該考慮:在不嚴重影響客戶端性能和伺服器端性能下,讓破解盜鏈規則的難度儘可能高。雖然 referer 很容易被偽造,但是仍然可以作為第一道防線過濾一部分請求。通過複雜的規則, 來提高盜鏈的成本。通過前後端日誌分析,了解流量的消費情況,定期按需修改防盜鏈算法。
4.2 應用分發現在手機應用分發非常多,也有不少人遇到過連結劫持的問題。如果面對 dns 劫持,基本上只能使用第三方解析方案,例如 HttpDns。如果是http這層被「代理伺服器」緩存,那麼像前面所說,可以嘗試構造動態url來組織被緩存。對於 http 劫持,大家可以參考參考信息中的連結,介紹的很詳細。從原理上了解了問題本質後,一些手段會更有針對性,但是也會發現一些問題並非很容易解決。發現問題後,可以儘快投訴。所以大家可以晚點看我給出的參考連結,了解如何定位各種劫持。
4.3 nginx 在 Linux 上的性能優化相對於 CDN 系統來說, 伺服器程序主要使用系統上的網絡IO和磁碟IO。對於小請求(幾KB到幾十KB)來說,衡量的關鍵指標更偏重於每秒可以響應的請求數量。因為請求文件小,因此 nginx 有很多優化針對小文件。例如 sendfile 功能,可以避免將文件讀取到內存(經過系統緩存到用戶內存,再傳遞給網絡接口的系統用),而直接讓作業系統內核發送該文件。當然,這個功能也有缺點,就是如果文件太大,會導致帶寬被某個請求佔用,因此nginx內部做了限制,防止這種情況的出現。相對來說,大請求一般情況更關注磁碟IO和內存的優化。請求較大時,nginx 通過一個定長buffer來切割每個請求消耗的網絡和磁碟IO。這樣可以更公平的將有限的IO分配給多個請求,既不會浪費,也不會導致不均勻。
nginx 本身採用了事件模型驅動,多進程下,正常情況下每個進程只有一個線程。但是事件模型允許即使一個線程,也可以響應成千上萬的請求。
當 nginx 運行在 linux 系統上時,如果服務的文件的存儲大小比機器內存大比較多,並且這些文件都是熱點文件時,連接 nginx 伺服器可能會引起連接超時或連結建立過慢的問題。
這個問題要從兩個方面來解釋: linux 的文件訪問操作上分為兩類。
一類是利用作業系統的虛擬存儲來緩存熱點文件,因此可以提高磁碟訪問速度。還有一類接口被稱為直接訪問模式,該模式會繞過作業系統緩存,直接將文件加載到用戶進程內存空間。而 linux 上,第一類訪問模式不支持「異步操作」,也就是不兼容事件模式。而第二類訪問模式雖然兼容「異步操作」,但是因為沒有作業系統進行磁碟緩存,導致這裡接口不友好。第二類主要是沒有緩存管理,系統的性能會大幅下降。nginx 在 linux 上,一直以來都適用第一類訪問模式進行操作。nginx 的設計目標就是多進程提供更好的穩定性,降低進程間的交互。如果使用第二類模式,那麼就會增加複雜度,並且讓進程之間的交互引入更多封鎖(考慮支持數據緩存機制)。這也就是如果請求的資源無法放入系統的內存中,就會導致事件模型被文件操作卡住,無法正常的響應連接。
在 nginx 1.7.12 及之後的 1.8 中,nginx通過引入 thread pool 來緩解上面的問題。主線程決定要發起文件系統操作時,將會創建一個特殊的作業,並將該作業丟到作業隊列中。而線程池中的線程會不斷的執行該隊列的文件任務,然後將執行好的結果放入返回隊列,主線程就會繼續後續操作。通過這個操作,主線程不會再被阻塞住,因此建立連接將不會被卡住。
但是,如果 IO 嚴重不足時,請求時間仍然會很長,還是可能讓客戶端請求超時。這種case,可以進行其他優化,例如磁碟調度算法,優化文件存儲結構,升級存儲等。之前有一片文章說,nginx使用線程池性能提升9倍,實際就是說在linux上性能問題。該問題在FreeBSD系統上不存在,因為FreeBSD系統的異步IO支持使用內存作為文件緩存。
Linux上之所以不支持,也是因為社區一直扯皮。而非系統自身能力問題。
4.4 如何節省成本CDN 的價格不是特別透明,大牌廠商一般都是和銷售來談。而且這中間還會根據不同流量有一些折扣。 但是市面上 CDN 價格基本可以認為:
小文件價格 > 流媒體價格 > 下載類價格
而直播的價格也會高於點播類的流媒體價格。
如果籤署的價格協議是按照標準的峰值帶寬+95計費方式,那麼消峰往往是一個比較常見的方式。但是消峰要根據具體的使用場景來進行,例如下面的場景可能不適用或屬於消峰:緊急發布一個修復嚴重bug或安全漏洞的版本,這時候,可能會提示用戶儘快升級,可能會造成一個特別高的峰值。開闢新業務,舊流量沒有明顯改變下,在某些熱點時段產生新高峰。被大規模盜鏈,引起額外的流量,產生新高峰。消峰的方法就是將請求錯開,避免同一時間出現請求,下面場景比較適合消峰:發布非重要的升級,期望用戶逐步過渡。可以通過限制通知用戶升級的數量,來減少峰值出現。自動化日誌分析,針對異常流量,有自動化應急預案,例如:自動拒絕部分請求。
4.5 嵌入SDK 的對於客戶的影響實際上類似像 HttpDns 或者 p2p 加速這裡 sdk 都會遇到客戶擔憂的幾點:代碼安全性問題,體積大小引發的CDN成本上漲,穩定性問題,集成的額外代價(小客戶沒有人力或能力),需求是否真實存在(小客戶可能沒有精力考慮這些)。這也是 SDK 方案往往遇到難以推廣的問題。開源 SDK 從很大程度上可以降低客戶對代碼安全性的擔憂,但是成本,集成代價都是不太好解決的。
5.P2P穿牆打洞下面加上一點臨時補充的內容,也是來自網上,我簡單的組織了一下。幫助大家簡單了解P2P裡面一個關鍵技術, 打洞穿牆。
一般P2P雖然是多對多的傳輸, 但實際上, 可以分解為: 控制部分和傳輸部分. P2P 網絡中需要一些服務節點, 用於交換信息和協調打洞。當然這些服務節點一般還會有查詢資源位置和相關節點的功能。 傳輸部分中涉及的實體分兩類:可以直接被訪問的實體和隱藏在NAT後面的實體。只要有至少一方可以直接被訪問,那麼利用控制部分就可以建立傳輸通道,也就不需要進行打洞。當兩個實體都被隱藏在NAT後面時, 才有打洞這個問題。
所謂打洞,實際上是指隱藏在 NAT 內部伺服器通過連接外部實體時,在 NAT 伺服器上留下的一個「臨時」的映射關係。這樣 NAT 伺服器才能正確的將外網的數據包,發送給內部實體。
在 P2P 打洞時,每個實體都需要主動連接 P2P網絡的伺服器,將自己的外網IP和打洞出來的「臨時」埠上報到伺服器。這樣伺服器就可以根據該實體的資源信息和網絡信息一起保存下來,為後續請求連接的人提供輸入參數。
當實體A準備連接實體B時,只需要通過 P2P網絡的伺服器獲取連接信息就可以直接進行連接了。因為「臨時」的洞在之前已經建立好了。
這裡其實有一些額外的要求:
如果 NAT 打洞失敗,可以考慮放棄或者轉而使用伺服器轉發模式。
上面介紹的是比較簡單的UDP打洞,TCP也是可以穿牆打洞的,但是比較複雜,這裡我也沒有太多發言權。國內的廠商在穿牆打洞上確實有很多高手,對於國內複雜的網際網路環境,簡單的算法不能解決很多細節問題。正因為這些廠商在相關領域做了很久,才使得「高速通道」中的P2P傳輸效果非常好。
今天分享的內容,都來自下面的連結。大家如果願意對上面內容細節有更深入的了解,可以針對性的閱讀參考信息。
參考信息:CDN內容分發網絡架構與四大關鍵技術 http://www.idcquan.com/CDN/720016_2.html
CDN技術詳解 http://book.2cto.com/201207/327.html
Nginx開發從入門到精通 http://tengine.taobao.org/book/
nginx 線程池原文: https://www.nginx.com/blog/thread-pools-boost-performance-9x/
nginx 線程池翻譯: http://www.infoq.com/cn/articles/thread-pools-boost-performance-9x
淺析我國網際網路骨幹網網間結算問題 (http://blog.chinaunix.net/uid-20486655-id-261838.html)
nginx API 網關介紹: https://www.nginx.com/solutions/api-gateway/
nginx 微服務架構: https://www.nginx.com/blog/introduction-to-microservices/
dns 劫持/http 劫持: http://bbs.kafan.cn/thread-1825061-1-1.html
CDN緩存那些事 http://bbs.qcloud.com/forum.php?mod=viewthread&tid=3775
全局精確流量調度新思路-HttpDNS服務詳解 http://blog.csdn.net/zhaqiwen/article/details/42024045
百度曾經開源的 cdn 緩存工具OliveHC(國內已經關閉): https://github.com/Jacky-Li/olivehc
淺談網站防盜鏈技術 http://bbs.csdn.net/topics/110042791
Nginx防盜鏈詳細解說 http://blog.csdn.net/yuwenruli/article/details/8541952
隨機 url 等相關信息: http://stackoverflow.com/questions/29674755/a-single-regex-for-all-location-paths-regardless-of-the-name-in-nginx http://stackoverflow.com/questions/367786/prevent-caching-of-ajax-call http://stackoverflow.com/questions/126772/how-to-force-a-web-browser-not-to-cache-images
探密詭異的HTTP Referer總是為空的原因 http://www.cnblogs.com/dreamstudio/archive/2009/04/01/1427202.html
P2P內網穿透原理 http://bbs.cnhonker.com/forum.php?mod=viewthread&tid=7479
P2P之UDP穿透NAT的原理與實現 [轉] http://blog.csdn.net/lsaturn/article/details/29262
從ip138網站爬取ip所處地點 http://blog.csdn.net/jthink_/article/details/28597757
Nginx做前端Proxy時TIME_WAIT過多的問題 http://www.cnblogs.com/qleelulu/p/3601499.html
UDP穿透NAT的原理與實現(UDP「打洞」原理)http://blog.csdn.net/overmaker/article/details/3201799
QAQ1:CDN的首次域名解析慢,測試發現很多都需要幾百ms,怎麼優化?
A1:首次查詢因為沒有緩存,確實會更慢。這個過程可能需要根據dig工具開始, 不斷用迭代查詢, 判斷哪臺dns伺服器解析慢. 然後要求這個伺服器的管理者優化解析. 可能是自己的dns慢,也可能是CDN廠商的CDN伺服器慢。需要逐步的定位伺服器。
Q2:頂級節點 回源 操作獲取的資源文件是採用分布式存儲和管理的吧?會限制單個頂級節點的管理的資源大小嗎?
A2:這個問題很贊,但是因為不太了解各個廠家的情況,所以沒辦法給出統一和完整的答案。但是考慮到節點眾多,以及客戶規模不同,節點實際還會被分組。就是一部分節點只給一部分客戶用,這樣減少了頂級節點的存儲壓力。 同時,確實需要使用分布式存儲,這樣在容錯和存儲大小上都會更加從容。頂級節點也會有容量限制,一樣會清理資源。這也是「回源次數」是一個很重要的CDN衡量指標。
Q3:對不涉及目前內容下載的加速 CDN的意義就是打通各大運營商人為設置的障礙和負載均衡嗎? 比如物聯網設備接入加速。
A3:抱歉,我基本接觸的都是媒體加速和下載類加速。但是從我剛開始做CDN,到現在為止,我認為各大運營商之間的障礙是一個非常痛苦和漫長的過程。因此,如果說不考慮加速,那麼CDN確實有這些意義。 另外解決不同地區間的最優路徑選擇上,CDN系統確實也更有優勢。特別是晚上流量高峰時期,省間骨幹網絡的質量確實會下降很多。希望能幫助你。
Q4:在使用第三方CDN時,客戶https證書是怎樣管理的呢?
A4:這個我之前的業務範疇確實沒做到這麼深入,因為我們加速的大部分內容,還都是簡單的http。不過你這個問題特別好,我也之前確實看到過兩篇關於CDN和ssl的資料。目前CDN+ssl性能好像不是特別好,特別影響頁面的加載,另一個是CDN對網站的安全支持很有限,我可以繼續往下看看這邊。
想進一步了解CDN的架構細節?或想同群專家進一步交流CDN經驗及高可用架構,可回復arch申請進群。
本文策劃 陳剛@北京智識, 內容由劉世傑、陳剛、四正編輯與發布,其他多位志願者對本文亦有貢獻。讀者可以通過搜索「ArchNotes」或長按下面圖片,關注「高可用架構」公眾號,查看更多架構方面內容,獲取通往架構師之路的寶貴經驗。轉載請註明來自「高可用架構(ArchNotes)」公眾號,敬請包含二維碼!