創業公司工程師應該掌握的可伸縮Web開發技術

csdn發表於2015-10-29

  近些年來,越來越多的行業開始和網際網路結合,誕生了越來越多的網際網路創業公司。網際網路創業公司需要面對許多的不確定因素。如果你和你的小夥伴們夠幸運,你們的公司可能會在幾個星期之內讓使用者數、商品數、訂單量增長几十倍上百倍。一次促銷可能會帶來平時幾十倍的訪問流量,一次秒殺活動可能會吸引平時數百倍的訪問使用者。這對公司自然是極大的好事,說明產品得到認可,公司未來前景美妙。

  但是快速增長的使用者和訂單卻對公司的技術提出極大的挑戰。受計算資源本身的限制,一臺伺服器能啟動的執行緒數、能儲存的資料,每秒鐘能完成的計算、能讀寫的資料、能傳輸的資料都是有限的。而系統處理每一個使用者請求都需要消耗一定的計算資源,當大量的使用者同時來訪問系統的時候,會出現因計算資源不足而導致的響應延遲以及超時出錯,當併發訪問使用者超過某個極限,甚至會導致伺服器當機,整個網站不可訪問的慘劇。

  當公司正在為使用者增加訂單量上升而慶祝的時候,卻傳來系統崩潰網站不可訪問的噩耗。喜劇變成悲劇,慶祝會變成批鬥會,作為負責公司技術的工程師,作為批鬥會的主角,你,是否會覺得壓力山大。

  本文面向創業公司的工程師,介紹可伸縮的Web開發技術。伸縮性是指系統可以根據需求和成本調整自身處理能力的一種特性。伸縮性意味著系統可以改變自身的處理能力以滿足更多使用者訪問處理更多資料而不會對使用者體驗造成任何影響。

  一、構建可伸縮的Web架構

  網際網路創業的一個特點是開始的時候規模都很小,幾個人的小團隊,少量的啟動資金,就開始創業了。Google是從史丹佛的實驗室開始創業的,Facebook是從哈佛的宿舍裡開始創業的,Alibaba是從馬雲家的客廳開始創業的。剛開始的時候,使用者也少,所以只要一臺伺服器就可以應付所有的使用者訪問,這時整個Web系統架構如圖1。資料庫、Web應用、檔案服務都部署在一臺伺服器上。

創業公司工程師應該掌握的可伸縮Web開發技術

圖1 網際網路創業早期最簡單的Web系統架構

  如果創業方向正確,產品解決使用者痛點,能為社會創造價值,就會有更多使用者來訪問網站。這時,Web系統受計算資源不足影響,會出現響應延遲,打不開網站等情況。解決方法有兩種,一種方法是使用更強大計算能力的計算機,另一種方法是使用更多的計算機。第一種方法主要問題在於再強大的計算機也都有資源限制,而一個成功的網站的終極目標是服務全世界,隨著網站的發展,不管多強大的計算機遲早也會遇到計算資源不足的問題;而且越強大的計算機其價格也越昂貴,這也是剛剛起步的創業公司不能承受的。所以幾乎所有的網際網路公司都選擇了第二種方法,即構建一個彈性可伸縮的Web系統,通過逐步向系統中增加伺服器從而提高整個系統的計算處理能力。

  增加伺服器的一個基本手段是將不同的服務部署在不同的伺服器上,應用伺服器,資料庫伺服器,檔案伺服器獨立部署,如圖2。

創業公司工程師應該掌握的可伸縮Web開發技術

圖2 進行簡單拆分獨立部署的Web系統架構

  此外,還可以將不同的模組拆分到不同的伺服器。比如一個電子商務網站,商城、論壇、賣家這些相對獨立的模組可以獨立部署,即使在商城系統內部,首頁、商品列表、商品詳情、訂單等子模組也可以進一步獨立部署,如圖3。

創業公司工程師應該掌握的可伸縮Web開發技術

圖3 按功能模組進一步拆分獨立部署的Web系統架構

  事實上隨著業務不斷髮展,網站需要使用更多的服務,快取、訊息佇列、搜尋、NoSQL、反向代理等,還需要將靜態內容服務從應用伺服器中分離出來,以及使用CDN(內容分發網路)進行靜態內容訪問加速。這些服務都應該部署在獨立的伺服器上,通過使用更多的伺服器提高網站的整體處理能力。

  這些可以分拆的功能和服務雖然已經獨立部署,但是每個功能或者服務如果只能部署在一臺伺服器上,能夠提供的計算能力以及能夠處理的併發訪問依然有限。解決方法是通過叢集的方式將單一服務部署在多臺伺服器上,從而提供更強大的處理能力,如圖4。

創業公司工程師應該掌握的可伸縮Web開發技術

圖4 叢集部署的Web系統架構 

  總之,可伸縮網站架構的核心思路就是通過分拆叢集等手段向Web系統中新增各種伺服器,為系統提供更多計算、儲存、傳輸能力,這些伺服器能有效分擔系統訪問壓力,使Web系統能夠支撐更多使用者訪問、儲存更多資料而不至於影響使用者體驗。

  二、使用可伸縮的基礎技術產品

  前面提到,單一服務或者應用需要通過叢集的方式提供更強大的計算處理能力。叢集即多臺伺服器部署相同應用或服務構成一個伺服器群統一對外提供服務。如果有更多使用者訪問,需要處理更多併發訪問請求的時候,只需要向叢集中新增新的伺服器即可。這就要求服務或應用本身具有可伸縮性。

  1. 通過負載均衡實現應用伺服器可伸縮

  應用伺服器一般指部署核心業務邏輯,主要處理使用者請求的伺服器。應用通常設計成無狀態結構,即應用本身不記錄使用者請求的上下文資訊,這樣設計的好處是任何使用者的任何一次請求都可以交給任何一個應用伺服器去處理。實踐中,一般通過負載均衡伺服器將一組應用伺服器構建成一個叢集,如圖5。

創業公司工程師應該掌握的可伸縮Web開發技術

圖5 通過負載均衡實現應用伺服器可伸縮(圖片來源《大型網站技術架構:核心原理與案例分析》)

  首先在負載均衡伺服器上配置所有的應用伺服器資訊,使用者請求先到達負載均衡伺服器,負載均衡伺服器通過某種負載均衡演算法計算得到一個應用伺服器的網路地址,然後將請求資料包轉發給這個應用伺服器,由該伺服器完成使用者請求處理。如果使用者數增加,併發請求超過現有叢集的處理能力,只需要在現有應用伺服器叢集中增加伺服器,在負載均衡伺服器上增加新的伺服器配置資訊,部分使用者請求就會轉發到新增伺服器上,實現分擔叢集訪問壓力的目的。
負載均衡伺服器的實現有很多種,DNS負載均衡、HTTP重定向負載均衡,HTTP轉發負載均衡、IP層負載均衡、資料鏈路層負載均衡等,實踐中,中小網站多使用Nginx等反向代理伺服器實現HTTP轉發負載均衡,而規模稍大以後則基本都使用LVS實現IP層負載均衡或者資料鏈路層負載均衡。目前越來越多的網站使用雲服務部署網站,這些雲服務也提供負載均衡服務,背後使用的技術依然是LVS或者HTTP轉發。

  2. 通過遠端分散式快取實現快取可伸縮

  快取是改善網站效能的最重要手段,一方面快取使用記憶體儲存資料,可以更快速地響應請求;另一方面大量資料訪問請求通過快取返回,減少資料庫壓力,進一步改善效能。目前網站中大量使用的快取服務是Memcached或者Redis。Memcached分散式快取訪問模型如圖6。

創業公司工程師應該掌握的可伸縮Web開發技術

圖6 Memcached分散式快取訪問模型 (圖片來源《大型網站技術架構:核心原理與案例分析》)

  應用程式通過Memcached客戶端訪問Memcached伺服器叢集,其中路由演算法模組負責根據應用程式輸入的KEY計算得到應該訪問哪臺伺服器,然後通過通訊模組從對應伺服器上讀寫資料。

  如果Memecahed叢集需要快取更多資料或者需要提供更高的併發訪問,只需要向叢集中增加新的伺服器,然後修改客戶端伺服器列表即可應用程式訪問到新加的伺服器。

  需要注意的是如果路由演算法選擇不當,比如使用餘數Hash演算法,會出現加入一臺伺服器而導致現有的快取資料大量訪問不能命中的情況,其後果相當於快取伺服器叢集整體當機,給系統帶來災難性後果。目前Memcached主要採用一致性Hash演算法,這種演算法可以使加入新伺服器對現有資料訪問影響最小。而Redis通過一種類似虛擬節點的對映演算法也可以達到相似的效果。

  3. 通過主從複製和分散式資料庫實現資料庫可伸縮

  目前各種網站主要使用的關聯式資料庫是MySQL,MySQL支援資料複製功能,使用這個功能可以對資料庫進行簡單的伸縮。圖7為使用資料複製的MySQL叢集伸縮性方案。

創業公司工程師應該掌握的可伸縮Web開發技術

圖7 通過主從複製實現簡單伸縮性的MySQL叢集 (圖片來源《大型網站技術架構:核心原理與案例分析》)

  在這個方案中,雖然多臺伺服器部署MySQL例項,但是他們的角色有主從之分,資料寫操作都在主伺服器上,由主伺服器將資料同步到叢集中其他從伺服器,資料讀操作及資料分析等離線操作在從伺服器上進行。

  主從複製只能通過增加有限的幾臺伺服器分擔資料庫的訪問壓力,如果資料庫需要記錄數千萬上億條記錄,需要應對每秒數十萬次訪問壓力,那麼主從複製是遠遠不夠的。這種情況下,可以考慮使用更具伸縮性的各種NoSQL資料庫產品,如HBase等,也可以考慮使用分散式資料庫。分散式關聯式資料庫則通過一個代理層將資料分片並經過路由後寫入一個關聯式資料庫叢集中。

  除了應用、快取、資料庫,其他的服務,諸如搜尋、訊息佇列等也可以以類似的思路和方案實現叢集可伸縮。

  三、打造可伸縮的技術團隊

  創業公司剛開始時,通常不過兩三個工程師,圍繞核心業務,開發一個簡單的版本就釋出上線開始運營了。隨著業務不斷髮展,伺服器數量必定是越來越多、技術越來越複雜,對應的,公司規模也是越來越大,工程師團隊越來越多人。一般說來,一家網際網路公司能做到上市,工程師團隊的人數大概從數百人到數千人不等,技術團隊規模和創業時相比擴大數百倍。這就要求必須有效組織工程師團隊,打造可伸縮的技術團隊,使技術團隊的成長和公司業務成長、技術水平進步保持一致。

  1. 團隊拆分

  制約一個團隊人數規模的主要因素是溝通路徑,溝通路徑越多,資訊傳遞越慢,傳遞過程中引入的噪音越多,團隊越趨於混亂。一個5人團隊,溝通路徑是10=(5*4)/2,一個9人團隊,溝通路徑是36=(9*8)/2,溝通路徑隨團隊規模呈指數級增長。所以當技術團隊人數增長到一定規模,和構建可伸縮的Web架構中需要對服務進行拆分一樣,需要對團隊進行拆分,將一個大團隊拆分成幾個小團隊,使每個小的團隊保持一個比較少的人數。

  團隊拆分有兩種方案,一種是按職能拆分,前端工程師、後端工程師、測試工程師、運維工程師、資料倉儲工程師各種工程師分別構成一個個的小團隊,這種拆分的好處是團隊結構比較穩定,團隊成員都是使用同樣技術的“自己人”,團隊內部溝通交流更快速高效;帶來的問題是開發過程是按照產品和專案組織的,而開發一個產品需要用到前端、後端、測試、運維各種工程師,開發過程會遇到各種跨團隊的交流與合作,帶來更多的溝通成本。另一種是按照產品和專案拆分,團隊圍繞產品展開,每個團隊內部擁有開發維護一個產品所需的各種技術角色,從開發到測試釋出運維都在團隊內部搞定,不需要太多跨團隊合作,這種拆分也存在一些問題,特別是創業公司早期,產品不穩定,管理層決定要上一個新產品,於是迅速招人開發,但是很多時候產品剛上線不久甚至還沒上線,管理層的決定又有變化,產品不做了,團隊解散,這種朝令夕改會對技術團隊造成較大傷害,所以某些網際網路公司特別將“擁抱變化”上升到公司價值觀高度,讓員工對這種情況做好心理準備。

  對於公司而言,前一種方案帶來的問題是溝通低效、人員冗餘、開發進展緩慢;後一種方案帶來的問題是員工情緒低落影響士氣。顯然前一種方案對公司發展影響更大,所以實踐中,更多公司採用後一種團隊組織方式。為了應對這種方案帶來的消極影響,公司會積極組織各種培(xi)訓(nao),提供各種員工福利員工關懷,讓員工忘記各種不快,投入到下一個產品開發中。不過對創業公司而言,從本質上,員工利益和公司利益是一致的,只有公司活下去、做大做強,所有人才能更好的獲益,不過這也要求創業公司儘可能做到決策透明,讓所有員工能理解管理層的決定,並自覺維護、執行管理層的決定。

  2. 保持敏捷

  創業團隊白手起家,不但表現在缺資金缺使用者缺人才,也表現在缺管理缺標準缺規範,於是採用各種“野路子”的管理手段。但是公司發展到一定規模,這些手段就開始捉襟見肘,出現各種問題,於是公司開始從各種名企外企引入各類『管理人才』,進行規範化管理。不過在這個規範化的過程中,有時候會出現某種矯枉過正,導致公司僵化笨拙,還沒成為大公司卻得了一堆大公司的病。

  舉兩個極端但是真實的例子。某公司要求程式碼單元測試覆蓋率必須達到一定比率,並且寫了工具專門掃描工程師提交的程式碼是否達到要求的單元測試覆蓋率,於是就看到有些工程師為getXXX和setXXX方法寫測試用例。某公司要求設計階段必須寫設計文件,並提供了設計文件模板,這個模板有一章叫做『資料庫設計』,某個專案不需要資料庫,因此設計文件不通過評審,為此工程師不得不設計了一個永遠不會用到的資料庫。

某位偉人曾經說過:教條不如狗屎,狗屎可以肥田,教條屁用沒有。有些『管理人員』自己不曾在一線實踐過,卻為一線人員制定各種規章制度,效果可想而知。對創業公司而言,最好的管理不是流程規範,而是最佳實踐。某個專案迭代管理做得好,某個專案設計文件寫得好,拿來在全公司分享,大家一起學習改進,在實踐中提高,產生更好的實踐繼續分享。從實踐中來到實踐中去,而不是從PPT來到Word中去。

  總結

  本文限於篇幅,概要描述了Web應用可伸縮架構技術,期望創業公司工程師在創業早期就能明瞭網站技術發展的一般模式,更好地規劃自己公司的技術發展道路。關於網站可伸縮架構的更多技術細節,可以根據這篇文章提到的技術點按圖索驥閱讀更多資料,更重要的當然是在實踐中學習,隨著公司逐步壯大,自己也逐漸成長為網站技術方面的卓越人才。期待未來最偉大的網際網路公司出現在中國,期待未來最頂尖的網際網路技術人才出現在本文的讀者當中,祝福大家。

  來源:《程式設計師》雜誌  作者:李智慧

相關文章