前言
愛因斯坦說過“耐心和恒心總會得到報酬的”,我也一直把這句話當做自己的座右銘,這句箴言在今年也徹底在“我”身上實作了。
每一個程式員都擁有一座大廠夢,我也不例外,去年面試螞蟻金服,竟然被MySQL問倒了,很多相關性的問題都沒有答上來,才2面就涼涼了。回去之後也潛心複習了,準備了二戰,如今終于進入了螞蟻金服,被錄用。
以下展示的阿裡面試題(含答案)、學習包、實戰文檔等,均可以分享給大家!
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-Q1QSkMfZ-1621307712341)(//upload-images.jianshu.io/upload_images/20355010-72148a6757ccbf3f.jpg?imageMogr2/auto-orient/strip|imageView2/2/w/640/format/webp)]
微服務是什麼
微服務起源于2005年Peter Rodgers博士在雲端運算博覽會提出的微Web服務(Micro-Web-Service),根本思想類似于Unix的管道設計理念。2014年,由Martin Fowler 與 James Lewis共同提出了微服務的概念,定義了微服務架構風格是一種通過一套小型服務來開發單個應用的方法,每個服務運作在自己的程序中,并通過輕量級的機制進行通訊(HTTP API)。關鍵的三點是small、automated以及lightweight。
對比SOA,微服務可以看做是SOA的子集,是輕量級的SOA,粒度更細的服務,獨立程序、資料分離,更注重靈活、持續傳遞、DevOps以及去中心化實踐。其共同的架構原理:
- 單一職責
-
關注分離:
控制與邏輯相分離
- 子產品化和分而治之
特點:
- 用服務進行元件化
- 圍繞業務能力進行組織
- 是産品而非項目
- 端點智能化和啞管道: 控制邏輯都在端點,管道僅僅是傳輸
- 全自動化部署
- 語言和資料的去中心化控制
- 面向失敗設計
- 漸進式設計
綜合來看,其優缺點如下:
優點:
- 子產品的強邊界
- 獨立部署
- 技術選型的多樣性
缺點:
- 分布式帶來程式設計複雜度,遠端調用的消耗
- 舍棄強一緻性,實作最終一緻性
- 操作複雜性要求有一個成熟的運維團隊或者運維基礎設施
為什麼要采用微服務
是否選擇微服務取決于你要設計的系統的複雜度。微服務是用來把控複雜系統的,但是随之而來的就是引入了微服務本身的複雜度。需要解決包括自動化部署、監控、容錯處理、最終一緻性等其他分布式系統面臨的問題。即使已經有一些普遍使用的解決方案,但是仍然是有不小的成本的。
生産力和複雜度的關系如圖所示,可見系統越複雜,微服務帶來的收益越大。此外,無論是單體應用還是微服務,團隊的技能都需要能夠把控住。
馬丁.福勒的一個觀點是:除非管理單體應用的成本已經太複雜了(太大導緻很難修改和部署),否則都不要考慮微服務。大部分應用都應該選擇單體架構,做好單體應用的子產品化而不是拆分成服務。
是以,系統一開始采用單體架構,做好子產品化,之後随着系統變得越來越複雜、子產品/服務間的邊界越來越清晰,再重構為微服務架構是一個合理的架構演化路徑。
四個可以考慮上微服務的情況:
- 多人開發一個子產品/項目,送出代碼頻繁出現大量沖突。
- 子產品間嚴重耦合,互相依賴,每次變動需要牽扯多個團隊,單次上線需求太多,風險大。
- 主要業務和次要業務耦合,橫向擴充流程複雜。
- 熔斷降級全靠if-else。
微服務的三個階段:
-
微服務1.0:
僅使用注冊發現,基于SpringCloud或者Dubbo進行開發。
-
微服務2.0:
使用了熔斷、限流、降級等服務治理政策,并配備完整服務工具和平台。
-
微服務3.0:
Service Mesh将服務治理作為通用元件,下沉到平台層實作,應用層僅僅關注業務邏輯,平台層可以根據業務監控自動排程和參數調整,實作AIOps和智能排程。
微服務架構
先決條件
-
快速的環境提供能力:
依賴于雲計算、容器技術,快速傳遞環境。
-
基本的監控能力:
包括基礎的技術監控和業務監控。
-
快速的應用部署能力:
需要部署管道提供快速的部署能力。
-
Devops文化:
需要具有良好的持續傳遞能力,包括全鍊路追蹤、快速環境提供和部署等,還需要快速的反應能力(對問題、故障的快速響應),開發和運維的協同工作。
此外,根據康威定律和逆康威定律(技術架構倒逼組織架構改進),組織架構也是一個很關鍵的因素。對應于微服務架構,組織架構需要遵循以下原則:
- 一個微服務由一個團隊維護,團隊成員以三人為宜。
- 單個團隊的任務和發展是獨立的,不受其他因素影響。
- 團隊是功能齊全、全棧、自治的,扁平、自我管理。
基礎設施
微服務的推行需要依賴于很多底層基礎設施,包括提供微服務的編譯、內建、打包、部署、配置等工作,采用PaaS平台解決微服務從開發到運作的全生命周期管理,同時提供異構環境管理、容器資源隔離與互通、服務伸縮漂移、服務更新與回退、服務熔斷與降級、服務注冊與發現。
- 最基本的基礎設施
-
程序間通訊機制:
微服務是獨立程序的,需要确定之間的通訊方式。
- 服務發現+服務路由: 提供服務注冊中心,服務提供者和消費者通過服務發現擷取服務的資訊進而調用服務,實作服務的負載均衡等。
-
服務容錯:
微服務架構中,由于服務非常多,往往是一個服務挂了,整個請求鍊路的服務都受到影響,是以需要服務容錯,在服務調用失敗的時候能夠處理錯誤或者快速失敗,包括熔斷、fallback、重試、流控和服務隔離等。
-
分布式事務支援:
随着業務拆分為服務,那麼有時候不可避免的就是跨服務的事務,即分布式事務的問題。
原則是盡量避免分布式事務,如果無法避免那麼可以使用消息系統或者CQRS和Event Sourcing方案來實作最終一緻性。
如果需要強一緻性,則有兩階段送出、三階段送出、TCC等分布式事務解決方案。
- 提升外部服務對接效率和内部開發效率
-
API網關: 負責外部系統的通路,負責跨橫切面的公共層面的工作,包括安全、日志、權限控制、傳輸加密、請求轉發、流量控制等。
典型的網關功能即對外暴露一個域名xx.com,根據第一級目錄做反向路由xx.com/user,xx.com/trade。
每一級目錄,如user、trade對應一個服務的域名。
此外,API網關也可以有服務編排的功能(不推薦)。
- 接口架構: 規範服務之間通訊使用的資料格式、解析包、自解釋文檔,便于服務使用方快速上手等。
- 提升測試和運維效率
-
持續內建:
這一部分并非是微服務特定的,對于之前的單體應用,此部分一般來說也是必要的。
主要是指通過自動化手段,持續地對代碼程序編譯建構、自動化測試,以得到快速有效的品質回報,進而保證代碼的順利傳遞。
自動化測試包括代碼級别的單元測試、單個系統的內建測試、系統間的接口測試。
-
自動化部署:
微服務架構,節點數動辄上百上千,自動化部署能夠提高部署速度和部署頻率,進而保證持續傳遞。
包括版本管理、資源管理、部署操作、復原操作等功能。
而對于微服務的部署方式,包括藍綠部署、滾動部署以及金絲雀部署。
-
配置中心: 運作時配置管理能夠解決動态修改配置并批量生效的問題。
包括配置版本管理、配置項管理、節點管理、配置同步等。
-
持續傳遞:
包括持續內建、自動化部署等流程。
目的就是小步疊代,快速傳遞。
- 進一步提升運維效率
-
服務監控: 微服務架構下節點數目衆多,需要監控的機器、網絡、程序、接口等的數量大大增加,需要一個強大的監控系統,能夠提供實時搜集資訊進行分析以及實時分析之上的預警。
包括監控服務的請求次數、響應時間分布、最大/最小響應值、錯誤碼分布等
-
服務跟蹤:
跟蹤一個請求的完整路徑,包括請求發起時間、響應時間、響應碼、請求參數、傳回結果等資訊,也叫做全鍊路跟蹤。
通常的服務監控可以和服務監控做在一起,宏觀資訊由服務跟蹤呈現,微觀單個服務/節點的資訊由服務監控呈現。
服務跟蹤目前的實作理論基本都是Google的Dapper論文。
-
服務安全:
内網之間的微服務調用原則上講應該是都可以互相通路寫,一般并不需要權限控制,但有時候限于業務要求,會對接口、資料等方面有安全控制的要求。
此部分可以以配置的方式存在于服務注冊中心中,和服務綁定,在請求時由做為服務提供者的服務節點進行安全政策控制。
配置則可以存儲在配置中心以友善動态修改。
在微服務數量很少的情況下,以上基礎設施的優先級自上而下降低。否則,僅僅依賴人工操作,則投入産出比會很低。
還需要提到的是Docker容器技術。雖然這個對于微服務并不是必須的,但是容器技術輕量級、靈活、與應用依存、屏蔽環境差異的特性對于持續傳遞的實作是至關重要的,即使對于傳統的單體應用也能夠給其帶來傳遞效率的大幅提升。
架構設計模式
在引入微服務之後,傳統的單體應用變為了一個一個服務,之前一個應用直接提供接口給用戶端通路的架構不再适用。微服務架構下,針對不同裝置的接口做為BFF層(Backend For Frontend),也叫做使用者體驗适配層,負責聚合、編排微服務的資料轉換成前端需要的資料。服務之間的調用則在允許的情況下(允許延遲)盡可能使用異步消息傳遞方式,如此形成面向使用者體驗的微服務架構設計模式。如下圖所示:
Client -> API Gateway -> BFF(Backend For Frontend) -> Downstream Microservices
- 背景采用微服務架構,微服務可以采用不同的程式設計語言和不同的存儲機制。
- 前台采用BFF模式對不同的使用者體驗(如桌面浏覽器,Native App,平闆響應式Web)進行适配。
- BFF、API Orchestration Layer,Edge Service Layer,Device Wrapper Layer是相同的概念。
- BFF不能過多,過多會造成代碼邏輯重複備援。
- 可以将網關承擔的功能,如Geoip、限流、安全認證等跨橫切面功能和BFF做在同一層,雖然增加了BFF層的複雜性,但能夠得到性能優勢。
服務拆分
微服務架構最核心的環節,主要是對服務的橫向拆分。服務拆分就是講一個完整的業務系統解耦為服務,服務需要職責單一,之間沒有耦合關系,能夠獨立開發和維護。
服務拆分不是一蹴而就的,需要在開發過程中不斷地理清邊界。在完全理清服務之前,盡量推遲對服務的拆分,尤其是對資料庫的拆分。
拆分方法如下:
- 基于業務邏輯拆分
- 基于可擴充拆分
- 基于可靠性拆分
- 基于性能拆分
其中,對于無法修改的遺留系統,采用絞殺者模式:在遺留系統外面增加新的功能做成微服務方式,而不是直接修改原有系統,逐漸的實作對老系統替換。
拆分過程需要遵守的規範如下:
- 先少後多、先粗後細(粒度)
-
服務縱向拆分最多三層,兩次調用:
Controller、組合服務、基礎服務
- 僅僅單向調用,禁止循環調用
- 串行調用改為并行調用或者異步化
- 接口應該幂等
- 接口資料定義嚴禁内嵌,透傳
- 規範化工程名
- 先拆分服務,等服務粒度确定後再拆分資料庫。
微服務架構
上面講述了微服務架構的衆多基礎設施,如果每一個基礎設施都需要自己開發的話是非常巨大的開發工作。目前市面上已經有不少開源的微服務架構可以選擇。
-
Spring Boot
Spring Boot是用來簡化新Spring應用的初始搭建以及開發過程的。其雖然不是微服務架構,但其設計的初衷本質就是微應用的底層架構,是以非常适合用于微服務基礎設施的開發以及微服務的應用開發。尤其對于Spring技術棧的團隊來說,基于Spring Boot開發微服務架構和應用是自然而然的一個選擇。
-
Dubbo&&Motan
Dubbo阿裡開源的服務治理架構。其出現在微服務理念興起之前,可以看做是SOA架構的集大成之作。但其僅僅包含了微服務基礎設施的部分功能,諸如熔斷、服務跟蹤、網關等都沒有實作。
Motan則是微網誌開源的類似Dubbo的RPC架構,與Dubbo相比更輕量級。
-
服務發現 :
服務釋出、訂閱、通知
-
高可用政策 :
失敗重試(Failover)、快速失敗(Failfast)、資源隔離 - 負載均衡 :
最少活躍連接配接、一緻性 Hash、随機請求、輪詢等
-
擴充性 :
支援 SPI 擴充(service provider interface)
-
其他 :
調用統計、通路日志等
-
Spring Cloud
Spring Cloud是基于Spring Boot實作的微服務架構,也可以看做一套微服務實作規範。基本涵蓋了微服務基礎設施的方方面面,包括配置管理、服務發現、斷路器、智能路由、微代理、控制總線、全局鎖、決策競選、分布式會話和叢集狀态管理等。其基于Spring生态,社群支援非常好。但其很多元件都沒有經過生産環境驗證,需要慎重選擇。
Spring Cloud Netflix是Spring Cloud的一個子項目,是Spring對Netflix OSS的內建實作。基于Netflix的大規模使用,其中的已經被廣泛使用的元件包括:
此外,另一個子項目Spring Cloud Alibaba則是Alibaba開源的基于Spring Boot的微服務架構,主要是對阿裡雲服務的支援。
-
Eureka:
服務注冊和服務發現
-
Ribbon:
彈性而智能的程序間和服務通訊機制,用戶端負載均衡
-
Hystrix:
熔斷器,在運作時提供延遲和容錯的隔離
- Zuul: 服務網關
-
Service Mesh
上述的微服務架構都是侵入式的,服務化的過程都需要進行代碼改造。Service Mesh則是下一代微服務架構,最明顯的特征就是無入侵。采用sidecar模式來解決系統架構微服務化後的服務間通信和治理問題。如下圖所示:
目前主流的開源實作包括:
限于Service Mesh帶來的性能延遲的開銷以及sidecar對分布複雜性的增加,其對大規模部署(微服務數目多)、異構複雜(互動協定/開發語言類型多)的微服務架構帶來的收益會更大。
-
Linkerd和Envoy:
以 sidecar 為核心,關注如何做好proxy,并完成一些通用控制平面的功能。
缺乏對這些sidecar的管理和控制。
-
Istio和Conduit:
目前最為流行的Service Mesh實作方案,集中在更加強大的控制平面(sidecar被稱為資料平面)功能。
前者由Google和IBM合作,并使用了Envoy作為sidecar部分的實作;
後者則是Linkerd作者的作品。
相比起來,Istio有巨頭背景,功能強大,但可用性和易用性一直不高,Conduit則相對簡單、功能聚焦。
-
Sofastack
螞蟻金服開源的建構金融級分布式架構的一套中間件。包括微服務開發架構、RPC架構、服務注冊中心、全鍊路追蹤、服務監控、Service Mesh等一整套分布式應用開發工具。
特别值得一提的是SOFAMesh。其是對下一代微服務架構Service Mesh的大規模落地方案實踐,基于 Istio改進和擴充而來,應該是國内最為成熟的開源Service Mesh方案。
此外,需要提到Kubernetes(K8s),其本身提供了部分的微服務特性支援(通過域名做服務發現),對代碼無侵入。但服務調用、熔斷這些都需要自己實作。
綜上,目前公司技術團隊技術棧是Spring,并且已有服務的實作都是基于Dubbo,是以選擇Spring Cloud Netflix做為基礎的微服務架構,對其中不成熟或者缺乏的元件,選擇業界更為成熟的元件替代即可。
-
API網關:
Zuul
-
服務注冊中心:
Dubbo
-
配置中心:
disconf
-
服務監控&&全鍊路追蹤:
CAT
-
服務開發架構:
Spring Boot
-
日志監控、告警:
ELK + Elasalert
-
流量控制:
Sentinel
-
消息隊列:
Kafka
最後
按照上面的過程,4個月的時間剛剛好。當然Java的體系是很龐大的,還有很多更進階的技能需要掌握,但不要着急,這些完全可以放到以後工作中邊用别學。
學習程式設計就是一個由混沌到有序的過程,是以你在學習過程中,如果一時碰到了解不了的知識點,大可不必沮喪,更不要氣餒,這都是正常的不能再正常的事情了,不過是“人同此心,心同此理”的暫時而已。
“道路是曲折的,前途是光明的!”
-
服務開發架構:
Spring Boot
-
日志監控、告警:
ELK + Elasalert
-
流量控制:
Sentinel
-
消息隊列:
Kafka
最後
按照上面的過程,4個月的時間剛剛好。當然Java的體系是很龐大的,還有很多更進階的技能需要掌握,但不要着急,這些完全可以放到以後工作中邊用别學。
學習程式設計就是一個由混沌到有序的過程,是以你在學習過程中,如果一時碰到了解不了的知識點,大可不必沮喪,更不要氣餒,這都是正常的不能再正常的事情了,不過是“人同此心,心同此理”的暫時而已。
“道路是曲折的,前途是光明的!”
[外鍊圖檔轉存中…(img-6adglTRl-1621307712351)]
[外鍊圖檔轉存中…(img-mfNRvjkR-1621307712351)]
更多Java核心筆記、真實面經、學習筆記等知識幹貨可以點選這裡免費領取