使用Java後端技術的目的就是構建業務應用,爲用戶提供在線或者離線服務。所以,一個業務應用須要哪些技術、依賴哪些基礎設施就決定了須要掌握的後端技術有哪些。縱觀整個互聯網技術體系再結合公司的目前情況,筆者認爲必不可少或者很是關鍵的後端基礎技術/設施以下圖所示:ios
這裏的後端基礎設施主要指的是應用在線上穩定運行須要依賴的關鍵組件或者服務。開發或者搭建好以上的後端基礎設施,通常狀況下是可以支撐很長一段時間內的業務的。此外,對於一個完整的架構來講,還有不少應用感知不到的系統基礎服務,如負載均衡、自動化部署、系統安全等,並無包含在本章的描述範圍內。nginx
在移動APP的開發過程當中,一般後端提供的接口須要如下功能的支持:git
通常的作法,使用Nginx作負載均衡,而後在每一個業務應用裏作API接口的訪問權限控制和用戶鑑權,更優化一點的方式則是把後二者作成公共類庫供全部業務調用。但從整體上來看,這三種特性都屬於業務的公共需求,更可取的方式則是集成到一塊兒做爲一個服務,既能夠動態地修改權限控制和鑑權機制,也能夠減小每一個業務集成這些機制的成本。這種服務就是API網關,能夠選擇本身實現。也可使用開源軟件實現,如Kong和Netflix Zuul。API網關通常架構以下圖所示:web
可是以上方案的一個問題是因爲全部API請求都要通過網關,它很容易成爲系統的性能瓶頸。所以,能夠採起的方案是:去掉API網關,讓業務應用直接對接統一認證中心,在基礎框架層面保證每一個API調用都須要先經過統一認證中心的認證,這裏能夠採起緩存認證結果的方式避免對統一認證中心產生過大的請求壓力。spring
業務應用分爲:在線業務應用和內部業務應用。mongodb
業務應用基於後端的基礎框架開發,針對Java後端來講,應該有如下幾個框架:docker
通常來講,以上幾個框架便可以完成一個後端應用的雛形。數據庫
緩存、數據庫、搜索引擎、消息隊列這四者都是應用依賴的後端基礎服務,他們的性能直接影響到了應用的總體性能,有時候你代碼寫的再好也許就是由於這些服務致使應用性能沒法提高上去。編程
無論是業務應用、依賴的後端服務仍是其餘的各類服務,最終仍是要依賴於底層文件存儲的。一般來講,文件存儲須要知足的特性有:可靠性、容災性、穩定性,即要保證存儲的數據不會輕易丟失,即便發生故障也可以有回滾方案,也要保證高可用。在底層能夠採用傳統的RAID做爲解決方案,再上一層,目前Hadoop的HDFS則是最爲廣泛的分佈式文件存儲方案,固然還有NFS、Samba這種共享文件系統也提供了簡單的分佈式存儲的特性。後端
此外,若是文件存儲確實成爲了應用的瓶頸或者必須提升文件存儲的性能從而提高整個系統的性能時,那麼最爲直接和簡單的作法就是拋棄傳統機械硬盤,用SSD硬盤替代。像如今不少公司在解決業務性能問題的時候,最終的關鍵點每每就是SSD。這也是用錢換取時間和人力成本最直接和最有效的方式。在數據庫部分描述的SSDB就是對LevelDB封裝以後,利用SSD硬盤的特性的一種高性能KV數據庫。
至於HDFS,若是要使用上面的數據,是須要經過Hadoop的。相似xx on Yarn的一些技術就是將非Hadoop技術跑在HDFS上的解決方案。
統一認證中心,主要是對APP用戶、內部用戶、APP等的認證服務,包括
之因此須要統一認證中心,就是爲了可以集中對這些全部APP都會用到的信息進行管理,也給全部應用提供統一的認證服務。尤爲是在有不少業務須要共享用戶數據的時候,構建一個統一認證中心是很是必要的。此外,經過統一認證中心構建移動APP的單點登陸也是水到渠成的事情:模仿Web的機制,將認證後的信息加密存儲到本地存儲中供多個APP使用。
目前不少大的在線Web網站都是有單點登陸系統的,通俗的來講就是隻須要一次用戶登陸,就可以進入多個業務應用(權限能夠不相同),很是方便用戶的操做。而在移動互聯網公司中,內部的各類管理、信息系統甚至外部應用一樣也須要單點登陸系統。
目前,比較成熟的、用的最多的單點登陸系統應該是耶魯大學開源的CAS, 能夠基於 https://github.com/apereo/cas/tree/master/cas-server-webapp 來定製開發的。
基本上,單點登陸的原理都相似下圖所示:
在Java後端應用中,一種讀寫配置比較通用的方式就是將配置文件寫在Propeties、YAML、HCON等文件中,修改的時候只須要更新文件從新部署便可,能夠作到不牽扯代碼層面改動的目的。統一配置中心,則是基於這種方式之上的統一對全部業務或者基礎後端服務的相關配置文件進行管理的統一服務, 具備如下特性:
百度開源的Disconf和攜程的Apollo是能夠在生產環境使用的方案,也能夠根據本身的需求開發本身的配置中心,通常選擇Zookeeper做爲配置存儲。
對於外部API調用或者客戶端對後端API的訪問,可使用HTTP協議或者RESTful(固然也能夠直接經過最原始的socket來調用)。但對於內部服務間的調用,通常都是經過RPC機制來調用的。目前主流的RPC協議有:
這些RPC協議各有優劣點,須要針對業務需求作出最好的選擇。
這樣,當你的系統服務在逐漸增多,RPC調用鏈愈來愈複雜,不少狀況下,須要不停的更新文檔來維護這些調用關係。一個對這些服務進行管理的框架能夠大大減小所以帶來的繁瑣的人力工做。
傳統的ESB(企業服務總線)本質就是一個服務治理方案,但ESB做爲一種proxy的角色存在於Client和Server之間,全部請求都須要通過ESB,使得ESB很容易成爲性能瓶頸。所以,基於傳統的ESB,更好的一種設計以下圖所示:
如圖,以配置中心爲樞紐,調用關係只存在於Client和提供服務的Server之間,就避免了傳統ESB的性能瓶頸問題。對於這種設計,ESB應該支持的特性以下:
阿里開源的Dubbo則對以上作了很好的實現,也是目前不少公司都在使用的方案;噹噹網的擴展項目Dubbox則在Dubbo之上加入了一些新特性。目前,Dubbo已經被阿里貢獻給Apache,處於incubating狀態。在運維監控方面,Dubbo自己提供了簡單的管理控制檯dubbo-admin和監控中心dubbo-monitor-simple。Github上的dubboclub/dubbokeeper則是在其之上開發的更爲強大的集管理與監控於一身的服務管理以及監控系統。
此外,Netflix的Eureka也提供了服務註冊發現的功能,其配合Ribbon能夠實現服務的客戶端軟負載均衡,支持多種靈活的動態路由和負載均衡策略。
在不少業務中,定時調度是一個很是廣泛的場景,好比定時去抓取數據、定時刷新訂單的狀態等。一般的作法就是針對各自的業務依賴Linux的Cron機制或者Java中的Quartz。統一調度中心則是對全部的調度任務進行管理,這樣可以統一對調度集羣進行調優、擴展、任務管理等。Azkaban和Yahoo的Oozie是Hadoop的流式工做管理引擎,也能夠做爲統一調度中心來使用。固然,你也可使用Cron或者Quartz來實現本身的統一調度中心。
對於Java的Quartz這裏須要說明一下:這個Quartz須要和Spring Quartz區分,後者是Spring對Quartz框架的簡單實現也是目前使用的最多的一種調度方式。但其並無作高可用集羣的支持。而Quartz雖然有集羣的支持,可是配置起來很是複雜。如今不少方案都是使用Zookeeper來實現Spring Quartz的分佈式集羣。
此外,噹噹網開源的elastic-job則在基礎的分佈式調度之上又加入了彈性資源利用等更爲強大的功能。
日誌是開發過程必不可少的東西。打印日誌的時機、技巧是很能體現出工程師編碼水平的。畢竟,日誌是線上服務可以定位、排查異常最爲直接的信息。
一般的,將日誌分散在各個業務中很是不方便對問題的管理和排查。統一日誌服務則使用單獨的日誌服務器記錄日誌,各個業務經過統一的日誌框架將日誌輸出到日誌服務器上。
能夠經過實現Log4j或者Logback的Appender來實現統一日誌框架,而後經過RPC調用將日誌打印到日誌服務器上。
數據是最近幾年很是火的一個領域。從《精益數據分析》到《增加黑客》,都是在強調數據的非凡做用。不少公司也都在經過數據推進產品設計、市場運營、研發等。這裏須要說明的一點是,只有當你的數據規模真的到了單機沒法處理的規模才應該上大數據相關技術,千萬不要爲了大數據而大數據。不少狀況下使用單機程序+MySQL就能解決的問題非得上Hadoop即浪費時間又浪費人力。
這裏須要補充一點的是,對於不少公司,尤爲是離線業務並無那麼密集的公司,在不少狀況下大數據集羣的資源是被浪費的。所以誕了 xx on Yarn 一系列技術讓非Hadoop系的技術能夠利用大數據集羣的資源,可以大大提升資源的利用率,如Dockeron Yarn。
接着上面講的統一日誌服務,其輸出的日誌最終是變成數據到數據高速公路上供後續的數據處理程序消費的。這中間的過程包括日誌的收集和傳輸。
收集:統一日誌服務將日誌打印在日誌服務上以後,須要日誌收集機制將其集中起來。目前,常見的日誌收集方案有:Scribe、Chukwa、Kakfa和Flume。對好比下圖所示:
此外,Logstash也是一個能夠選擇的日誌收集方案,不一樣於以上的是,它更傾向於數據的預處理,且配置簡單、清晰,常常以ELK(Elasticsearch + Logstash + Kibana)的架構用於運維場景中。
傳輸:經過消息隊列將數據傳輸到數據處理服務中。對於日誌來講,一般選擇Kafka這個消息隊列便可。
此外,這裏還有一個關鍵的技術就是數據庫和數據倉庫間的數據同步問題,即將須要分析的數據從數據庫中同步到諸如Hive這種數據倉庫時使用的方案。可使用Apache Sqoop進行基於時間戳的數據同步,此外,阿里開源的Canal實現了基於binlog增量同步,更加適合通用的同步場景,可是基於Canal仍是須要作很多的業務開發工做。
離線數據分析是能夠有延遲的,通常針對的是非實時需求的數據分析工做,產生的也是延遲一天的報表。目前最經常使用的離線數據分析技術除了Hadoop還有Spark。相比Hadoop,Spark性能上有很大優點,固然對硬件資源要求也高。其中,Hadoop中的Yarn做爲資源管理調度組件除了服務於MR還能夠用於Spark(Spark on Yarn),Mesos則是另外一種資源管理調度系統。
對於Hadoop,傳統的MR編寫很複雜,也不利於維護,能夠選擇使用Hive來用SQL替代編寫MR。而對於Spark,也有相似Hive的Spark SQL。
此外,對於離線數據分析,還有一個很關鍵的就是數據傾斜問題。所謂數據傾斜指的是region數據分佈不均,形成有的結點負載很低,而有些卻負載很高,從而影響總體的性能。處理好數據傾斜問題對於數據處理是很關鍵的。
相對於離線數據分析,實時數據分析也叫在線數據分析,針對的是對數據有實時要求的業務場景,如廣告結算、訂單結算等。目前,比較成熟的實時技術有Storm和Spark Streaming。相比起Storm,Spark Streaming其實本質上仍是基於批量計算的。若是是對延遲很敏感的場景,仍是應該使用Storm。除了這二者,Flink則是最近很火的一個分佈式實時計算框架,其支持Exactly Once的語義,在大數據量下具備高吞吐低延遲的優點,而且可以很好的支持狀態管理和窗口統計,但其文檔、API管理平臺等都還須要完善。
實時數據處理通常狀況下都是基於增量處理的,相對於離線來講並不是可靠的,一旦出現故障(如集羣崩潰)或者數據處理失敗,是很難對數據恢復或者修復異常數據的。所以結合離線+實時是目前最廣泛採用的數據處理方案。Lambda架構就是一個結合離線和實時數據處理的架構方案。
此外,實時數據分析中還有一個很常見的場景:多維數據實時分析,即可以組合任意維度進行數據展現和分析。目前有兩種解決此問題的方案:ROLAP和MOLAP。
如上一小節所述,ROLAP的方案大多數狀況下用戶離線數據分析,知足不了實時的需求,所以MOLAP是多維數據實時分析的經常使用方案。對於其中經常使用的三個框架,對好比下:
. | 使用場景 | 語言 | 協議 | 特色 |
---|---|---|---|---|
Druid | 實時處理分析 | Java | JSON | 實時聚合 |
Pinot | 實時處理分析 | Java | JSON | 實時聚合 |
Kylin | OLAP分析引擎 | Java | JDBC/OLAP | 預處理、cache |
其中,Druid相對比較輕量級,用的人較多,比較成熟。
離線和實時數據分析產生的一些報表是給數據分析師、產品經理參考使用的,可是不少狀況下,線上的程序並不能知足這些需求方的需求。這時候就須要需求方本身對數據倉庫進行查詢統計。針對這些需求方,SQL上手容易、易描述等特色決定了其多是一個最爲合適的方式。所以提供一個SQL的即席查詢工具可以大大提升數據分析師、產品經理的工做效率。Presto、Impala、Hive都是這種工具。若是想進一步提供給需求方更加直觀的ui操做界面,能夠搭建內部的Hue。
對於面向用戶的線上服務,發生故障是一件很嚴重的事情。所以,作好線上服務的故障檢測告警是一件很是重要的事情。能夠將故障監控分爲如下兩個層面的監控:
監控還有一個關鍵的步驟就是告警。告警的方式有不少種:郵件、IM、短信等。考慮到故障的重要性不一樣、告警的合理性、便於定位問題等因素,有如下建議:
故障告警以後,那麼最最關鍵的就是應對了。對於創業公司來講,24小時待命是必備的素質,當遇到告警的時候,須要儘快對故障作出反應,找到問題所在,並能在可控時間內解決問題。對於故障問題的排查,基本上都是依賴於日誌的。只要日誌打的合理,通常狀況下是可以很快定位到問題所在的,可是若是是分佈式服務,而且日誌數據量特別大的狀況下,如何定位日誌就成爲了難題。這裏有幾個方案: