漫談互聯網架構

互聯網的標準技術架構以下圖所示,這張圖基本上涵蓋了互聯網技術公司的大部分技術點,不一樣的公司只是在具體的技術實現上稍有差別,但不會跳出這個框架的範疇。程序員

存儲層技術SQL正則表達式

SQL即咱們一般所說的關係數據。前幾年NoSQL火了一陣子,不少人都理解爲NoSQL是徹底拋棄關係數據,所有采用非關係型數據。但通過幾年的試驗後,你們發現關係數據不可能徹底被拋棄,NoSQL不是No SQL,而是Not Only SQL,即NoSQL是SQL的補充。數據庫

因此互聯網行業也必須依賴關係數據,考慮到Oracle太貴,還須要專人維護,通常狀況下互聯網行業都是用MySQL、PostgreSQL這類開源數據庫。這類數據庫的特色是開源免費,拿來就用;但缺點是性能相比商業數據庫要差一些。隨着互聯網業務的發展,性能要求愈來愈高,必然要面對一個問題:將數據拆分到多個數據庫實例才能知足業務的性能需求(其實Oracle也同樣,只是時間遲早的問題)。後端

數據庫拆分知足了性能的要求,但帶來了複雜度的問題:數據如何拆分、數據如何組合?這個複雜度的問題解決起來並不容易,若是每一個業務都去實現一遍,重複造輪子將致使投入浪費、效率下降,業務開發想快都快不起來。設計模式

因此互聯網公司流行的作法是業務發展到必定階段後,就會將這部分功能獨立成中間件,例如百度的DBProxy、淘寶的TDDL。不過這部分的技術要求很高,將分庫分表作到自動化和平臺化,不是一件容易的事情,因此通常是規模很大的公司纔會本身作。中小公司建議使用開源方案,例如MySQL官方推薦的MySQL Router、360開源的數據庫中間件Atlas。瀏覽器

假如公司業務繼續發展,規模繼續擴大,SQL服務器愈來愈多,若是每一個業務都基於統一的數據庫中間件獨立部署本身的SQL集羣,就會致使新的複雜度問題,具體表如今:緩存

  • 數據庫資源使用率不高,比較浪費。
  • 各SQL集羣分開維護,投入的維護成本愈來愈高。

所以,實力雄厚的大公司此時通常都會在SQL集羣上構建SQL存儲平臺,以對業務透明的形式提供資源分配、數據備份、遷移、容災、讀寫分離、分庫分表等一系列服務,例如淘寶的UMP(Unified MySQL Platform)系統。安全

NoSQL服務器

首先NoSQL在數據結構上與傳統的SQL的不一樣,例如典型的Memcache的key-value結構、Redis的複雜數據結構、MongoDB的文檔數據結構;其次,NoSQL無一例外地都會將性能做爲本身的一大賣點。NoSQL的這兩個特色很好地彌補了關係數據庫的不足,所以在互聯網行業NoSQL的應用基本上是基礎要求。微信

因爲NoSQL方案通常本身自己就提供集羣的功能,例如Memcache的一致性Hash集羣、Redis 3.0的集羣,所以NoSQL在剛開始應用時很方便,不像SQL分庫分表那麼複雜。通常公司也不會在開始時就考慮將NoSQL包裝成存儲平臺,但若是公司發展很快,例如Memcache的節點有上千甚至幾千時,NoSQL存儲平臺就頗有意義了。首先是存儲平臺經過集中管理可以大大提高運維效率;其次是存儲平臺能夠大大提高資源利用效率,2000臺機器,若是利用率能提高10%,就能夠減小200臺機器,一年幾十萬元就節省出來了。

因此,NoSQL發展到必定規模後,一般都會在NoSQL集羣的基礎之上再實現統一存儲平臺,統一存儲平臺主要實現這幾個功能:

  • 資源動態按需動態分配:例如同一臺Memcache服務器,能夠根據內存利用率,分配給多個業務使用。
  • 資源自動化管理:例如新業務只須要申請多少Memcache緩存空間就能夠了,無需關注具體是哪些Memcache服務器在爲本身提供服務。
  • 故障自動化處理:例如某臺Memcache服務器掛掉後,有另一臺備份Memcache服務器能馬上接管緩存請求,不會致使丟失不少緩存數據。

固然要發展到這個階段,通常也是大公司纔會這麼作,簡單來講就是若是隻有幾十臺NoSQL服務器,作存儲平臺收益不大;但若是有幾千臺NoSQL服務器,NoSQL存儲平臺就可以產生很大的收益。

小文件存儲

除了關係型的業務數據,互聯網行業還有不少用於展現的數據。例如,淘寶的商品圖片、商品描述;Facebook的用戶圖片;新浪微博的一條微博內容等。這些數據具備三個典型特徵:一是數據小,通常在1MB如下;二是數量巨大,Facebook在2013年天天上傳的照片就達到了3.5億張;三是訪問量巨大,Facebook天天的訪問量超過10億。

因爲互聯網行業基本上每一個業務都會有大量的小數據,若是每一個業務都本身去考慮如何設計海量存儲和海量訪問,效率天然會低,重複造輪子也會投入浪費,因此天然而然就要將小文件存儲作成統一的和業務無關的平臺。

和SQL和NoSQL不一樣的是,小文件存儲不必定須要公司或者業務規模很大,基本上認爲業務在起步階段就能夠考慮作小文件統一存儲。得益於開源運動的發展和最近幾年大數據的火爆,在開源方案的基礎上封裝一個小文件存儲平臺並非太難的事情。例如,HBase、Hadoop、Hypertable、FastDFS等均可以做爲小文件存儲的底層平臺,只須要將這些開源方案再包裝一下基本上就能夠用了。

典型的小文件存儲有:淘寶的TFS、京東JFS、Facebook的Haystack。

下圖是淘寶TFS的架構:

大文件存儲

互聯網行業的大文件主要分爲兩類:一類是業務上的大數據,例如Youtube的視頻、電影網站的電影;另外一類是海量的日誌數據,例如各類訪問日誌、操做日誌、用戶軌跡日誌等。和小文件的特色正好相反,大文件的數量沒有小文件那麼多,但每一個文件都很大,幾百MB、幾個GB都是常見的,幾十GB、幾TB也是有可能的,所以在存儲上和小文件有較大差異,不能直接將小文件存儲系統拿來存儲大文件。

說到大文件,特別要提到Google和Yahoo,Google的3篇大數據論文(Bigtable/Map- Reduce/GFS)開啓了一個大數據的時代,而Yahoo開源的Hadoop系列(HDFS、HBase等),基本上壟斷了開源界的大數據處理。

對照Google的論文構建一套完整的大數據處理方案的難度和成本實在過高,並且開源方案如今也很成熟了,因此大數據存儲和處理這塊反而是最簡單的,由於你沒有太多選擇,只能用這幾個流行的開源方案,例如,Hadoop、HBase、Storm、Hive等。實力雄厚一些的大公司會基於這些開源方案,結合本身的業務特色,封裝成大數據平臺,例如淘寶的雲梯系統、騰訊的TDW系統。

下面是Hadoop的生態圈:

開發層技術開發框架

互聯網業務發展有一個特色:複雜度愈來愈高。複雜度增長的典型現象就是系統愈來愈多,不一樣的系統由不一樣的小組開發。若是每一個小組用不一樣的開發框架和技術,則會帶來不少問題,典型的問題有:

  • 技術人員之間沒有共同的技術語言,交流合做少。
  • 每類技術都須要投入大量的人力和資源並熟練精通。
  • 不一樣團隊之間人員沒法快速流動,人力資源不能高效的利用。

因此,互聯網公司都會指定一個大的技術方向,而後使用統一的開發框架。例如,Java相關的開發框架SSH、SpringMVC、Play,Ruby的Ruby on Rails,PHP的ThinkPHP,Python的Django等。使用統一的開發框架可以解決上面提到的各類問題,大大提高組織和團隊的開發效率。

對於框架的選擇,有一個總的原則:優選成熟的框架,避免盲目追逐新技術!

爲何呢?

  • 首先,成熟的框架資料文檔齊備,各類坑基本上都有人踩過了,遇到問題很容易經過搜索來解決。
  • 其次,成熟的框架受衆更廣,招聘時更加容易招到合適的人才。
  • 第三,成熟的框架更加穩定,不會出現大的變更,適合長期發展。

Web服務器

開發框架只是負責完成業務功能的開發,真正可以運行起來給用戶提供服務,還須要服務器配合。

獨立開發一個成熟的Web服務器,成本很是高,何況業界又有那麼多成熟的開源Web服務器,因此互聯網行業基本上都是「拿來主義」,挑選一個流行的開源服務器便可。大一點的公司,可能會在開源服務器的基礎上,結合本身的業務特色作二次開發,例如淘寶的Tengine,但通常公司基本上只須要將開源服務器摸透,優化一下參數,調整一下配置就差很少了。

選擇一個服務器主要和開發語言相關,例如,Java的有Tomcat、JBoss、Resin等,PHP/Python的用Nginx,固然最保險的就是用Apache了,什麼語言都支持。

你可能會擔憂Apache的性能之類的問題,其實不用過早擔憂這個,等到業務真的發展到Apache撐不住的時候再考慮切換也不遲,那時候你有的是錢,有的是人,有的是時間。

容器

容器是最近幾年纔開始火起來的,其中以Docker爲表明,在BAT級別的公司已經有較多的應用。例如,騰訊萬臺規模的Docker應用實踐、新浪微博紅包的大規模Docker集羣等。

傳統的虛擬化技術是虛擬機,解決了跨平臺的問題,但因爲虛擬機太龐大,啓動又慢,運行時太佔資源,在互聯網行業並無大規模應用;而Docker的容器技術,雖然沒有跨平臺,但啓動快,幾乎不佔資源,推出後馬上就火起來了,預計Docker類的容器技術將是技術發展的主流方向。

千萬不要覺得Docker只是一個虛擬化或者容器技術,它將在很大程度上改變目前的技術形勢:

  • 運維方式會發生革命性的變化:Docker啓動快,幾乎不佔資源,隨時啓動和中止,基於Docker打造自動化運維、智能化運維將成爲主流方式。
  • 設計模式會發生本質上的變化:啓動一個新的容器實例代價如此低,將鼓勵設計思路朝「微服務」的方向發展。

例如,一個傳統的網站包括登陸註冊、頁面訪問、搜索等功能,沒有用容器的狀況下,除非有特別大的訪問量,不然這些功能開始時都是集成在一個系統裏面的;有了容器技術後,一開始就能夠將這些功能按照服務的方式設計,避免後續訪問量增大時又要重構系統。

服務層技術

互聯網業務的不斷髮展帶來了複雜度的不斷提高,業務系統也愈來愈多,系統間相互依賴程度加深。好比說爲了完成A業務系統,可能須要B、C、D、E等十幾個其餘系統進行合做。從數學的角度進行評估,能夠發現系統間的依賴是呈指數級增加的:3個系統相互關聯的路徑爲3條,6個系統相互關聯的路徑爲15條。

服務層的主要目標其實就是爲了下降系統間相互關聯的複雜度。

配置中心

故名思議,配置中心就是集中管理各個系統的配置。

當系統數量很少的時候,通常是各系統本身管理本身的配置,但系統數量多了之後,這樣的處理方式會有問題:

  • 某個功能上線時,須要多個系統配合一塊兒上線,分散配置時,配置檢查、溝通協調須要耗費較多時間。
  • 處理線上問題時,須要多個系統配合查詢相關信息,分散配置時,操做效率很低,溝通協調也須要耗費較多時間。
  • 各系統本身管理配置時,通常是經過文本編輯的方式修改的,沒有自動的校驗機制,容易配置錯誤,並且很難發現。

例如,我曾經遇到將IP地址的數字0誤敲成了鍵盤的字母O,肉眼很是難發現,但程序檢查其實就很容易。

實現配置中心主要就是爲了解決上面這些問題,將配置中心作成通用的系統的好處有:

  • 集中配置多個系統,操做效率高。
  • 全部配置都在一個集中的地方,檢查方便,協做效率高。
  • 配置中心能夠實現程序化的規則檢查,避免常見的錯誤。好比說檢查最小值、最大值、是否IP地址、是否URL地址,均可以用正則表達式完成。
  • 配置中心至關於備份了系統的配置,當某些狀況下須要搭建新的環境時,可以快速搭建環境和恢復業務。

整機磁盤壞掉、機器主板壞掉……遇到這些不可恢復的故障時,基本上只能從新搭建新的環境。程序包確定是已經有的,加上配置中心的配置,可以很快搭建新的運行環境,恢復業務。不然幾十個配置文件從新一個個去Vim中修改,耗時很長,還很容易出錯。

下面是配置中心簡單的設計,其中經過「系統標識 + host + port」來標識惟一一個系統運行實例是常見的設計方法。

服務中心

當系統數量很少的時候,系統間的調用通常都是直接經過配置文件記錄在各系統內部的,但當系統數量多了之後,這種方式就存在問題了。

好比說總共有10個系統依賴A系統的X接口,A系統實現了一個新接口Y,可以更好地提供原有X接口的功能,若是要讓已有的10個系統都切換到Y接口,則這10個系統的幾十上百臺機器的配置都要修改,而後重啓,可想而知這個效率是很低的。

除此之外,若是A系統總共有20臺機器,如今其中5臺出故障了,其餘系統若是是經過域名訪問A系統,則域名緩存失效前,仍是可能訪問到這5臺故障機器的;若是其餘系統經過IP訪問A系統,那麼A系統每次增長或者刪除機器,其餘全部10個系統的幾十上百臺機器都要同步修改,這樣的協調工做量也是很是大的。

服務中心就是爲了解決上面提到的跨系統依賴的「配置」和「調度」問題。

服務中心的實現通常來講有兩種方式:服務名字系統和服務總線系統。

  • 服務名字系統(Service Name System) 看到這個翻譯,相信你會馬上聯想到DNS,即Domain Name System。沒錯,二者的性質是基本相似的。DNS的做用將域名解析爲IP地址,主要緣由是咱們記不住太多的數字IP,域名就容易記住。服務名字系統是爲了將Service名稱解析爲「host + port + 接口名稱」,可是和DNS同樣,真正發起請求的仍是請求方。基本的設計以下:

  • 服務總線系統(Service Bus System) 看到這個翻譯,相信你可能馬上聯想到計算機的總線。沒錯,二者的本質也是基本相似的。 相比服務名字系統,服務總線系統更進一步了:由總線系統完成調用,服務請求方都不須要直接和服務提供方交互了。 基本的設計以下:

「服務名字系統」和「服務總線系統」簡單對好比下表所示。

消息隊列

互聯網業務的一個特色是「快」,這就要求不少業務處理採用異步的方式。例如,大V發佈一條微博後,系統須要發消息給關注的用戶,咱們不可能等到全部消息都發送給關注用戶後再告訴大V說微博發佈成功了,只能先讓大V發佈微博,而後再發消息給關注用戶。

傳統的異步通知方式是由消息生產者直接調用消息消費者提供的接口進行通知的,但當業務變得龐大,子系統數量增多時,這樣作會致使系統間交互很是複雜和難以管理,由於系統間互相依賴和調用,整個系統的結構就像一張蜘蛛網,以下圖所示。

消息隊列就是爲了實現這種跨系統異步通知的中間件系統。消息隊列既能夠「一對一」通知,也能夠「一對多」廣播。以微博爲例,能夠清晰地看到異步通知的實現和做用,以下圖所示。

對比前面的蜘蛛網架構,能夠清晰地看出引入消息隊列系統後的效果:

  • 總體結構從網狀結構變爲線性結構,結構清晰。
  • 消息生產和消息消費解耦,實現簡單。
  • 增長新的消息消費者,消息生產者徹底不須要任何改動,擴展方便。
  • 消息隊列系統能夠作高可用、高性能,避免各業務子系統各自獨立作一套,減輕工做量。
  • 業務子系統只須要聚焦業務便可,實現簡單。

消息隊列系統基本功能的實現比較簡單,但要作到高性能、高可用、消息時序性、消息事務性則比較難。業界已經有不少成熟的開源實現方案,若是要求不高,基本上拿來用便可,例如,RocketMQ、Kafka、ActiveMQ等。但若是業務對消息的可靠性、時序、事務性要求較高時,則要深刻研究這些開源方案,不然很容易踩坑。

開源的用起來方便,但要改就很麻煩了。因爲其相對比較簡單,不少公司也會花費人力和時間重複造一個輪子,這樣也有好處,由於能夠根據本身的業務特色作快速的適配開發。

網絡層技術

除了複雜度,互聯網業務發展的另外兩個關鍵特色是「高性能」和「高可用」。一般狀況下,咱們在設計高可用和高性能系統的時候,主要關注點在系統自己的複雜度,而後經過各類手段來實現高可用和高性能的要求。可是當咱們站在一個公司的的角度來思考架構的時候,單個系統的高可用和高性能並不等於總體業務的高可用和高性能,互聯網業務的高性能和高可用須要從更高的角度去設計,這個高點就是「網絡」。這裏的網絡強調的是站在網絡層的角度總體設計架構,而不是某個具體網絡的搭建。

負載均衡

顧名思議,負載均衡就是將請求均衡地分配到多個系統上。使用負載均衡的緣由也很簡單:每一個系統的處理能力是有限的,爲了應對大容量的訪問,必須使用多個系統。例如,一臺32核64GB內存的機器,性能測試數據顯示每秒處理Hello World的HTTP請求不超過2萬,實際業務機器處理HTTP請求每秒可能才幾百QPS,而互聯網業務併發超過1萬是比較常見的,遇到雙11、過年發紅包這些極端場景,每秒能夠達到幾十萬的請求。

DNS

DNS是最簡單也是最多見的負載均衡方式,通常用來實現地理級別的均衡。例如,北方的用戶訪問北京的機房,南方的用戶訪問廣州的機房。通常不會使用DNS來作機器級別的負載均衡,由於太耗費IP資源了。例如,百度搜索可能要10000臺以上機器,不可能將這麼多機器所有配置公網IP,而後用DNS來作負載均衡。

DNS負載均衡的優勢是通用(全球通用)、成本低(申請域名,註冊DNS便可),但缺點也比較明顯,主要體如今:

  • DNS緩存的時間比較長,即便將某臺業務機器從DNS服務器上刪除,因爲緩存的緣由,仍是有不少用戶會繼續訪問已經被刪除的機器。
  • DNS不夠靈活。DNS不能感知後端服務器的狀態,只能根據配置策略進行負載均衡,沒法作到更加靈活的負載均衡策略。好比說某臺機器的配置比其餘機器要好不少,理論上來講應該多分配一些請求給它,但DNS沒法作到這一點。

因此對於時延和故障敏感的業務,有實力的公司可能會嘗試實現HTTP-DNS的功能,即便用HTTP協議實現一個私有的DNS系統。HTTP-DNS主要應用在經過App提供服務的業務上,由於在App端能夠實現靈活的服務器訪問策略,若是是Web業務,實現起來就比較麻煩一些,由於URL的解析是由瀏覽器來完成的,只有Java的訪問能夠像App那樣實現比較靈活的控制。

HTTP-DNS的優缺點有:

  • 靈活:HTTP-DNS能夠根據業務需求靈活的設置各類策略。
  • 可控:HTTP-DNS是本身開發的系統,IP更新、策略更新等無需依賴外部服務商。
  • 及時:HTTP-DNS不受傳統DNS緩存的影響,能夠很是快地更新數據、隔離故障。
  • 開發成本高:沒有通用的解決方案,須要本身開發。
  • 侵入性:須要App基於HTTP-DNS進行改造。

Nginx 、LVS 、F5

DNS用於實現地理級別的負載均衡,而Nginx、LVS、F5用於同一地點內機器級別的負載均衡。其中Nginx是軟件的7層負載均衡,LVS是內核的4層負載均衡,F5是硬件的4層負載均衡。

軟件和硬件的區別就在於性能,硬件遠遠高於軟件,Ngxin的性能是萬級,通常的Linux服務器上裝個Nginx大概能到5萬/秒;LVS的性能是十萬級,沒有具體測試過,聽說可達到80萬/秒;F5性能是百萬級,從200萬/秒到800萬/秒都有。硬件雖然性能高,可是單臺硬件的成本也很高,一臺最便宜的F5都是幾十萬,可是若是按照同等請求量級來計算成本的話,實際上硬件負載均衡設備可能會更便宜,例如假設每秒處理100萬請求,用一臺F5就夠了,但用Nginx,可能要20臺,這樣折算下來用F5的成本反而低。所以一般狀況下,若是性能要求不高,能夠用軟件負載均衡;若是性能要求很高,推薦用硬件負載均衡。

4層和7層的區別就在於協議和靈活性。Nginx支持HTTP、E-mail協議,而LVS和F5是4層負載均衡,和協議無關,幾乎全部應用均可以作,例如聊天、數據庫等。

目前不少雲服務商都已經提供了負載均衡的產品,例如阿里雲的SLB、UCloud的ULB等,中小公司直接購買便可。

CDN

CDN是爲了解決用戶網絡訪問時的「最後一千米」效應,本質上是一種「以空間換時間」的加速策略,即將內容緩存在離用戶最近的地方,用戶訪問的是緩存的內容,而不是站點實時的內容。

下面是簡單的CDN請求流程示意圖:

 

CDN通過多年的發展,已經變成了一個很龐大的體系:分佈式存儲、全局負載均衡、網絡重定向、流量控制等都屬於CDN的範疇,尤爲是在視頻、直播等領域,若是沒有CDN,用戶是不可能實現流暢觀看內容的。

幸運的是,大部分程序員和架構師都不太須要深刻理解CDN的細節,由於CDN做爲網絡的基礎服務,獨立搭建的成本巨大,不多有公司本身設計和搭建CDN系統,從CDN服務商購買CDN服務便可,目前有專門的CDN服務商,例如網宿和藍汛;也有云計算廠家提供CDN服務,例如阿里雲和騰訊雲都提供CDN的服務。

多機房

從架構上來講,單機房就是一個全局的網絡單點,在發生比較大的故障或者災害時,單機房難以保證業務的高可用。例如,停電、機房網絡中斷、地震、水災等都有可能致使一個機房徹底癱瘓。

多機房設計最核心的因素就是如何處理時延帶來的影響,常見的策略有:

  1. 同城多機房 同一個城市多個機房,距離不會太遠,能夠投入重金,搭建私有的高速網絡,基本上可以作到和同機房同樣的效果。 這種方式對業務影響很小,但投入較大,若是不是大公司,通常是承受不起的;並且遇到極端的地震、水災等天然災害,同城多機房也是有很大風險的。
  2. 跨城多機房 在不一樣的城市搭建多個機房,機房間經過網絡進行數據複製(例如,MySQL主備複製),但因爲跨城網絡時延的問題,業務上須要作必定的妥協和兼容,好比不須要數據的實時強一致性,只是保證最終一致性。 例如,微博類產品,B用戶關注了A用戶,A用戶在北京機房發佈了一條微博,B在廣州機房不須要馬上看到A用戶發的微博,等10分鐘看到也能夠。 這種方式實現簡單,但和業務有很強的相關性,微博能夠這樣作,支付寶的轉帳業務就不能這樣作,由於用戶餘額是強一致性的。
  3. 跨國多機房 和跨城多機房相似,只是地理上分佈更遠,時延更大。因爲時延太大和用戶跨國訪問實在太慢,跨國多機房通常僅用於備份和服務本國用戶。

多中心

多中心必須以多機房爲前提,但從設計的角度來看,多中心相比多機房是本質上的飛越,難度也高出一個等級。

簡單來講,多機房的主要目標是災備,當機房故障時,能夠比較快速地將業務切換到另一個機房,這種切換操做容許必定時間的中斷(例如,10分鐘、1個小時),並且業務也可能有損失(例如,某些未同步的數據不能立刻恢復,或者要等幾天才恢復,甚至永遠都不能恢復了)。所以相比多機房來講,多中心的要求就高多了,要求每一箇中心都同時對外提供服務,且業務可以自動在多中心之間切換,故障後不需人工干預或者不多的人工干預就能自動恢復。

多中心設計的關鍵就在於「數據一致性」和「數據事務性」如何保證,這兩個難點都和業務緊密相關,目前沒有很成熟的且通用的解決方案,須要基於業務的特性進行詳細的分析和設計。以淘寶爲例,淘寶對外宣稱本身是多中心的,可是在實際設計過程當中,商品瀏覽的多中心方案、訂單的多中心方案、支付的多中心方案都須要獨立設計和實現。

正由於多中心設計的複雜性,不必定全部業務都能實現多中心,目前國內的銀行、支付寶這類系統就沒有徹底實現多中心,否則也不會出現挖掘機一鏟子下去,支付寶中斷4小時的故障。

用戶層技術用戶管理

互聯網業務的一個典型特徵就是經過互聯網將衆多分散的用戶鏈接起來,所以用戶管理是互聯網業務必不可少的一部分。

稍微大一點的互聯網業務,確定會涉及多個子系統,這些子系統不可能每一個都管理這麼龐大的用戶,由此引伸出用戶管理的第一個目標:單點登陸(SSO),又叫統一登陸。單點登陸的技術實現手段較多,例如cookie、JSONP、token等,目前最成熟的開源單點登陸方案當屬CAS,其架構以下

除此以外,當業務作大成爲了平臺後,開放成爲了促進業務進一步發展的手段,須要容許第三方應用接入,由此引伸出用戶管理的第二個目標:受權登陸。如今最流行的受權登陸就是OAuth 2.0協議,基本上已經成爲了事實上的標準,若是要作開放平臺,則最好用這個協議,私有協議漏洞多,第三方接入也麻煩。

用戶管理系統面臨的主要問題是用戶數巨大,通常至少千萬級,QQ、微信、支付寶這種巨無霸應用都是億級用戶。不過也不要被這個數據給嚇倒了,用戶管理雖然數據量巨大,但實現起來並不難,緣由是什麼呢? 由於用戶數據量雖然大,可是不一樣用戶之間沒有太強的業務關聯,A用戶登陸和B用戶登陸基本沒有關係。所以雖然數據量巨大,但咱們用一個簡單的負載均衡架構就能輕鬆應對。

用戶管理的基本架構以下:

消息推送

消息推送根據不一樣的途徑,分爲短信、郵件、站內信、App推送。除了App,不一樣的途徑基本上調用不一樣的API便可完成,技術上沒有什麼難度。例如,短信須要依賴運營商的短信接口,郵件須要依賴郵件服務商的郵件接口,站內信是系統提供的消息通知功能。

App目前主要分爲iOS和Android推送,iOS系統比較規範和封閉,基本上只能使用蘋果的APNS;但Android就不同了,在國外,用GCM和APNS差異不大;可是在國內,狀況就複雜多了:首先是GCM不能用;其次是各個手機廠商都有本身的定製的Android,消息推送實現也不徹底同樣。所以Android的消息推送就五花八門了,大部分有實力的大廠,都會本身實現一套消息推送機制,例如阿里雲移動推送、騰訊信鴿推送、百度雲推送;也有第三方公司提供商業推送服務,例如友盟推送、極光推送等。

一般狀況下,對於中小公司,若是不涉及敏感數據,Android系統上推薦使用第三方推送服務,由於畢竟是專業作推送服務的,消息到達率是有必定保證的。

若是涉及敏感數據,須要本身實現消息推送,這時就有必定的技術挑戰了。消息推送主要包含3個功能:設備管理(惟一標識、註冊、註銷)、鏈接管理和消息管理,技術上面臨的主要挑戰有:

  • 海量設備和用戶管理 消息推送的設備數量衆多,存儲和管理這些設備是比較複雜的;同時,爲了針對不一樣用戶進行不一樣的業務推廣,還須要收集用戶的一些信息,簡單來講就是將用戶和設備關聯起來,須要提取用戶特徵對用戶進行分類或者打標籤等。
  • 鏈接保活 要想推送消息必須有鏈接通道,可是應用又不可能一直在前臺運行,大部分設備爲了省電省流量等緣由都會限制應用後臺運行,限制應用後臺運行後鏈接通道可能就被中斷了,致使消息沒法及時的送達。鏈接保活是整個消息推送設計中細節和黑科技最多的地方,例如應用互相拉起、找手機廠商開白名單等。
  • 消息管理 實際業務運營過程當中,並非每一個消息都須要發送給每一個用戶,而是可能根據用戶的特徵,選擇一些用戶進行消息推送。因爲用戶特徵變化很大,各類排列組合都有可能,將消息推送給哪些用戶這部分的邏輯要設計得很是靈活,才能支撐花樣繁多的業務需求,具體的設計方案能夠採起規則引擎之類的微內核架構技術。

存儲雲、圖片雲

互聯網業務場景中,用戶會上傳多種類型的文件數據,例如微信用戶發朋友圈時上傳圖片,微博用戶發微博時上傳圖片、視頻,優酷用戶上傳視頻,淘寶賣家上傳商品圖片等,這些文件具有幾個典型特色:

  • 數據量大:用戶基數大,用戶上傳行爲頻繁,例如2016年的時候微信朋友圈天天上傳圖片就達到了10億張。
  • 文件體積小:大部分圖片是幾百KB到幾MB,短視頻播放時間也是在幾分鐘內。
  • 訪問有時效性:大部分文件是剛上傳的時候訪問最多,隨着時間的推移訪問量愈來愈小。

爲了知足用戶的文件上傳和存儲需求,須要對用戶提供文件存儲和訪問功能,這裏就須要用到前面介紹「存儲層」技術時提到的「小文件存儲」技術。簡單來講,存儲雲和圖片雲一般的實現都是「CDN + 小文件存儲」,如今有了「雲」以後,除非BAT級別,通常不建議本身再重複造輪子了,直接買雲服務多是最快也是最經濟的方式。

既然存儲雲和圖片雲都是基於「CDN + 小文件存儲」的技術,爲什麼不統一一套系統,而將其拆分爲兩個系統呢?這是由於「圖片」業務的複雜性致使的,普通的文件基本上提供存儲和訪問就夠了,而圖片涉及的業務會更多,包括裁剪、壓縮、美化、審覈、水印等處理,所以一般狀況下圖片雲會拆分爲獨立的系統對用戶提供服務。

業務層技術

互聯網的業務千差萬別,不一樣的業務分解下來有不一樣的系統,因此業務層沒有辦法提煉一些公共的系統或者組件。拋開業務上的差別,各個互聯網業務發展最終面臨的問題都是相似的:業務複雜度愈來愈高。也就是說,業務層面對的主要技術挑戰是「複雜度」。

複雜度愈來愈高的一個主要緣由就是系統愈來愈龐大,業務愈來愈多。幸運的是,面對業務層的技術挑戰,咱們有一把「屠龍寶刀」,無論什麼業務難題,用上「屠龍寶刀」問題都能迎刃而解。這把「屠龍寶刀」就是「拆」,化整爲零、分而治之,將總體複雜性分散到多個子業務或者子系統裏面去。具體拆的方式你能夠查看專欄前面可擴展架構模式部分的分層架構、微服務、微內核等。

以一個簡單的電商系統爲例,以下圖所示。

我這個模擬的電商系統經歷了3個發展階段:

  • 第一階段:全部功能都在1個系統裏面。
  • 第二階段:將商品和訂單拆分到2個子系統裏面。
  • 第三階段:商品子系統和訂單子系統分別拆分紅了更小的6個子系統。

上面只是個樣例,實際上隨着業務的發展,子系統會愈來愈多,聽說淘寶內部大大小小的已經有成百上千的子系統了。

隨着子系統數量愈來愈多,若是達到幾百上千,另一個複雜度問題又會凸顯出來:子系統數量太多,已經沒有人可以說清楚業務的調用流程了,出了問題排查也會特別複雜。此時應該怎麼處理呢,總不可能又將子系統合成大系統吧?最終答案仍是「合」,正所謂「合久必分、分久必合」,但合的方式不同,此時採起的「合」的方式是按照「高內聚、低耦合」的原則,將職責關聯比較強的子系統合成一個虛擬業務域,而後經過網關對外統一呈現,相似於設計模式中的Facade模式。一樣以電商爲樣例,採用虛擬業務域後,其架構以下:

平臺技術

當業務規模比較小、系統複雜度不高時,運維、測試、數據分析、管理等支撐功能主要由各系統或者團隊獨立完成。隨着業務規模愈來愈大,系統複雜度愈來愈高,子系統數量愈來愈多,若是繼續採起各自爲政的方式來實現這些支撐功能,會發現重複工做很是多。所以咱們天然而然就會想到將這些支撐功能作成平臺,避免重複造輪子,減小不規範帶來的溝通和協做成本。

運維平臺

運維平臺核心的職責分爲四大塊:配置、部署、監控、應急,每一個職責對應系統生命週期的一個階段,以下圖所示。

  • 配置:主要負責資源的管理。例如,機器管理、IP地址管理、虛擬機管理等。
  • 部署:主要負責將系統發佈到線上。例如,包管理、灰度發佈管理、回滾等。
  • 監控:主要負責收集系統上線運行後的相關數據並進行監控,以便及時發現問題。
  • 應急:主要負責系統出故障後的處理。例如,中止程序、下線故障機器、切換IP等。

運維平臺的核心設計要素是「四化」:標準化、平臺化、自動化、可視化。

  1. 標準化 須要制定運維標準,規範配置管理、部署流程、監控指標、應急能力等,各系統按照運維標準來實現,避免不一樣的系統不一樣的處理方式。標準化是運維平臺的基礎,沒有標準化就沒有運維平臺。 若是某個系統就是沒法改造本身來知足運維標準,那該怎麼辦呢?常見的作法是不改造系統,由中間方來完成規範適配。例如,某個系統對外提供了RESTful接口的方式來查詢當前的性能指標,而運維標準是性能數據經過日誌定時上報,那麼就能夠寫一個定時程序訪問RESTful接口獲取性能數據,而後轉換爲日誌上報到運維平臺。
  2. 平臺化 傳統的手工運維方式須要投入大量人力,效率低,容易出錯,所以須要在運維標準化的基礎上,將運維的相關操做都集成到運維平臺中,經過運維平臺來完成運維工做。 運維平臺的好處有:
    • 能夠將運維標準固化到平臺中,無須運維人員死記硬背運維標準。
    • 運維平臺提供簡單方便的操做,相比之下人工操做低效且容易出錯。
    • 運維平臺是可複用的,一套運維平臺能夠支撐幾百上千個業務系統。
  3. 自動化 傳統手工運維方式效率低下的一個主要緣由就是要執行大量重複的操做,運維平臺能夠將這些重複操做固化下來,由系統自動完成。 例如,一次手工部署須要登陸機器、上傳包、解壓包、備份舊系統、覆蓋舊系統、啓動新系統,這個過程當中須要執行大量的重複或者相似的操做。有了運維平臺後,平臺須要提供自動化的能力,完成上述操做,部署人員只須要在最開始單擊「開始部署」按鈕,系統部署完成後通知部署人員便可。 相似的還有監控,有了運維平臺後,運維平臺能夠實時收集數據並進行初步分析,當發現數據異常時自動發出告警,無須運維人員盯着數據看,或者寫一大堆「grep + awk + sed」來分析日誌才能發現問題。
  4. 可視化 運維平臺有很是多的數據,若是所有經過人工去查詢數據再來判斷,則效率很低。尤爲是在故障應急時,時間就是生命,處理問題都是爭分奪秒,能減小1分鐘的時間就可能挽回幾十萬元的損失,可視化的主要目的就是爲了提高數據查看效率。 可視化的原理和汽車儀表盤相似,若是隻是一連串的數字顯示在屏幕上,相信大部分人一看到一連串的數字,第一感受是眼花,並且也很難將數據與具體的狀況聯繫起來。而有了儀表盤後,經過儀表盤的指針偏離幅度及指針指向的區域顏色,可以一目瞭然地看出當前的狀態是低速、中速仍是高速。 可視化相比簡單的數據羅列,具有下面這些優勢:
    • 可以直觀地看到數據的相關屬性,例如,汽車儀表盤中的數據最小值是0,最大是100,單位是MPH。
    • 可以將數據的含義展現出來,例如汽車儀表盤中不一樣速度的顏色指示。
    • 可以將關聯數據整合一塊兒展現,例如汽車儀表盤的速度和里程。

測試平臺

測試平臺核心的職責固然就是測試了,包括單元測試、集成測試、接口測試、性能測試等,均可以在測試平臺來完成。

測試平臺的核心目的是提高測試效率,從而提高產品質量,其設計關鍵就是自動化。傳統的測試方式是測試人員手工執行測試用例,測試效率低,重複的工做多。經過測試平臺提供的自動化能力,測試用例可以重複執行,無須人工參與,大大提高了測試效率。

爲了達到「自動化」的目標,測試平臺的基本架構以下圖所示。

  1. 用例管理 測試自動化的主要手段就是經過腳本或者代碼來進行測試,例如單元測試用例是代碼、接口測試用例能夠用Python來寫、可靠性測試用例能夠用Shell來寫。爲了可以重複執行這些測試用例,測試平臺須要將用例管理起來,管理的維度包括業務、系統、測試類型、用例代碼。例如,網購業務的訂單系統的接口測試用例。
  2. 資源管理 測試用例要放到具體的運行環境中才能真正執行,運行環境包括硬件(服務器、手機、平板電腦等)、軟件(操做系統、數據庫、Java虛擬機等)、業務系統(被測試的系統)。 除了性能測試,通常的自動化測試對性能要求不高,因此爲了提高資源利用率,大部分的測試平臺都會使用虛擬技術來充分利用硬件資源,如虛擬機、Docker等技術。
  3. 任務管理 任務管理的主要職責是將測試用例分配到具體的資源上執行,跟蹤任務的執行狀況。任務管理是測試平臺設計的核心,它將測試平臺的各個部分串聯起來從而完成自動化測試。
  4. 數據管理 測試任務執行完成後,須要記錄各類相關的數據(例如,執行時間、執行結果、用例執行期間的CPU、內存佔用狀況等),這些數據具有下面這些做用:
    • 展示當前用例的執行狀況。
    • 做爲歷史數據,方便後續的測試與歷史數據進行對比,從而發現明顯的變化趨勢。例如,某個版本後單元測試覆蓋率從90%降低到70%。
    • 做爲大數據的一部分,能夠基於測試的任務數據進行一些數據挖掘。例如,某個業務一年執行了10000個用例測試,另一個業務只執行了1000個用例測試,兩個業務規模和複雜度差很少,爲什麼差別這麼大?

數據平臺

數據平臺的核心職責主要包括三部分:數據管理、數據分析和數據應用。每一部分又包含更多的細分領域,詳細的數據平臺架構以下圖所示。

  1. 數據管理 數據管理包含數據採集、數據存儲、數據訪問和數據安全四個核心職責,是數據平臺的基礎功能。
    • 數據採集:從業務系統蒐集各種數據。例如,日誌、用戶行爲、業務數據等,將這些數據傳送到數據平臺。
    • 數據存儲:將從業務系統採集的數據存儲到數據平臺,用於後續數據分析。
    • 數據訪問:負責對外提供各類協議用於讀寫數據。例如,SQL、Hive、Key-Value等讀寫協議。
    • 數據安全:一般狀況下數據平臺都是多個業務共享的,部分業務敏感數據須要加以保護,防止被其餘業務讀取甚至修改,所以須要設計數據安全策略來保護數據。
  2. 數據分析 數據分析包括數據統計、數據挖掘、機器學習、深度學習等幾個細分領域。
    • 數據統計:根據原始數據統計出相關的總覽數據。例如,PV、UV、交易額等。
    • 數據挖掘:數據挖掘這個概念自己含義能夠很廣,爲了與機器學習和深度學習區分開,這裏的數據挖掘主要是指傳統的數據挖掘方式。例如,有經驗的數據分析人員基於數據倉庫構建一系列規則來對數據進行分析從而發現一些隱含的規律、現象、問題等,經典的數據挖掘案例就是沃爾瑪的啤酒與尿布的關聯關係的發現。
    • 機器學習、深度學習:機器學習和深度學習屬於數據挖掘的一種具體實現方式,因爲其實現方式與傳統的數據挖掘方式差別較大,所以數據平臺在實現機器學習和深度學習時,須要針對機器學習和深度學習獨立進行設計。
  3. 數據應用 數據應用很普遍,既包括在線業務,也包括離線業務。例如,推薦、廣告等屬於在線應用,報表、欺詐檢測、異常檢測等屬於離線應用。 數據應用可以發揮價值的前提是須要有「大數據」,只有當數據的規模達到必定程度,基於數據的分析、挖掘才能發現有價值的規律、現象、問題等。若是數據沒有達到必定規模,一般狀況下作好數據統計就足夠了,尤爲是不少初創企業,無須一開始就參考BAT來構建本身的數據平臺。

管理平臺

管理平臺的核心職責就是權限管理,不管是業務系統(例如,淘寶網)、中間件系統(例如,消息隊列Kafka),仍是平臺系統(例如,運維平臺),都須要進行管理。若是每一個系統都本身來實現權限管理,效率過低,重複工做不少,所以須要統一的管理平臺來管理全部的系統的權限。

權限管理主要分爲兩部分:身份認證、權限控制,其基本架構以下圖所示。

1.身份認證

肯定當前的操做人員身份,防止非法人員進入系統。例如,不容許匿名用戶進入系統。爲了不每一個系統都本身來管理用戶,一般狀況下都會使用企業帳號來作統一認證和登陸。

2.權限控制

根據操做人員的身份肯定操做權限,防止未經受權的人員進行操做。例如,不容許研發人員進入財務系統查看別人的工資。

相關文章
相關標籤/搜索