-
1 # 手機使用者100113927652
-
2 # IT實戰聯盟
一個小團隊就能真正能落地的微服務架構實踐!
編者的話
微服務是否真的適合小團隊這裡不多做爭辯。但是透過現象看本質,隨著產品版本的不斷迭代、業務複雜度的提高最終都會導致單體應用越來越龐大,總會超過單體架構的負荷。那麼使用微服務分而治之就成為一個不得不面對的問題。所以這麼龐大的單體應用拆分出多個小應用也更符合這種分治的思想。雖然這些不是小團隊能夠考慮到的事情,但是如果能在產品的初期階段能夠規劃好產品的架構體系那麼在慢慢演變的過程中會越來越順手,團隊的戰鬥力也打造的越來越強。
一、背景
1、單體應用
起步的時候開發人員只有2、3人,並沒有考慮微服務之類的(多餘)。但是整體架構採用了SPA式的前後端分離法,單純的從物理層做區分(認為只要是客戶端的就是前端,伺服器端的就是後端),這種分法不能滿足前後端分離的需求,認為從技術職責上劃分才能滿足目前我們的使用場景。
由於團隊資源有限後端人員往往擔任前端的一些開發任務,所以採用瞭如下職責劃分:
前端:負責View和Controller層。
後端:只負責Model層,業務處理/資料等。
優點:可以做url design,我們可以根據場景決定在服務端同步渲染,還是根據view層資料輸出json資料,我們還可以根據表現層需求很容易的做Bigpipe,Comet,Socket等等,完全是需求決定使用方式。
缺點:需要前端來寫Controller,以Java語言開發為例,需要前端學會Java開發,這樣在處理複雜的業務邏輯的產品裡雙方都有Java 程式碼方面的重疊。
伺服器部署上,採用Nginx代理前端HTML資源,在接收請求時根據路徑反向代理到服務埠達到實現業務目的,如下圖所示:
採用RESTful Api和Json搭建前後臺互動
備註:後臺提供一組設計原則和約束條件,介面透過swagger生成文件進行介面測試和聯調。
2、開發過程遇到的問題
2.1 半持續整合
由於團隊成員之間沒有共事過的經歷,對於開發模式、質量管控和開發流程都需要重新開始制定。針對這種情況開發初期沒有進行引入非常完整的整合測試體系,主要是針對介面進行單元測試(Unit Test)、編寫測試用例和人工Review。
2.2 引進Jenkins持續整合工具
Jenkins功能包括:
1、持續的軟體版本釋出/測試專案。
2、監控外部呼叫執行的工作。
兩種啟動方式
第一種:切換到jenkins.war存放的目錄,輸入如下命令:$ java -jar jenkins.war如果需要修改埠可以使用如下命令:$ java -jar jenkins.jar--httpPort=8081然後在瀏覽器中輸入localhost:8081,localhost可以是本機的ip,也可以是計算機名。就可以開啟jenkins。第二種:解壓tomcat到某個目錄,如/usr/local,進入tomcat下的/bin目錄,啟動tomcat將jenkins.war檔案放入tomcat下的webapps目錄下,啟動tomcat時,會自動在webapps目錄下建立jenkins目錄,在位址列上需要輸入localhost:8080/jenkins。
持續整合
執行步驟:
開發人員提交程式碼進入gerrit中;Jenkins被觸發開始編譯程式碼並執行整合測試;完成後生成測試報告;測試透過再由reviewer進行程式碼Review;在單體應用時代這樣的CI架構已經足夠好用,由於有整合測試的覆蓋,在保持API相容性的前提下進行程式碼重構都將變得更有信心。
三、微服務時代
1 服務拆分原則
1.1 公共庫的初始化拆分
我們把公共的庫都放在common裡面,這裡麵包括了log,config,errors等基礎庫,還有redis,mysql,mongodb等db的連線池初始化,還有rpc的連線池初始化,這裡或者用grpc或者使用者自己基於go自帶的rpc的二次封裝等。還有trace等用於追蹤請求方便日誌查詢的基本庫。
這些基礎庫是我們做微服務的必備,在搭建一個新專案的時候,前期需求討論評審完成後,編碼前期,我們會先把這些公共庫的初始化工作都做了,比如db的一些連線池初始化不同專案稍微有一些不同。rpc等連線池程式碼基本都是能複用的。其他的公共庫,直接拖到新專案裡就能開搞,大大的規範了程式碼質量和減少開發週期。
1.2 根據業務職責拆分
其實微服務的拆分最根本是一些程式碼職責的拆分和抽象,這一步和我們模組化的時候思路是一樣的。我們將按照要開發的業務功能拆分為不同的專案,而負責不同功能的研發人員就可以在自己的程式碼專案上進行開發,從而解決了大家無法在開發階段並行開發的苦惱。
如上圖所示,可以拆分為使用者中心、產品中心和訂單中心等,支撐整體業務的基礎服務業可以相應的進行拆分。
1.3 各元件之間介面的定義(重點講)
公共庫和各個業務職責搞清楚後,接下來還不要著急寫程式碼,我們先把各個元件之間介面定義清楚。不然各自寫各自的,最後還是一團亂麻。
先做到以下幾點:
1.3.1 介面協議選型。
- 現在微服務流行採用的http協議restful介面(語言無關)。
- RMI遠端介面呼叫(Java語言支援)。
- 大資料傳遞採用檔案離線下載的方式(FTP)。
- 狀態資料(如果進度條)放在Redis中共享快取。
- 資料庫共享。一般來說微服務的資料庫是隔離的,不同微服務不允許直接訪問彼此的資料庫。如涉及大資料有效能問題時可特殊考慮。
備註:如果為防止資料被人抓包分析,需要有相對應的加解密處理方案。
1.3.2 定義介面內容。
介面內容包含介面名稱(url)、輸入引數、返回值、錯誤碼。一個典型的restful介面內容定義如下:
備註:code:100代表成功,message:描述說明,result:返回詳細資訊可以一般是json格式
1.3.3 明確介面效能。
介面效能包括:介面單次響應時間、單次查詢返回記錄條數和每秒支援呼叫次數等。資料量比較大的查詢介面一把都會設計成分頁查詢,需要定義好單次查詢返回的最大記錄條數。
微服務介面的支撐能力是有限的,必須定義好單位時間內允許的最大請求次數(超過請求次數就不響應或者返回錯誤碼),否則海量的請求一下湧過來,服務就掛了。對於特殊的服務,還會根據實際情況設定一天的請求次數上限等。
1.3.4 做好介面管理。
上面說了要做那麼多事情那麼能不能用好並且是持續的用好,介面管理是非常重要的。
介面管理包括:介面版本管理、介面許可權管理、介面管控等;
為什麼要做介面版本管理?
大家都知道同一個介面隨著產品的不斷迭代、需求的不斷變更都可能面臨介面升級(不管是新增還是相容)。但是不管怎麼升級都需要相容舊的業務使用,為了管理好就需要透過版本號來解決。例如:在URL中帶上不同的版本號,需要使用新特性的可以呼叫新版本的介面;不使用新特性的可以仍然沿用舊版本介面。
為什麼要做介面許可權管理?
對外發布的介面都需要做許可權控制,未授權的服務是不允許訪問的。可以採用在介面的header引數中加上加密的token作為許可權認證。
後續當整個系統越來越龐大複雜後,各微服務釋出的介面需要做視覺化管理,包含服務的註冊、釋出、呼叫、下線都需要在統一的運維平臺上操作。
為什麼要做介面管控?
前面提到的介面版本管理對介面不同版本的相容處理是不可能不限支援下去的。釋出舊版本介面的下線公告到期後,如果在監控平臺上發現舊版本介面已無人呼叫就可以下線了,如果還有人呼叫則可以通知他進行限期整改。
1.4 開始分工寫自己的元件
這樣就可以分配任務編寫程式碼啦。每個開發人員都是相對獨立的開發,並且介面也定義好了,公共庫也都已經初始化完畢,然後開發就是完全並行了。編寫完之後,自己的元件可以依靠單元測試,做一些基本的測試。然後聯調即可。
2 技術框架選擇
來看一下經典的微服務架構圖:
主要包含11大核心元件,分別是:
核心支撐元件
服務閘道器Zuul服務註冊發現Eureka+Ribbon服務配置中心Apollo認證授權中心Spring Security OAuth服務框架Spring MVC/Boot監控反饋元件
資料匯流排Kafka日誌監控ELK呼叫鏈監控CATMetrics監控KairosDB健康檢查和告警ZMon限流熔斷和流聚合Hystrix/Turbine看到這裡是不是想說:“尼瑪,這是幾個人小團隊能玩起來的?確定不是讓我們996 變 007 嗎?”,我也想說我們也不是用的這個,一般是給別人吹牛用的,哈哈哈哈!
我們來看下面這張技術架構圖,大家會好理解許多。
這張圖大部分業務都通用,根據團隊自身情況去選擇技術來滿足業務需求。
四、總結
還是那句話,技術棧沒有好壞之分,只有適合一說。本文推薦的技術棧主要基於我個人的實踐和總結,但是未必適合所有場景,畢竟每個企業的上下文各不相同。作為架構師你可以參考我推薦的技術棧,但不可拘泥照搬,你必須在深入理解分佈系統原理的基礎上,再結合企業實際場景靈活應用。
貢獻者
-
3 # 使用者5702379994320
微服務架構系統靈活性,健壯性,擴充套件性好,特別適合需求變化迅速的場景。但系統複雜度高,部署,管理難度大。微服務除了開發期框架之外,還有需要一系列的執行期中介軟體支撐,如API閘道器,服務註冊中心,統一配置中心等。 目前國內比較成熟的吧,東軟有一支團隊在做,他們網站是 https://platform.neusoft.com/
回覆列表
微服務除了開發期框架之外,還有需要一系列的執行期中介軟體支撐,如API閘道器,服務註冊中心,統一配置中心等。 目前國內比較成熟的,東軟有一支團隊在做,可以參考一下,他們網站是 platform.neusoft.com