玩轉robots協議 -- 其餘 -- IT技術博客大學習 -- 共學習 共進步! - Google Chrome (2013/7/14 20:24:07)
玩轉robots協議
2013年2月8日北京市第一中級人民法院正式受理了百度訴奇虎360違反「Robots協議」抓取、複製其網站內容的不正當競爭行爲一案,索賠金額高達一億元,這能夠看作2012年下半年「3B大戰」的繼續。在這次索賠案件中,百度稱本身的Robots文本中已設定不容許360爬蟲進入,而360的爬蟲依然對「百度知道」、「百度百科」等百度網站內容進行抓取。php
其實早在2012年11月初,針對雙方摩擦加重的狀況,在中國互聯網協會的牽頭下,包括百度、新浪、奇虎360在內的12家互聯網公司已共同簽署了《互聯網搜索引擎服務自律公約》,在公約第七條承諾「遵循國際通行的行業慣例與商業規則,遵照機器人協議(robots協議)。css
今天就找個機會聊聊一晚上成名的robots協議。html
初識robots協議
什麼是robots
要了解robots協議首先要了解robots,本文說的robots不是《I,robot》裏的威爾·史密斯,不是《機器人總動員》裏的瓦力和伊娃,不是《終結者》系列中的施瓦辛格。什麼?這些經典電影你都不知道?好吧,算我想多了。本文的robots特指搜索引擎領域的web robots,這個名字可能不少人不熟悉,可是提到Web Wanderers,Crawlers和Spiders不少人可能就恍然大悟了,在中文裏咱們統稱爲爬蟲或者網絡爬蟲,也就是搜索引擎抓取互聯網網頁的程序。python
同窗們都知道網頁是經過超級連接互相關聯起來的,從而造成了網頁的網狀結構。爬蟲的工做方式就像蜘蛛在網上沿着連接爬來爬去,最基本的流程能夠簡化以下:jquery
1.餵給爬蟲一堆url,咱們稱之爲種子(seeds)web
2.爬蟲抓取seeds,解析html網頁,抽取其中的超級連接ajax
3.爬蟲接着抓取這些新發現的連接指向的網頁算法
2,3循環往復數據庫
什麼是robots協議
瞭解了上面的流程就能看到對爬蟲來講網站很是被動,只有老老實實被抓取的份。存在這樣的需求:windows
1.某些路徑下是我的隱私或者網站管理使用,不想被搜索引擎抓取,好比說日本愛情動做片
2.不喜歡某個搜索引擎,不肯意被他抓取,最有名的就是以前淘寶不但願被百度抓取
3.小網站使用的是公用的虛擬主機,流量有限或者須要付費,但願搜索引擎抓的溫柔點
4.某些網頁是動態生成的,沒有直接的連接指向,可是但願內容被搜索引擎抓取和索引
網站內容的全部者是網站管理員,搜索引擎應該尊重全部者的意願,爲了知足以上等等,就須要提供一種網站和爬蟲進行溝通的途徑,給網站管理員表達本身意願的機會。有需求就有供應,robots協議就此誕生。Robots協議,學名叫:The Robots Exclusion Protocol,就搜索引擎抓取網站內容的範圍做了約定,包括網站是否但願被搜索引擎抓取,哪些內容不容許被抓取,把這些內容放到一個純文本文件robots.txt裏,而後放到站點的根目錄下。爬蟲抓取網站內容前會先抓取robots.txt,據此「自覺地」抓取或者不抓取該網頁內容,其目的是保護網站數據和敏感信息、確保用戶我的信息和隱私不被侵犯。
須要注意的是robots協議並不是是規範,只是行業內一個約定俗成的協議。什麼意思呢?Robots協議不是什麼技術壁壘,而只是一種互相尊重的協議,比如私家花園的門口掛着「閒人免進」,尊重者繞道而行,不尊重者依然能夠推門而入,好比說360。
說了這麼多,看幾個有名的例子感受一下先:
例子1:淘寶
User-agent: Baiduspider
Disallow: /
User-agent: baiduspider
Disallow: /
程序猿,你懂的。這不就是淘寶不想讓百度抓取嘛
例子2:京東
User-agent: *
Disallow: /?*
Disallow: /pop/*.html
User-agent: EtaoSpider
Disallow: /
這個也不復雜,京東有2個目錄不但願全部搜索引擎來抓。同時,對etao徹底屏蔽。
基本玩法
robots.txt的位置
說簡單也簡單,robots.txt放到一個站點的根目錄下便可。說複雜也有點小複雜,一個robots.txt只能控制相同協議,相同端口,相同站點的網頁抓取策略。什麼意思呢?看個例子最清楚:
百度網頁搜索
百度知道
這兩個robots.txt的內容是不一樣的,也就是說百度網頁搜索和百度知道的抓取策略能夠由本身獨立的robots.txt來控制,井水不犯河水。
robots.txt的內容
最簡單的robots.txt只有兩條規則:
1.User-agent:指定對哪些爬蟲生效
2.Disallow:指定要屏蔽的網址
整個文件分爲x節,一節由y個User-agent行和z個Disallow行組成。一節就表示對User-agent行指定的y個爬蟲屏蔽z個網址。這裏x>=0,y>0,z>0。x=0時即表示空文件,空文件等同於沒有robots.txt。
下面詳細介紹這兩條規則:
User-agent
爬蟲抓取時會聲明本身的身份,這就是User-agent,沒錯,就是http協議裏的User-agent。robots.txt利用User-agent來區分各個引擎的爬蟲。
舉例說明:google網頁搜索爬蟲的User-agent爲Googlebot,下面這行就指定google的爬蟲。
User-agent:Googlebot
若是想指定全部的爬蟲怎麼辦?不可能窮舉啊,能夠用下面這一行:
User-agent: *
可能有的同窗要問了,我怎麼知道爬蟲的User-agent是什麼?這裏提供了一個簡單的列表:爬蟲列表
固然,你還能夠查相關搜索引擎的資料獲得官方的數據,好比說google爬蟲列表,百度爬蟲列表
Disallow
Disallow 行列出的是要攔截的網頁,以正斜線 (/) 開頭,能夠列出特定的網址或模式。
要屏蔽整個網站,使用正斜線便可:
Disallow: /
要屏蔽某一目錄以及其中的全部內容,在目錄名後添加正斜線:
Disallow: /無用目錄名/
要屏蔽某個具體的網頁,就指出這個網頁。
Disallow: /網頁.html
Disallow還可使用前綴和通配符。
要屏蔽目錄a1-a100,可使用上面的方式寫100行,或者
Disallow:/a
可是須要注意,這樣會把任何以a開頭的目錄和文件也屏蔽,慎用。若是須要屏蔽a1-a100,可是不屏蔽a50,怎麼辦?同窗們能夠思考一下,這個問題咱們留到下一節。
要阻止特定類型的文件(如 .gif),請使用如下內容:
Disallow: /*.gif$
*匹配任意個字符,$匹配url結束,具體就不解釋了吧,不瞭解的同窗去自學一下通配符。
提示一下,Disallow的內容區分大小寫。例如,Disallow: /junkfile.asp 會屏蔽 junkfile.asp,卻會容許Junk_file.asp。
最最後,通配符不是全部搜索引擎都支持,使用要當心。沒辦法,誰讓robots.txt沒有一個你們都認可的標準呢。
實例 ###
百度網頁搜索
User-agent: Baiduspider
Disallow: /baidu
Disallow: /s?
User-agent: Googlebot
Disallow: /baidu
Disallow: /s?
Disallow: /shifen/
Disallow: /homepage/
Disallow: /cpro
User-agent: MSNBot
Disallow: /baidu
Disallow: /s?
Disallow: /shifen/
Disallow: /homepage/
Disallow: /cpro
...
如今讀懂這個應該毫無壓力了吧,順便說一句百度的robots.txt比較嗦,有興趣的同窗能夠簡化一下。
高階玩法
首先聲明:高級玩法不是全部引擎的爬蟲都支持,通常來講,做爲搜索引擎技術領導者的谷歌支持的最好。
例子:google robots.txt
allow
還記得上面的問題嗎?若是須要屏蔽a1-a100,可是不屏蔽a50,怎麼辦?
方案1:
Disallow:/a1/
Disallow:/a2/
...
Disallow:/a49/
Disallow:/a51/
...
Disallow:/a100/
方案2:
Disallow:/a
Allow:/a50/
ok,allow你們會用了吧。
順便說一句,若是想屏蔽a50下面的文件private.html,咋整?
Disallow:/a
Allow:/a50/
Disallow:/a50/private.html
聰明的你必定能發現其中的規律,對吧?誰管的越細就聽誰的。
sitemap
前面說過爬蟲會經過網頁內部的連接發現新的網頁。可是若是沒有鏈接指向的網頁怎麼辦?或者用戶輸入條件生成的動態網頁怎麼辦?可否讓網站管理員通知搜索引擎他們網站上有哪些可供抓取的網頁?這就是sitemap,最簡單的 Sitepmap 形式就是 XML 文件,在其中列出網站中的網址以及關於每一個網址的其餘數據(上次更新的時間、更改的頻率以及相對於網站上其餘網址的重要程度等等),利用這些信息搜索引擎能夠更加智能地抓取網站內容。
sitemap是另外一個話題,足夠開一篇新的文章聊的,這裏就不展開了,有興趣的同窗能夠參考sitemap
新的問題來了,爬蟲怎麼知道這個網站有沒有提供sitemap文件,或者說網站管理員生成了sitemap,(多是多個文件),爬蟲怎麼知道放在哪裏呢?
因爲robots.txt的位置是固定的,因而你們就想到了把sitemap的位置信息放在robots.txt裏。這就成爲robots.txt裏的新成員了。
節選一段google robots.txt:
Sitemap: http://www.gstatic.com/culturalinstitute/sitemaps/www_google_com_culturalinstitute/sitemap-index.xml
Sitemap: http://www.google.com/hostednews/sitemap_index.xml
插一句,考慮到一個網站的網頁衆多,sitemap人工維護不太靠譜,google提供了工具能夠自動生成sitemap。
meta tag
其實嚴格來講這部份內容不屬於robots.txt,不過也算很是相關,我也不知道放哪裏合適,暫且放到這裏吧。
robots.txt的初衷是爲了讓網站管理員管理能夠出如今搜索引擎裏的網站內容。可是,即便使用 robots.txt 文件讓爬蟲沒法抓取這些內容,搜索引擎也能夠經過其餘方式找到這些網頁並將它添加到索引中。例如,其餘網站仍可能連接到該網站。所以,網頁網址及其餘公開的信息(如指向相關網站的連接中的定位文字或開放式目錄管理系統中的標題)有可能會出如今引擎的搜索結果中。若是想完全對搜索引擎隱身那咋整呢?答案是:元標記,即meta tag。
好比要徹底阻止一個網頁的內容列在搜索引擎索引中(即便有其餘網站連接到此網頁),可以使用 noindex 元標記。只要搜索引擎查看該網頁,便會看到 noindex 元標記並阻止該網頁顯示在索引中,這裏注意noindex元標記提供的是一種逐頁控制對網站的訪問的方式。
舉例:
要防止全部搜索引擎將網站中的網頁編入索引,在網頁的
部分添加:
<meta name="robots" content="noindex">
這裏的name取值能夠設置爲某個搜索引擎的User-agent從而指定屏蔽某一個搜索引擎。
除了noindex外,還有其餘元標記,好比說nofollow,禁止爬蟲今後頁面中跟蹤連接。詳細信息能夠參考Google支持的元標記,這裏提一句:noindex和nofollow在HTML 4.01規範裏有描述,可是其餘tag的在不一樣引擎支持到什麼程度各不相同,還請讀者自行查閱各個引擎的說明文檔。
Crawl-delay
除了控制哪些能夠抓哪些不能抓以外,robots.txt還能夠用來控制爬蟲抓取的速率。如何作到的呢?經過設置爬蟲在兩次抓取之間等待的秒數。
Crawl-delay:5
表示本次抓取後下一次抓取前須要等待5秒。
注意:google已經不支持這種方式了,在webmaster tools裏提供了一個功能能夠更直觀的控制抓取速率。
這裏插一句題外話,幾年前我記得曾經有一段時間robots.txt還支持複雜的參數:Visit-time,只有在visit-time指定的時間段裏,爬蟲才能夠訪問;Request-rate: 用來限制URL的讀取頻率,用於控制不一樣的時間段採用不一樣的抓取速率。後來估計支持的人太少,就漸漸的廢掉了,有興趣的同窗能夠自行google。我瞭解到的是目前google和baidu都已經不支持這個規則了,其餘小的引擎公司貌似歷來都沒有支持過。若是確有支持那是我孤陋寡聞了,歡迎留言告知。
真的有用?
好吧,到此爲止robots.txt相關的東東介紹的也七七八八了,能堅持看到這裏的同窗估計都躍躍欲試了,惋惜,我要潑盆冷水,能徹底期望robots.txt保護咱們網站的內容嗎?不必定。不然百度和360就不用打官司了。
協議一致性
第一個問題是robots.txt沒有一個正式的標準,各個搜索引擎都在不斷的擴充robots.txt功能,這就致使每一個引擎對robots.txt的支持程度各有不一樣,更不用說在某個功能上的具體實現的不一樣了。
緩存
第二個問題是robots.txt自己也是須要抓取的,出於效率考慮,通常爬蟲不會每次抓取網站網頁前都抓一下robots.txt,加上robots.txt更新不頻繁,內容須要解析。一般爬蟲的作法是先抓取一次,解析後緩存下來,並且是至關長的時間。假設網站管理員更新了robots.txt,修改了某些規則,可是對爬蟲來講並不會馬上生效,只有當爬蟲下次抓取robots.txt以後才能看到最新的內容。尷尬的是,爬蟲下次抓取robots.txt的時間並非由網站管理員控制的。固然,有些搜索引擎提供了web 工具可讓網站管理員通知搜索引擎那個url發生了變化,建議從新抓取。注意,此處是建議,即便你通知了搜索引擎,搜索引擎什麼時候抓取仍然是不肯定的,只是比徹底不通知要好點。至於好多少,那就看搜索引擎的良心和技術能力了。
ignore
第三個問題,不知是無心仍是有意,反正有些爬蟲不太遵照或者徹底忽略robots.txt,不排除開發人員能力的問題,好比說根本不知道robots.txt。另外,自己robots.txt不是一種強制措施,若是網站有數據須要保密,必需採起技術措施,好比說:用戶驗證,加密,ip攔截,訪問頻率控制等。
偷偷的抓
第四個問題,即便採用了種種限制,仍然存在某些惡意的抓取行爲能突破這些限制,好比一些利用肉雞進行的抓取。悲觀的說,只要普通用戶能夠訪問,就不能徹底杜絕這種惡意抓取的行爲。可是,能夠經過種種手段使抓取的代價增大到讓對方沒法接受。好比說:Captcha, Ajax用戶行爲驅動的異步加載等等。這個就不屬於本文討論的範疇了。
泄密
最後,robots.txt自己還存在泄密的風險。舉例,若是某一個網站的robots.txt裏忽然新增了一條:Disallow /map/,你想到了什麼?是否是要推出地圖服務了?因而有好奇心的同窗就會開始嘗試各類文件名去訪問該路徑下的文件,但願能看到驚喜。貌似當初google的地圖就是這麼被提早爆出來的,關於這點我不太肯定,你們就當八卦聽聽好了。有興趣的同窗能夠參考用robots.txt探索Google Baidu隱藏的祕密
工具
當你輸入一個網址的時候,實際會發生什麼? - 博客 - 伯樂在線 (2013/2/27 8:36:14)
英文原文:What really happens when you navigate to a URL,編譯:寒冬星空
做爲一個軟件開發者,你必定會對網絡應用如何工做有一個完整的層次化的認知,一樣這裏也包括這些應用所用到的技術:像瀏覽器,HTTP,HTML,網絡服務器,需求處理等等。
本文將更深刻的研究當你輸入一個網址的時候,後臺到底發生了一件件什麼樣的事~
1. 首先嘛,你得在瀏覽器裏輸入要網址:
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
2. 瀏覽器查找域名的IP地址
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
導航的第一步是經過訪問的域名找出其IP地址。DNS查找過程以下:
- 瀏覽器緩存 – 瀏覽器會緩存DNS記錄一段時間。 有趣的是,操做系統沒有告訴瀏覽器儲存DNS記錄的時間,這樣不一樣瀏覽器會儲存個自固定的一個時間(2分鐘到30分鐘不等)。
- 系統緩存 – 若是在瀏覽器緩存裏沒有找到須要的記錄,瀏覽器會作一個系統調用(windows裏是gethostbyname)。這樣即可得到系統緩存中的記錄。
- 路由器緩存 – 接着,前面的查詢請求發向路由器,它通常會有本身的DNS緩存。
- ISP DNS 緩存 – 接下來要check的就是ISP緩存DNS的服務器。在這通常都能找到相應的緩存記錄。
- 遞歸搜索 – 你的ISP的DNS服務器從跟域名服務器開始進行遞歸搜索,從.com頂級域名服務器到Facebook的域名服務器。通常DNS服務器的緩存中會有.com域名服務器中的域名,因此到頂級服務器的匹配過程不是那麼必要了。
DNS遞歸查找以下圖所示:
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
DNS有一點使人擔心,這就是像wikipedia.org 或者 facebook.com這樣的整個域名看上去只是對應一個單獨的IP地址。還好,有幾種方法能夠消除這個瓶頸:
- 循環 DNS 是DNS查找時返回多個IP時的解決方案。舉例來講,Facebook.com實際上就對應了四個IP地址。
- 負載平衡器 是以一個特定IP地址進行偵聽並將網絡請求轉發到集羣服務器上的硬件設備。 一些大型的站點通常都會使用這種昂貴的高性能負載平衡器。
- 地理 DNS 根據用戶所處的地理位置,經過把域名映射到多個不一樣的IP地址提升可擴展性。這樣不一樣的服務器不可以更新同步狀態,但映射靜態內容的話很是好。
- Anycast 是一個IP地址映射多個物理主機的路由技術。 美中不足,Anycast與TCP協議適應的不是很好,因此不多應用在那些方案中。
大多數DNS服務器使用Anycast來得到高效低延遲的DNS查找。
3. 瀏覽器給web服務器發送一個HTTP請求
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
由於像Facebook主頁這樣的動態頁面,打開後在瀏覽器緩存中很快甚至立刻就會過時,毫無疑問他們不能從中讀取。
因此,瀏覽器將把一下請求發送到Facebook所在的服務器:
GET http://facebook.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: facebook.com
Cookie: datr=1265876274-[...]; locale=en_US; lsd=WW[...]; c_user=2101[...]
GET 這個請求定義了要讀取的URL: 「http://facebook.com/」。 瀏覽器自身定義 (User-Agent 頭), 和它但願接受什麼類型的相應 (Accept and Accept-Encoding 頭). Connection頭要求服務器爲了後邊的請求不要關閉TCP鏈接。
請求中也包含瀏覽器存儲的該域名的cookies。可能你已經知道,在不一樣頁面請求當中,cookies是與跟蹤一個網站狀態相匹配的鍵值。這樣cookies會存儲登陸用戶名,服務器分配的密碼和一些用戶設置等。Cookies會以文本文檔形式存儲在客戶機裏,每次請求時發送給服務器。
用來看原始HTTP請求及其相應的工具不少。做者比較喜歡使用fiddler,固然也有像FireBug這樣其餘的工具。這些軟件在網站優化時會幫上很大忙。
除了獲取請求,還有一種是發送請求,它常在提交表單用到。發送請求經過URL傳遞其參數(e.g.: http://robozzle.com/puzzle.aspx?id=85)。發送請求在請求正文頭以後發送其參數。
像「http://facebook.com/」中的斜槓是相當重要的。這種狀況下,瀏覽器能安全的添加斜槓。而像「http: //example.com/folderOrFile」這樣的地址,由於瀏覽器不清楚folderOrFile究竟是文件夾仍是文件,因此不能自動添加 斜槓。這時,瀏覽器就不加斜槓直接訪問地址,服務器會響應一個重定向,結果形成一次沒必要要的握手。
4. facebook服務的永久重定向響應
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
圖中所示爲Facebook服務器發回給瀏覽器的響應:
HTTP/1.1 301 Moved Permanently
Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
pre-check=0
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Location: http://www.facebook.com/
P3P: CP="DSP LAW"
Pragma: no-cache
Set-Cookie: made_write_conn=deleted; expires=Thu, 12-Feb-2009 05:09:50 GMT;
path=/; domain=.facebook.com; httponly
Content-Type: text/html; charset=utf-8
X-Cnection: close
Date: Fri, 12 Feb 2010 05:09:51 GMT
Content-Length: 0
服務器給瀏覽器響應一個301永久重定向響應,這樣瀏覽器就會訪問「http://www.facebook.com/」 而非「http://facebook.com/」。
爲何服務器必定要重定向而不是直接發會用戶想看的網頁內容呢?這個問題有好多有意思的答案。
其中一個緣由跟搜索引擎排名有 關。你看,若是一個頁面有兩個地址,就像http://www.igoro.com/ 和http://igoro.com/,搜索引擎會認爲它們是兩個網站,結果形成每個的搜索連接都減小從而下降排名。而搜索引擎知道301永久重定向是 什麼意思,這樣就會把訪問帶www的和不帶www的地址歸到同一個網站排名下。
還有一個是用不一樣的地址會形成緩存友好性變差。當一個頁面有好幾個名字時,它可能會在緩存裏出現好幾回。
5. 瀏覽器跟蹤重定向地址
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
如今,瀏覽器知道了「http://www.facebook.com/」纔是要訪問的正確地址,因此它會發送另外一個獲取請求:
GET http://www.facebook.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Cookie: lsd=XW[...]; c_user=21[...]; x-referer=[...]
Host: www.facebook.com
頭信息以以前請求中的意義相同。
6. 服務器「處理」請求
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
服務器接收到獲取請求,而後處理並返回一個響應。
這表面上看起來是一個順向的任務,但其實這中間發生了不少有意思的東西- 就像做者博客這樣簡單的網站,況且像facebook那樣訪問量大的網站呢!
- Web 服務器軟件
web服務器軟件(像IIS和阿帕奇)接收到HTTP請求,而後肯定執行什麼請求處理來處理它。請求處理就是一個可以讀懂請求而且能生成HTML來進行響應的程序(像ASP.NET,PHP,RUBY…)。舉 個最簡單的例子,需求處理能夠以映射網站地址結構的文件層次存儲。像http://example.com/folder1/page1.aspx這個地 址會映射/httpdocs/folder1/page1.aspx這個文件。web服務器軟件能夠設置成爲地址人工的對應請求處理,這樣 page1.aspx的發佈地址就能夠是http://example.com/folder1/page1。
- 請求處理
請求處理閱讀請求及它的參數和cookies。它會讀取也可能更新一些數據,並講數據存儲在服務器上。而後,需求處理會生成一個HTML響應。
所 有動態網站都面臨一個有意思的難點 -如何存儲數據。小網站一半都會有一個SQL數據庫來存儲數據,存儲大量數據和/或訪問量大的網站不得不找一些辦法把數據庫分配到多臺機器上。解決方案 有:sharding (基於主鍵值講數據表分散到多個數據庫中),複製,利用弱語義一致性的簡化數據庫。
委 託工做給批處理是一個廉價保持數據更新的技術。舉例來說,Fackbook得及時更新新聞feed,但數據支持下的「你可能認識的人」功能只須要每晚更新 (做者猜想是這樣的,改功能如何完善不得而知)。批處理做業更新會致使一些不過重要的數據陳舊,但能使數據更新耕做更快更簡潔。
7. 服務器發回一個HTML響應
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
圖中爲服務器生成並返回的響應:
HTTP/1.1 200 OK
Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
pre-check=0
Expires: Sat, 01 Jan 2000 00:00:00 GMT
P3P: CP="DSP LAW"
Pragma: no-cache
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
X-Cnection: close
Transfer-Encoding: chunked
Date: Fri, 12 Feb 2010 09:05:55 GMT
2b3Tn@[...]
整個響應大小爲35kB,其中大部分在整理後以blob類型傳輸。
內容編碼頭告訴瀏覽器整個響應體用gzip算法進行壓縮。解壓blob塊後,你能夠看到以下指望的HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
lang="en" id="facebook">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-language" content="en" />
...
關於壓縮,頭信息說明了是否緩存這個頁面,若是緩存的話如何去作,有什麼cookies要去設置(前面這個響應裏沒有這點)和隱私信息等等。
請注意報頭中把Content-type設置爲「text/html」。報頭讓瀏覽器將該響應內容以HTML形式呈現,而不是以文件形式下載它。瀏覽器會根據報頭信息決定如何解釋該響應,不過同時也會考慮像URL擴展內容等其餘因素。
8. 瀏覽器開始顯示HTML
在瀏覽器沒有完整接受所有HTML文檔時,它就已經開始顯示這個頁面了:
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
9. 瀏覽器發送獲取嵌入在HTML中的對象
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
在瀏覽器顯示HTML時,它會注意到須要獲取其餘地址內容的標籤。這時,瀏覽器會發送一個獲取請求來從新得到這些文件。
下面是幾個咱們訪問facebook.com時須要重獲取的幾個URL:
- 圖片
http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif http://static.ak.fbcdn.net/rsrc.php/zBS5C/hash/7hwy7at6.gif
…
- CSS 式樣表
http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css http://static.ak.fbcdn.net/rsrc.php/zANE1/hash/cvtutcee.css
…
- JavaScript 文件
http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js
http://static.ak.fbcdn.net/rsrc.php/z6R9L/hash/cq2lgbs8.js
…
這些地址都要經歷一個和HTML讀取相似的過程。因此瀏覽器會在DNS中查找這些域名,發送請求,重定向等等…
但 不像動態頁面那樣,靜態文件會容許瀏覽器對其進行緩存。有的文件可能會不須要與服務器通信,而從緩存中直接讀取。服務器的響應中包含了靜態文件保存的期限 信息,因此瀏覽器知道要把它們緩存多長時間。還有,每一個響應均可能包含像版本號同樣工做的ETag頭(被請求變量的實體值),若是瀏覽器觀察到文件的版本 ETag信息已經存在,就立刻中止這個文件的傳輸。
試着猜猜看「fbcdn.net」在地址中表明什麼?聰明的答案是」Facebook內容分發網絡」。Facebook利用內容分發網絡(CDN)分發像圖片,CSS表和JavaScript文件這些靜態文件。因此,這些文件會在全球不少CDN的數據中心中留下備份。
靜態內容每每表明站點的帶寬大小,也能經過CDN輕鬆的複製。一般網站會使用第三方的CDN。例如,Facebook的靜態文件由最大的CDN提供商Akamai來託管。
舉例來說,當你試着ping static.ak.fbcdn.net的時候,可能會從某個akamai.net服務器上得到響應。有意思的是,當你一樣再ping一次的時候,響應的服務器可能就不同,這說明幕後的負載平衡開始起做用了。
10. 瀏覽器發送異步(AJAX)請求
![當你輸入一個網址的時候,實際會發生什麼? 當你輸入一個網址的時候,實際會發生什麼?](http://static.javashuo.com/static/loading.gif)
在Web 2.0偉大精神的指引下,頁面顯示完成後客戶端仍與服務器端保持着聯繫。
以 Facebook聊天功能爲例,它會持續與服務器保持聯繫來及時更新你那些亮亮灰灰的好友狀態。爲了更新這些頭像亮着的好友狀態,在瀏覽器中執行的 JavaScript代碼會給服務器發送異步請求。這個異步請求發送給特定的地址,它是一個按照程式構造的獲取或發送請求。仍是在Facebook這個例 子中,客戶端發送給http://www.facebook.com/ajax/chat/buddy_list.php一個發佈請求來獲取你好友裏哪一個 在線的狀態信息。
提起這個模式,就必需要講講」AJAX」– 「異步JavaScript 和 XML」,雖然服務器爲何用XML格式來進行響應也沒有個一清二白的緣由。再舉個例子吧,對於異步請求,Facebook會返回一些JavaScript的代碼片斷。
除了其餘,fiddler這個工具可以讓你看到瀏覽器發送的異步請求。事實上,你不只能夠被動的作爲這些請求的看客,還能主動出擊修改和從新發送它們。AJAX請求這麼容易被蒙,可着實讓那些計分的在線遊戲開發者們鬱悶的了。(固然,可別那樣騙人家~)
Facebook聊天功能提供了關於AJAX一個有意思的問題案例:把數據從服務器端推送到客戶端。由於HTTP是一個請求-響應協議,因此聊天服務器不能把新消息發給客戶。取而代之的是客戶端不得不隔幾秒就輪詢下服務器端看本身有沒有新消息。
這些狀況發生時長輪詢是個減輕服務器負載挺有趣的技術。若是當被輪詢時服務器沒有新消息,它就不理這個客戶端。而當還沒有超時的狀況下收到了該客戶的新消息,服務器就會找到未完成的請求,把新消息作爲響應返回給客戶端。
總結一下
但願看了本文,你能明白不一樣的網絡模塊是如何協同工做的