閱讀原文:【技術(shù)分享】微服務(wù)開發(fā)的幸福感,是如何提升的?
點(diǎn)擊關(guān)注“八戒技術(shù)團(tuán)隊(duì)”,閱讀更多技術(shù)干貨
隨著微服務(wù)的流行,越來越多公司使用了微服務(wù)架構(gòu),但由于公司業(yè)務(wù)的特殊性、技術(shù)棧的歷史原因等,都需要選擇一個(gè)適合自己公司的服務(wù)開發(fā)框架,對(duì)框架進(jìn)行規(guī)范定義,集成自研組件和系統(tǒng),讓業(yè)務(wù)迭代實(shí)現(xiàn)更快速,讓開發(fā)人員使用更便捷。
本文將基于SpringBoot,從框架約束、自研中間件集成、強(qiáng)類型客戶端、接口文檔等多個(gè)方面介紹服務(wù)框架的設(shè)計(jì)與實(shí)踐。
一、背景介紹
公司后端服務(wù)是以Java生態(tài)為主,有基于Dubbo的RPC服務(wù)、基于SpringBoot的HTTP服務(wù)兩種開發(fā)模式,所有服務(wù)基于K8S的容器云雙機(jī)房獨(dú)立部署,支持雙活流量的架構(gòu)。
結(jié)合公司上下文環(huán)境、業(yè)務(wù)規(guī)模,綜合考慮技術(shù)棧統(tǒng)一、服務(wù)治理、使用成本等多方面的因素,經(jīng)過多部 商議,確定將“基于SpringBoot開發(fā)HTTP服務(wù)”作為主要開發(fā)模式。公司每天都有一些新的微服務(wù)產(chǎn)生,很多自研組件服務(wù)和中間件系統(tǒng),需要服務(wù)開發(fā)者單獨(dú)接入,為了規(guī)范和簡(jiǎn)化后端服務(wù)開發(fā)者集成應(yīng)用,一套規(guī)范、集成的開發(fā)框架就變得非常有必要。
二、基于SpringBoot的服務(wù)框架設(shè)計(jì)
1、如何統(tǒng)一規(guī)范框架的使用?
統(tǒng)一規(guī)范可以通過默認(rèn)約定、強(qiáng)制校驗(yàn)、自動(dòng)內(nèi)嵌等多種方式來實(shí)現(xiàn),下面將分別舉例說明。
統(tǒng)一管理依賴包(默認(rèn)約定)
基于Maven的依賴包管理,通過Partent統(tǒng)一定義依賴包及版本,默認(rèn)引入必須的依賴包和插件。創(chuàng)建工程自動(dòng)生成代碼時(shí),默認(rèn)約定繼承Parent,開發(fā)者只需引入必要的Starter即可,開發(fā)者可以修改繼承關(guān)系,但不推薦。
依賴包的統(tǒng)一管理,可以避免不同版本包沖突的麻煩,也方便后期公司統(tǒng)一升級(jí)依賴包和版本。
統(tǒng)一參數(shù)格式(強(qiáng)制校驗(yàn))
返回參數(shù)都繼承BaseResponse,請(qǐng)求參數(shù)都繼承BaseRequest。強(qiáng)制校驗(yàn)接口服務(wù)來保證參數(shù)規(guī)范性,在工程啟動(dòng)時(shí)自動(dòng)檢測(cè),不遵循規(guī)范的工程將無法正常啟動(dòng),繞過校驗(yàn)的工程不納入公司后端體系,很多核心能力均無法正常使用。
統(tǒng)一參數(shù)格式,不僅可以同時(shí)支持HTTP調(diào)用、強(qiáng)類型客戶端,同時(shí)規(guī)避了HTTP接口的濫用,簡(jiǎn)化規(guī)范了錯(cuò)誤處理。
統(tǒng)一處理異常(自動(dòng)內(nèi)嵌)
通過Spring的RestControllerAdvice可以對(duì)全局異常統(tǒng)一捕獲,并對(duì)異常統(tǒng)一處理。異常處理自動(dòng)內(nèi)嵌到核心包中,只要使用該框架,就自動(dòng)生效。
統(tǒng)一異常處理,不僅規(guī)范了異常返回格式,兼容了強(qiáng)類型客戶端,日志統(tǒng)一記錄,并對(duì)返回的異常信息進(jìn)行脫敏處理。
2、如何簡(jiǎn)化自研中間件組件和系統(tǒng)的集成?
所有中間件依賴包都在Parent中統(tǒng)一管理,對(duì)于自研的通用類組件(比如日志組件、線程池組件、web安全組件、自研的工具類組件等),默認(rèn)在Parent中已引入,開發(fā)者可以直接使用。
公司有很多自研的中間件組件或系統(tǒng),或者根據(jù)公司環(huán)境二次開發(fā)過的開源組件,只能按照公司的特定的方式進(jìn)行接入使用,有一定的接入成本。為了接入更方便,都做成了可插拔的組件,通過Starter方式進(jìn)行接入。
使用Starter方式,簡(jiǎn)化了依賴、簡(jiǎn)化了配置、簡(jiǎn)化了接入代碼。
作為后端服務(wù),核心能力是對(duì)外提供服務(wù),或者調(diào)用其他服務(wù)。如果使用REST方式訪問遠(yuǎn)程HTTP接口,難以將接口管理起來,當(dāng)接口變動(dòng)的時(shí)候可能需要修改多處。
在技術(shù)調(diào)研過程中,我們發(fā)現(xiàn)SpringCloud提供了OpenFeign來解決這個(gè)問題。
3、如何實(shí)現(xiàn)強(qiáng)類型的HTTP客戶端?
OpenFeign是一種聲明式、模板化的HTTP客戶端,在Spring Cloud中使用OpenFeign,只需要定義接口和注解,可以做到使用HTTP請(qǐng)求訪問遠(yuǎn)程服務(wù),就像調(diào)用本地方法一樣。
但OpenFeign和我們公司技術(shù)環(huán)境不一致,加上太多歷史項(xiàng)目也無法支持OpenFeign,于是我們借鑒OpenFeign思想,基于開源Fegin開發(fā)了適合公司環(huán)境的ZbjFeign,支持在SpringBoot和普通Spring環(huán)境中使用。
雖然實(shí)現(xiàn)了聲明式調(diào)用,如果每次都要寫接口定義和注解,還是很不方便。為了解決這個(gè)問題,我們開發(fā)了一鍵發(fā)布Client包功能,通過掃描Controller接口方法元數(shù)據(jù),基于ZbjFeign生成接口調(diào)用Client,構(gòu)建打包發(fā)布到公司Maven倉庫。后端開發(fā)者只需引入一個(gè)包,就可以像調(diào)用本地接口一樣調(diào)用遠(yuǎn)程HTTP接口。對(duì)于前端NodeJS調(diào)用,也生成了對(duì)應(yīng)的生成物,支持前端框架的“強(qiáng)類型”調(diào)用。如果開發(fā)者要看接口文檔,我們也提供全公司統(tǒng)一、完整的接口文檔。
4、如何實(shí)現(xiàn)文檔的統(tǒng)一管理?
公司所有文檔都是基于Confluence進(jìn)行管理的,接口文檔也不例外,于是我們也實(shí)現(xiàn)了在發(fā)布階段,一鍵發(fā)布接口文檔。后臺(tái)實(shí)現(xiàn)也是自動(dòng)掃描Controller接口元數(shù)據(jù),通過模版生成HTML片段,并提交到Confluence。接口文檔中提供了Java強(qiáng)類型客戶端調(diào)用、HTTP調(diào)用兩種方式的參考。
Client和文檔都有了,接下來我們通過案例看一下如何使用。
三、框架使用案例
1、Starter的使用案例
通過Starter方式使用分布式消息隊(duì)列 RabbitMq,只需要引入Starter,就可以直接使用了。
第一步:引入依賴Starter。
第二步:消費(fèi)者監(jiān)聽隊(duì)列消息。無需做任何配置,具體代碼如下。
說明:公司的RabbitMQ是經(jīng)過二次開發(fā)的,不是通過“地址+賬號(hào)”訪問,而是通過申請(qǐng)的業(yè)務(wù)ID進(jìn)行訪問。
2、強(qiáng)類型客戶端使用案例
只需要引入Client包,無需做任何配置,就可以像調(diào)本地方法一樣調(diào)HTTP服務(wù)。
第一步:引入Client依賴。
第二步:直接通過強(qiáng)類型進(jìn)行HTTP接口調(diào)用,就像本地方法一樣。
說明:客戶端包生產(chǎn)時(shí)內(nèi)置了遠(yuǎn)端服務(wù)的域名,如果發(fā)生變化可以從自研的配置中心修改。
四、未來框架的思考和展望
最后,給大家分享一下關(guān)于未來工作,我們的一些思考與規(guī)劃,還不太成熟,拋出來和大家探討一下。
1、服務(wù)治理本文未涉及到服務(wù)治理相關(guān)部分(熔斷、限流等),是因?yàn)榭紤]到解耦、靈活性等多方面因素,我們并沒打算像Dubbo或者SpringCloud, 通過代碼庫方式耦合在應(yīng)用程序生命周期中,而是從應(yīng)用生命周期脫 離出來,下沉到基礎(chǔ)設(shè)施或者網(wǎng)絡(luò)層,進(jìn)行統(tǒng)一治理。
2、應(yīng)用可觀測(cè)性微服務(wù)架構(gòu)中,故障可能出現(xiàn)在任何地方,做可觀測(cè)系統(tǒng)已經(jīng)在我們 計(jì)劃中,通過日志、鏈路跟蹤、度量等手段,讓各數(shù)據(jù)之間產(chǎn)生更多的關(guān)聯(lián),使每一次 App 點(diǎn)擊所產(chǎn)生的多次服務(wù)調(diào)用耗時(shí)、返回值和參數(shù)都清晰可 ,甚至可以下鉆到第三方軟件調(diào)用、SQL請(qǐng)求、節(jié)點(diǎn)拓?fù)洹⒕W(wǎng)絡(luò)響應(yīng)等信息中。運(yùn)維、開發(fā)和業(yè)務(wù)人員通過這樣的觀測(cè)能力可以實(shí)時(shí)掌握軟件的運(yùn)行情況,并獲得前所未有的關(guān)聯(lián)分析能力,以便不斷優(yōu)化業(yè)務(wù)的健康度和用戶體驗(yàn)。
3、框架持續(xù)演進(jìn)如今,技術(shù)與業(yè)務(wù)都發(fā)展非常快,后端框架也會(huì)在一定范圍內(nèi)不斷升級(jí)重構(gòu),以適應(yīng)變化的技術(shù)和業(yè)務(wù)需求。本框架設(shè)計(jì)都是面向服務(wù)接口調(diào)用,未來可能也會(huì)引入消息驅(qū)動(dòng)設(shè)計(jì),處理一些異步化的場(chǎng)景, 甚至重構(gòu)升級(jí)為事件驅(qū)動(dòng)的架構(gòu)。當(dāng)然,在業(yè)務(wù)高速迭代的情況下, 也需要考慮架構(gòu)演進(jìn)與業(yè)務(wù)發(fā)展之間的平衡。
希望以上內(nèi)容能對(duì)有需要的人有所幫助
歡迎大家留言寫下自己希望了解的技術(shù)方向
歡迎大家一起探討交流