談談互聯網後端基礎設施java
來自:http://chuansong.me/n/717637351233mysql
對於一個互聯網企業,後端服務是必不可少的一個組成部分。拋開業務應用來講,往下的基礎服務設施作到哪些纔可以保證業務的穩定可靠、易維護、高可用呢?縱觀整個互聯網技術體系再結合公司的目前情況,我的認爲必不可少或者很是關鍵的後端基礎技術/設施以下圖所示:ios
這裏的後端基礎設施主要指的是應用在線上穩定運行須要依賴的關鍵組件/服務等。開發或者搭建好以上的後端基礎設施,通常狀況下是可以支撐很長一段時間內的業務的。此外,對於一個完整的架構來講,還有不少應用感知不到的系統基礎服務,如負載均衡、自動化部署、系統安全等,並無包含在本文的描述範圍內。nginx
Api網關git
在移動app的開發過程當中,一般後端提供的接口須要如下功能的支持:github
通常的作法,使用nginx作負載均衡,而後在每一個業務應用裏作api接口的訪問權限控制和用戶鑑權,更優化一點的方式則是把後二者作成公共類庫供全部業務調用。但從整體上來看,這三種特性都屬於業務的公共需求,更可取的方式則是集成到一塊兒做爲一個服務,既能夠動態地修改權限控制和鑑權機制,也能夠減小每一個業務集成這些機制的成本。這種服務就是Api網關(http://blog.csdn.net/pzxwhc/article/details/49873623),能夠選擇本身實現,也可使用開源軟件實現,如Kong。以下圖所示:web
可是以上方案的一個問題是因爲全部api請求都要通過網關,它很容易成爲系統的性能瓶頸。所以,能夠採起的方案是:去掉api網關,讓業務應用直接對接統一認證中心,在基礎框架層面保證每一個api調用都須要先經過統一認證中心的認證,這裏能夠採起緩存認證結果的方式避免對統一認證中心產生過大的請求壓力。redis
業務應用和後端基礎框架spring
業務應用分爲:在線業務應用和內部業務應用。sql
業務應用基於後端的基礎框架開發,針對Java後端來講,應該有的幾個框架以下:
通常來講,以上幾個框架便可以完成一個後端應用的雛形。
對於這些框架來講,最爲關鍵的是根據團隊技術構成選擇最合適的,有能力開發本身的框架則更好。此外,這裏須要提供一個後端應用的模板或生成工具(如maven的archetype)給團隊成員使用,可讓你們在開發新的應用的時候,迅速的生成雛形應用,而無需再作一些框架搭建的重複性勞動。
緩存、數據庫、搜索引擎、消息隊列
緩存、數據庫、搜索引擎、消息隊列這四者都是應用依賴的後端基礎服務,他們的性能直接影響到了應用的總體性能,有時候你代碼寫的再好也許就是由於這些服務致使應用性能沒法提高上去。
緩存
如緩存五分鐘法則所講:若是一個數據頻繁被訪問,那麼就應該放內存中。這裏的緩存就是一種讀寫效率都很是高的存儲方案,可以應對高併發的訪問請求,一般狀況下也不須要持久化的保證。但相對其餘存儲來講,緩存通常是基於內存的,成本比較昂貴,所以不能濫用。
緩存能夠分爲:本地緩存和分佈式緩存。
對於緩存的使用,須要注意如下幾點:
對於其具體的實現機制,能夠參考《Redis設計與實現》一書
數據庫
數據庫是後端開發中很是常見的一個服務組件。對於數據庫的選型,要根據業務的特色和數據結構的特色來決定。
從存儲介質上,數據庫能夠分爲:
從存儲數據類型、數據模式上,數據庫能夠分爲:
和數據庫相關的一個很重要的就是數據庫的索引。有一種說法是:「掌握了索引就等於掌握了數據庫」。暫且不去評判此說法是否真的準確,但索引的確關係着數據庫的讀寫性能。須要對數據庫的索引原理作到足夠的瞭解才能更好的使用各類數據庫。一般來講,Mysql、Oracle、Mongodb這些都是使用的B樹做爲索引,是考慮到傳統硬盤的特色後兼顧了讀寫性能以及範圍查找需求的選擇,而Hbase用得LSM則是爲了提升寫性能對讀性能作了犧牲。
搜索引擎
搜索引擎也是後端應用中一個很關鍵的組件,尤爲是對內容類、電商類的應用,經過關鍵詞、關鍵字搜索內容、商品是一個很常見的用戶場景。比較成熟的開源搜索引擎有Solr和Elasticsearch,不少中小型互聯網公司搜索引擎都是基於這兩個開源系統搭建的。它們都是基於Lucence來實現的,不一樣之處主要在於termIndex的存儲、分佈式架構的支持等等。
對於搜索引擎的使用,從系統熟悉、服務搭建、功能定製,須要花費較長時間。在這個過程當中,須要注意如下問題:
更爲詳細的對於搜索引擎的工程化實踐能夠參考有贊工程師的這篇文章:有贊搜索引擎實踐(工程篇)
另外,搜索引擎還能夠用在數據的多維分析上,就是GrowingIO、MixPanel中的能夠任意維度查詢數據報表的功能。固然,druid也許是一個更好的實現多維分析的方案,官方也有其與es的比較:http://t.cn/RcGFIxn。
消息隊列
軟件的組織結構,從開始的面向組件到SOA、SAAS是一個逐漸演變的過程。而到了今天微服務盛行的時代,你都很差意思說本身的系統只是單一的一個系統而沒有解耦成一個個service。固然,小的系統的確沒有拆分的必要性,但一個複雜的系統拆成一個個service作微服務架構確實是不得不作的事情。
那麼問題就來了,service之間的通訊如何來作呢?使用什麼協議?經過什麼方式調用?都是須要考慮的問題。
先拋開協議不談,service之間的調用方式能夠分爲同步調用以及異步調用。同步調用的方式無需多說,那麼異步調用是怎麼進行的呢?一種很常見的方式就是使用消息隊列,調用方把請求放到隊列中便可返回,而後等待服務提供方去隊列中去獲取請求進行處理,而後把結果返回給調用方便可(能夠經過回調)。
異步調用就是消息中間件一個很是常見的應用場景。此外,消息隊列的應用場景還有如下:
目前主流的消息隊列軟件,主要有如下幾種:
文件存儲
無論是業務應用、依賴的後端服務仍是其餘的各類服務,最終仍是要依賴於底層文件存儲的。一般來講,文件存儲須要知足的特性有:可靠性、容災性、穩定性,即要保證存儲的數據不會輕易丟失,即便發生故障也可以有回滾方案,也要保證高可用率。在底層能夠採用傳統的RAID做爲解決方案,再上一層,目前hadoop的hdfs則是最爲廣泛的分佈式文件存儲方案,固然還有NFS、Samba這種共享文件系統也提供了簡單的分佈式存儲的特性。
此外,若是文件存儲確實成爲了應用的瓶頸或者必須提升文件存儲的性能從而提高整個系統的性能時,那麼最爲直接和簡單的作法就是拋棄傳統機械硬盤,用SSD硬盤替代。像如今不少公司在解決業務性能問題的時候,最終的關鍵點每每就是SSD。這也是用錢換取時間和人力成本最直接和最有效的方式。在數據庫部分描述的SSDB就是對LevelDB封裝以後,利用SSDB的特性的一種高性能KV數據庫。
至於HDFS,若是要使用上面的數據,是須要經過hadoop的。相似xx on yarn的一些技術就是將非hadoop技術跑在hdfs上的解決方案(固然也是爲了使用MR)。
統一認證中心
統一認證中心,主要是對app用戶、內部用戶、app等的認證服務,包括
之因此須要統一認證中心,就是爲了可以集中對這些全部app都會用到的信息進行管理,也給全部應用提供統一的認證服務。尤爲是在有不少業務須要共享用戶數據的時候,構建一個統一認證中心是很是必要的。此外,經過統一認證中心構建移動app的單點登陸也是水到渠成的事情(模仿web的機制,將認證後的信息加密存儲到本地磁盤中供多個app使用)。
單點登陸系統
目前不少大的在線web網站都是有單點登陸系統的,通俗的來講就是隻須要一次用戶登陸,就可以進入多個業務應用(權限能夠不相同),很是方便用戶的操做。而在移動互聯網公司中,內部的各類管理、信息系統一樣也須要單點登陸系統。目前,比較成熟的、用的最多的單點登陸系統應該是耶魯大學開源的CAS, 能夠基於https://github.com/apereo/cas/tree/master/cas-server-webapp來定製開發的。此外,國人開源的kisso的這個也不錯。基本上,單點登陸的原理都相似下圖所示:
統一配置中心
在Java後端應用中,一種讀寫配置比較通用的方式就是將配置文件寫在propeties、yaml、HCON文件中,修改的時候只須要更新文件從新部署便可,能夠作到不牽扯代碼層面改動的目的。統一配置中心,則是基於這種方式之上的統一對全部業務或者基礎後端服務的相關配置文件進行管理的統一服務, 具備如下特性:
disconf是能夠在生產環境使用的一個方案,也可能根據本身的需求開發本身的配置中心(能夠選擇zookeeper做爲配置存儲)。
服務治理框架
對於外部API調用或者客戶端對後端api的訪問,可使用http協議或者說restful(固然也能夠直接經過最原始的socket來調用)。但對於內部服務間的調用,通常都是經過RPC機制來調用的。目前主流的RPC協議有:
這些RPC協議各有優劣點,須要針對業務需求作出相應的最好的選擇。
這樣,當你的系統服務在逐漸增多,RPC調用鏈愈來愈複雜,不少狀況下,須要不停的更新文檔來維護這些調用關係。一個對這些服務進行管理的框架能夠大大節省所以帶來的繁瑣的人力工做。
傳統的ESB(企業服務總線)本質就是一個服務治理方案,但esb做爲一種proxy的角色存在於client和server之間,全部請求都須要通過esb,使得esb很容易成爲性能瓶頸。所以,基於傳統的esb,更好的一種設計以下圖所示:
如圖,以配置中心爲樞紐,調用關係只存在於client和提供服務的server之間,就避免了傳統esb的性能瓶頸問題。對於這種設計,esb應該支持的特性以下:
阿里開源的dubbo則對以上作了很好的實現,也是目前不少公司都在使用的方案。但因爲某些緣由,dubbo現已再也不維護,推薦你們使用噹噹後來維護的dubbox。
統一調度中心
在不少業務中,定時調度是一個很是廣泛的場景,好比定時去抓取數據、定時刷新訂單的狀態等。一般的作法就是針對各自的業務依賴Linux的cron機制或者java中的quartz。統一調度中心則是對全部的調度任務進行管理,這樣可以統一對調度集羣進行調優、擴展、任務管理等。azkaban和oozie是hadoop的流式工做管理引擎,也能夠做爲統一調度中心來使用。固然,你也可使用cron或者quartz來實現本身的統一調度中心。
對於Java的quartz這裏須要說明一下:這個quartz須要和spring quartz區分,後者是spring對quartz框架的簡單實現也是目前使用的最多的一種調度方式。可是,其並無作高可用集羣的支持。而quartz雖然有集羣的支持,可是配置起來很是複雜。如今不少方案都是使用zookeeper來實現spring quartz集羣的。這裏有一個國人開源的uncode-shcedule對此實現的還不錯,能夠根據本身的業務需求作二次開發。
統一日誌服務
日誌是開發過程必不可少的東西。有時候,打印日誌的時機、技巧是很能體現出工程師編碼水平的。畢竟,日誌是線上服務可以定位、排查異常最爲直接的信息。
一般的,將日誌分散在各個業務中很是不方便對問題的管理和排查。統一日誌服務則使用單獨的日誌服務器記錄日誌,各個業務經過統一的日誌框架將日誌輸出到日誌服務器上。
能夠經過實現log4j後者logback的appender來實現統一日誌框架,而後經過RPC調用將日誌打印到日誌服務器上。
數據基礎設施
數據是最近幾年很是火的一個領域。從《精益數據分析》到《增加黑客》,都是在強調數據的非凡做用。不少公司也都在經過數據推進產品設計、市場運營、研發等。詳細的可見以前的一篇《數據雜談》,對數據相關的東西作過一些總結。這裏須要說明的一點是,只有當你的數據規模真的到了單機沒法處理的規模才應該上大數據相關技術,千萬不要爲了大數據而大數據。不少狀況下使用單機程序+mysql就能解決的問題非得上hadoop即浪費時間又浪費人力。
這裏須要補充一點的是,對於不少公司,尤爲是離線業務並無那麼密集的公司,在不少狀況下大數據集羣的資源是被浪費的。所以誕生了xx on yarn一系列技術讓非hadoop系的技術能夠利用大數據集羣的資源,可以大大提升資源的利用率,如Docker on yarn(Hulu的VoidBox)。
數據高速公路
接着上面講的統一日誌服務,其輸出的日誌最終是變成數據到數據高速公路上供後續的數據處理程序消費的。這中間的過程包括日誌的收集、傳輸。
此外,這裏還有一個關鍵的技術就是數據庫和數據倉庫間的數據同步問題,即將須要分析的數據從數據庫中同步到諸如hive這種數據倉庫時使用的方案。比較簡單的、用的也比較多的可使用sqoop進行基於時間戳的數據同步,此外,阿里開源的canal實現了基於binlog增量同步,更加適合通用的同步場景,可是基於canal你仍是須要作很多的業務開發工做的。推薦另外一款國人開源的MySQL-Binlog,原理和canal相似,默認提供了任務的後臺管理功能,只須要實現接收到binlog後的處理邏輯便可。
離線數據分析
離線數據分析是能夠有延遲的,通常針對是非實時需求的數據分析工做,產生的也是T-1的報表。目前最經常使用的離線數據分析技術除了hadoop還有spark。相比hadoop,spark性能上有很大優點,固然對硬件資源要求也高。
對於hadoop,傳統的MR編寫很複雜,也不利於維護,能夠選擇使用hive來用sql替代編寫mr,可是前提務必要對hive的原理作到了解。能夠參見美團的這篇博文來學習:Hive SQL的編譯過程。而對於spark,也有相似hive的spark sql。
此外,對於離線數據分析,還有一個很關鍵的就是數據傾斜問題。所謂數據傾斜指的是region數據分佈不均,形成有的結點負載很低,而有些卻負載很高,從而影響總體的性能。所以,處理好數據傾斜問題對於數據處理是很關鍵的。對於hive的數據傾斜,可見:hive大數據傾斜總結。對於spark的傾斜問題,可見:Spark性能優化指南——高級篇。
實時數據分析
相對於離線數據分析,實時數據分析也叫在線數據分析,針對的是對數據有實時要求的業務場景,如廣告結算、訂單結算等。目前,比較成熟的實時技術有storm和spark streaming。相比起storm,spark streaming其實本質上仍是基於批量計算的。若是是對延遲很敏感的場景,仍是應該使用storm。
對於實時數據分析,須要注意的就是實時數據處理結果寫入存儲的時候,要考慮併發的問題,雖然對於storm的bolt程序來講不會有併發的問題,可是寫入的存儲介質是會面臨多任務同時讀寫的。一般採用的方案就是採用時間窗口的方式對數據作緩衝後批量寫入。
此外,實時數據處理通常狀況下都是基於增量處理的,相對於離線來講並不是可靠的,一旦出現故障(如集羣崩潰)或者數據處理失敗,是很難對數據恢復或者修復異常數據的。所以結合離線+實時是目前最廣泛採用的數據處理方案。Lambda架構就是一個結合離線和實時數據處理的架構方案。
數據即席分析
離線和實時數據分析產生的一些報表是給數據分析師、產品經理參考使用的,可是不少狀況下,線上的程序並不能知足這些需求方的需求。這時候就須要需求方本身對數據倉庫進行查詢統計。針對這些需求方,SQL上手容易、易描述等特色決定了其多是一個最爲合適的方式。所以提供一個SQL的即席查詢工具可以大大提升數據分析師、產品經理的工做效率。Presto、Impala、Hive都是這種工具。若是想進一步提供給需求方更加直觀的ui操做界面,能夠搭建內部的Hue。
故障監控
對於面向用戶的線上服務,發生故障是一件很嚴重的事情。所以,作好線上服務的故障檢測告警是一件很是重要的事情。能夠將故障監控分爲如下兩個層面的監控:
監控還有一個關鍵的步驟就是告警。告警的方式有不少種:郵件、im、短信等。考慮到故障的重要性不一樣、告警的合理性、便於定位問題等因素,有如下建議:
故障告警以後,那麼最最關鍵的就是應對了。對於創業公司來講,24小時待命是必備的素質,當遇到告警的時候,須要儘快對故障作出反應,找到問題所在,並能在可控時間內解決問題。對於故障問題的排查,基本上都是依賴於日誌的。只要日誌打的合理,通常狀況下是可以很快定位到問題所在的,可是若是是分佈式服務,而且日誌數據量特別大的狀況下,如何定位日誌就成爲了難題。這裏有幾個方案: