分享某國有大型銀行統(tǒng)一開發(fā)平臺(tái)的建設(shè)歷程,重點(diǎn)介紹其當(dāng)前正在建設(shè)的微服務(wù)開發(fā)平臺(tái)中的關(guān)鍵點(diǎn)和實(shí)踐經(jīng)驗(yàn)。
轉(zhuǎn)載本文需注明出處:微信公眾號EAWorld。
引言:
某銀行是一家國有大型銀行,從2016年開始采用了我們的SOA開發(fā)平臺(tái)作為基礎(chǔ)Java開發(fā)平臺(tái)。
2018年,我們發(fā)布了新一代微服務(wù)開發(fā)平臺(tái)EOS Platform 8,而其正在謀求技術(shù)架構(gòu)轉(zhuǎn)型升級,正好借助我們的新一代微服務(wù)開發(fā)平臺(tái),對已有的SOA架構(gòu)技術(shù)平臺(tái)進(jìn)行升級。
作為該銀行Java開發(fā)平臺(tái)項(xiàng)目的架構(gòu)師,本文我為大家分享其統(tǒng)一開發(fā)平臺(tái)技術(shù)架構(gòu)轉(zhuǎn)型升級的歷程,并結(jié)合銀行重點(diǎn)項(xiàng)目——公司客戶營銷系統(tǒng)的案例,向大家講述微服務(wù)項(xiàng)目建設(shè)的一些實(shí)踐經(jīng)驗(yàn),希望給正在或即將進(jìn)行微服務(wù)架構(gòu)轉(zhuǎn)型的企業(yè)得到一些啟發(fā)。
目錄:
1、統(tǒng)一開發(fā)平臺(tái)建設(shè)歷程
2、微服務(wù)架構(gòu)落地的關(guān)鍵點(diǎn)
3、基于平臺(tái)應(yīng)用實(shí)踐
4、總結(jié)
1.統(tǒng)一開發(fā)平臺(tái)建設(shè)歷程
建設(shè)背景
在經(jīng)濟(jì)新常態(tài)下,國內(nèi)商業(yè)銀行正面臨持續(xù)加深的市場化改革和互聯(lián)網(wǎng)金融大潮的雙重挑戰(zhàn)。同時(shí),國家日益重視銀行業(yè)信息科技風(fēng)險(xiǎn)防范和管理工作,提出信息系統(tǒng)“安全、可控”的戰(zhàn)略目標(biāo)。為應(yīng)對新經(jīng)濟(jì)形勢下的新挑戰(zhàn)和“自主、可控”的新任務(wù),銀行業(yè)需要從以下兩方面來提高自身IT建設(shè)能力:
第一,在IT管理層面,銀行需要建立統(tǒng)一管控體系,實(shí)現(xiàn)項(xiàng)目集中化管理、提升自主掌控能力,降低系統(tǒng)運(yùn)行和維護(hù)風(fēng)險(xiǎn);
第二,在架構(gòu)層面,銀行需要統(tǒng)一的技術(shù)路線、技術(shù)架構(gòu)和數(shù)據(jù)標(biāo)準(zhǔn),不斷積累可復(fù)用的企業(yè)資產(chǎn),提升系統(tǒng)快速交付能力。
建設(shè)過程
該銀行在自主創(chuàng)新上起步很早,長期以來一直堅(jiān)持走國產(chǎn)化和開源軟件的道路。
該銀行自2016年開始圍繞普元EOS+BPS+BIIP進(jìn)行SOA架構(gòu)Java開發(fā)平臺(tái)建設(shè);2017年初發(fā)布Java開發(fā)平臺(tái)1.0版本,截止到2018年,已經(jīng)由40多個(gè)系統(tǒng)基于Java開發(fā)平臺(tái)建設(shè)和上線運(yùn)行; 2017~2018年,圍繞Java開發(fā)平臺(tái),建設(shè)開發(fā)運(yùn)維標(biāo)準(zhǔn)規(guī)范、技術(shù)可研標(biāo)準(zhǔn)規(guī)范、開源技術(shù)選型標(biāo)準(zhǔn)規(guī)范、培訓(xùn)及考試認(rèn)證體系。
但是傳統(tǒng)的SOA項(xiàng)目開發(fā)周期長,彈性伸縮能力弱,系統(tǒng)內(nèi)外間耦合程度高,無法從根本架構(gòu)上滿足銀行向互聯(lián)網(wǎng)銀行轉(zhuǎn)變的需求。作為銀行自主創(chuàng)新的核心,Java開發(fā)平臺(tái)技術(shù)架構(gòu)亟待轉(zhuǎn)型。所以從2018年起,借助我們的新一代微服務(wù)開發(fā)平臺(tái),實(shí)現(xiàn)技術(shù)架構(gòu)升級,并引入Devops提升系統(tǒng)開發(fā)運(yùn)維一體化能力。
2.微服務(wù)架構(gòu)落地的關(guān)鍵點(diǎn)
微服務(wù)落地關(guān)鍵技術(shù)選型
在當(dāng)前市面上存在多個(gè)流行的微服務(wù)框架,要在框架中選擇一款適合自己的微服務(wù)框架。在普元,通過對多個(gè)微服務(wù)框架進(jìn)行比較,最終選擇了SpringCloud作為基礎(chǔ)的微服務(wù)框架。
其中以
Eureka作為服務(wù)注冊中心
SpringBoot作為服務(wù)容器
SWAGGER作為在線文檔自動(dòng)生成+功能測試
Apollo作為配置中心,來提供配置的熱更新功能
使用Vue+IviewUI來支撐前端工程模塊化的開發(fā)
使用Skywaking作為微服務(wù)的監(jiān)控
前后端分離明確分工
在開發(fā)方式上,使用前后端分離的開發(fā)模式。在傳統(tǒng)的開發(fā)模式中,開發(fā)人員急需要關(guān)注后端邏輯的開發(fā),還需要關(guān)注前端頁面的開發(fā),開發(fā)職責(zé)比較混亂。
前后端分離的開發(fā)模式:前端傾向于呈現(xiàn),著重處理用戶體驗(yàn)相關(guān)的問題;后端則傾向于業(yè)務(wù)邏輯、數(shù)據(jù)處理和持久化等。在設(shè)計(jì)清晰的情況下,后端只需要以數(shù)據(jù)為中心對業(yè)務(wù)處理算法負(fù)責(zé),并按約定為前端提供 API 接口;而前端使用這些接口對用戶體驗(yàn)負(fù)責(zé)。
與此同時(shí),前端可以根據(jù)用戶不同時(shí)期的體驗(yàn)需求迅速改版,后端對此毫無壓力。同理,后端進(jìn)行的業(yè)務(wù)邏輯升級,數(shù)據(jù)持久方案變更,只要不影響到接口,前端可以毫不知情。
在前后端分離的開發(fā)模式下,前端和后端應(yīng)該以前端為主導(dǎo)。為什么呢?因?yàn)榍岸碎_發(fā)人員會(huì)受到項(xiàng)目/產(chǎn)品經(jīng)理或客戶的直接影響:這個(gè)地方應(yīng)該放個(gè)按鈕,那個(gè)操作應(yīng)該這么進(jìn)行等等。前端還要與美工對接:這樣的設(shè)計(jì)不好實(shí)現(xiàn),是否可以改成那樣??蛻粢蟊仨氝@么操作,但是這個(gè)設(shè)計(jì)做不到,所以前端還要跟后端對接:對于某些應(yīng)用,甚至是多個(gè)后端。因此前端可以成為項(xiàng)目溝通的中心,比后端更合適承擔(dān)主導(dǎo)的角色。
高可靠高可用確保服務(wù)穩(wěn)定
在微服務(wù)架構(gòu)下,所有的服務(wù)均為無狀態(tài)的。所謂的無狀態(tài)是指對單次請求的處理,不依賴其他請求;也就是說,處理一次請求所需的全部信息,要么都包含在這個(gè)請求里,要么可以從外部獲取到(比如說數(shù)據(jù)庫),服務(wù)器本身不存儲(chǔ)任何信息。使用無狀態(tài)的服務(wù), 服務(wù)實(shí)例可以進(jìn)行多節(jié)點(diǎn)的實(shí)例的部署。
在我們的微服務(wù)架構(gòu)中所有的服務(wù)節(jié)點(diǎn)均使用MM雙節(jié)點(diǎn)配置,并可以進(jìn)行多節(jié)點(diǎn)擴(kuò)展,來達(dá)到服務(wù)的高可用高可靠。
持續(xù)發(fā)布,快速發(fā)布微服務(wù)應(yīng)用
在微服務(wù)的架構(gòu)下,持續(xù)發(fā)布我們面臨的兩大問題:
1、部署流程的多樣性
2、應(yīng)用會(huì)被拆分成多個(gè)微服務(wù),部署到多n個(gè)節(jié)點(diǎn)。如何做到微服務(wù)的持續(xù)發(fā)布,快速響應(yīng)
首先我們將任務(wù)進(jìn)行原子化(如:組件的編譯、打包、數(shù)據(jù)初始化、部署等每一項(xiàng)定義為一個(gè)任務(wù)),這些任務(wù)可進(jìn)行任意的編排。
其次我們通過定義發(fā)布流水線,用戶進(jìn)行發(fā)布流程編排,直接設(shè)置環(huán)境中部署任務(wù)(在部署任務(wù)中設(shè)置具體的組件部署方式,部署配置)、編排環(huán)境的順序等進(jìn)行自由的持續(xù)發(fā)布。
多策略部署,實(shí)現(xiàn)應(yīng)用快速切換
針對微服務(wù)應(yīng)用的快速切換,我們提供多策略的部署方式:
1、滾動(dòng)升級做灰度發(fā)布,對外接口保持不變
2、藍(lán)綠切換,對外接口不變
3、API多版本,對外接口發(fā)生變化
3.基于平臺(tái)應(yīng)用實(shí)踐
Yes Or No, 微服務(wù)架構(gòu)的優(yōu)勢與挑戰(zhàn)?
第一個(gè)需要思考的問題,就是我該不該采用微服務(wù)架構(gòu)來實(shí)施這個(gè)項(xiàng)目?;卮鹪摬辉?,首先來看看微服務(wù)架構(gòu)有那些優(yōu)勢,對我提出了哪些要求,我需不需要它的這個(gè)優(yōu)勢,又能否解決它的問題。
微服務(wù)的優(yōu)勢很明顯,顯著的有以下幾點(diǎn):
1、微服務(wù)業(yè)務(wù)功能簡單,功能邊界清晰,易于開發(fā)、理解和維護(hù)
2、每個(gè)服務(wù)可以由專門的開發(fā)團(tuán)隊(duì)開發(fā),自由選擇技術(shù)棧,如數(shù)據(jù)庫、編程語言
3、服務(wù)間調(diào)用采用的API接口,只要接口不變,內(nèi)部調(diào)整對其他微服務(wù)透明
4、微服務(wù)無狀態(tài)部署,通過注冊中心自動(dòng)發(fā)現(xiàn),可以新增或者移除服務(wù)實(shí)例按需彈性伸縮,橫向擴(kuò)展很容易
5、單個(gè)微服務(wù)十分輕量,啟停速度很快,且便于持續(xù)自動(dòng)化部署
6、每個(gè)微服務(wù)都是獨(dú)立部署,技術(shù)棧選擇自由,所以可以獨(dú)立演進(jìn)
但同樣的它也給項(xiàng)目實(shí)施和運(yùn)維人員提出了更高了要求:
1、開發(fā)測試階段,因?yàn)樯婕胺?wù)依賴,而依賴服務(wù)如果沒有就緒,需要編寫Mock或者擋板
2、微服務(wù)架構(gòu)是天生的分布式架構(gòu),而分布式有它固有的復(fù)雜性,如網(wǎng)絡(luò)延遲、分布式事務(wù)、容錯(cuò)等
3、微服務(wù)數(shù)量多,分散在眾多節(jié)點(diǎn)上,對他們的運(yùn)維監(jiān)控成本大幅提升
4、雖然發(fā)布單個(gè)微服務(wù)很容易,但是一個(gè)微服務(wù)項(xiàng)目往往包含眾多微服務(wù)實(shí)例,且服務(wù)依賴對服務(wù)啟動(dòng)順序有要求,整個(gè)應(yīng)用的發(fā)布相比單體應(yīng)用反而要復(fù)雜
5、一個(gè)業(yè)務(wù)請求牽涉多個(gè)服務(wù)間調(diào)用,出現(xiàn)問題后,如果沒有集中日志收集、調(diào)用鏈路跟蹤,定位問題相比單體應(yīng)用要困難的多
Yes Or No, 那些系統(tǒng)適合采用微服務(wù)架構(gòu)?
根據(jù)上述微服務(wù)架構(gòu)的優(yōu)點(diǎn)和要求,我們可以知道微服務(wù)架構(gòu)并不是萬能的,有它適合采用的系統(tǒng),這些系統(tǒng)包括:
1、對于業(yè)務(wù)流程較為復(fù)雜,且業(yè)務(wù)會(huì)逐漸變得更加復(fù)雜的系統(tǒng),單體應(yīng)用將十分龐大,后期難以修改和維護(hù),應(yīng)考慮使用微服務(wù)架構(gòu)。
2、為了滿足業(yè)務(wù)需求,項(xiàng)目中引入了眾多的技術(shù)棧,中間件,單體應(yīng)用會(huì)給開發(fā)者帶來很大的困擾,應(yīng)考慮將應(yīng)用拆分成多個(gè)獨(dú)立部署的采用最優(yōu)技術(shù)棧實(shí)施的微服務(wù)。
3、高并發(fā)的,有高可用和彈性伸縮需求的系統(tǒng),往往是那些面向龐大數(shù)量互聯(lián)網(wǎng)用戶的平臺(tái)類、交易類系統(tǒng),應(yīng)考慮利用微服務(wù)架構(gòu)便于橫向擴(kuò)展和彈性伸縮的特性。
4、單體應(yīng)用版本發(fā)布成本高,而單個(gè)微服務(wù)的變更和發(fā)布都很容易,那些有高頻率版本發(fā)布需求的系統(tǒng),應(yīng)使用微服務(wù)架構(gòu)。
5、沒有數(shù)據(jù)實(shí)時(shí)強(qiáng)一致要求,可接受數(shù)據(jù)最終一致的系統(tǒng),可使用微服務(wù)架構(gòu)。
How,單體到微服務(wù)怎么拆?
經(jīng)過一番比對,這個(gè)項(xiàng)目適合采用微服務(wù)架構(gòu)。那么該怎么對項(xiàng)目進(jìn)行服務(wù)拆分呢,拆分到什么粒度為止呢?
18年初,某銀行使用微服務(wù)開發(fā)平臺(tái)建設(shè)公司客戶營銷項(xiàng)目,首先面臨的問題就是微服務(wù)如何拆分,結(jié)合我們的經(jīng)驗(yàn),提出了以下5個(gè)拆分原則:
1、按照業(yè)務(wù)拆分
按照業(yè)務(wù)來拆分微服務(wù)是很自然的,將同類業(yè)務(wù)劃歸一個(gè)微服務(wù),有利于開發(fā)人員理解需求和開發(fā)(不同的業(yè)務(wù)由不同的開發(fā)人員來開發(fā)),同時(shí)清晰的功能邊界天生具有高內(nèi)聚的優(yōu)點(diǎn),避免了微服務(wù)間頻繁的遠(yuǎn)程調(diào)用,提升了性能和穩(wěn)定性。
2、按照請求數(shù)拆分
某些服務(wù)被頻繁調(diào)用,而某些服務(wù)很少被調(diào)用,頻繁調(diào)用的服務(wù)可考慮與很少被調(diào)用的服務(wù)隔離出來獨(dú)立部署。
3、常變與不變
某些服務(wù)可能很頻繁的因需求的變更而頻繁發(fā)布新版本和上線,為避免影響那些不變的服務(wù),這些頻繁變化的服務(wù)應(yīng)當(dāng)隔離出來獨(dú)立部署。
4、避免過度拆分
如果發(fā)現(xiàn)某些服務(wù)頻繁的相互調(diào)用,說明這兩個(gè)服務(wù)所屬的業(yè)務(wù)由很緊密的耦合關(guān)系,考慮合并為一個(gè)服務(wù)。
5、避免分布式事務(wù)
如果服務(wù)間存在多方更新的情況,即A調(diào)用B,A又調(diào)用C或者B又調(diào)用C,B和C均要更新數(shù)據(jù)庫,且B和C要求同時(shí)成功或者同時(shí)失敗,則出現(xiàn)了多方更新,應(yīng)考慮合并B和C。
How,微服務(wù)怎么開發(fā)?
微服務(wù)劃分完了,是不是可以進(jìn)入開發(fā)了呢? 進(jìn)入開發(fā)前,首先要看一看平臺(tái)提供了那些基礎(chǔ)能力,這些是不需要重復(fù)去開發(fā)的。
我們目前在這家銀行正在建設(shè)的微服務(wù)開發(fā)平臺(tái),建設(shè)有包括微服務(wù)開發(fā)IDE、服務(wù)注冊中心、配置中心、API網(wǎng)關(guān)、認(rèn)證鑒權(quán)中心、日志中心、管理監(jiān)控中心等基礎(chǔ)服務(wù)組件,項(xiàng)目組只需關(guān)心自身業(yè)務(wù)微服務(wù)的開發(fā)。
采用敏捷開發(fā)模式,每個(gè)微服務(wù)組件開發(fā)由1到2人負(fù)責(zé),每日通過持續(xù)集成日構(gòu)建,快速迭代開發(fā)。
公司客戶營銷項(xiàng)目也是基于微服務(wù)開發(fā)平臺(tái)進(jìn)行建設(shè),建設(shè)中做了以下約定:
1、前后端分離+Rest通信,前端采用Vue,后端采用Spring Boot,Rest+Json通信;
2、使用平臺(tái)提供的API網(wǎng)關(guān)統(tǒng)一接入,前后端通信、系統(tǒng)間的服務(wù)調(diào)用都要經(jīng)過API網(wǎng)關(guān),網(wǎng)關(guān)上做負(fù)載、限流、調(diào)用認(rèn)證鑒權(quán)中心服務(wù)做用戶身份認(rèn)證和權(quán)限校驗(yàn);
3、Rest服務(wù)返回的對象統(tǒng)一,包含Http Status狀態(tài)碼和消息體,Service和Ctroller直接拋出業(yè)務(wù)異常,業(yè)務(wù)異常統(tǒng)一為一種類型的運(yùn)行時(shí)異常,通過Spring MVC的統(tǒng)一異常處理機(jī)制,向前端返回狀態(tài)為200包含異常提示信息的結(jié)果(之所以返回200,是因?yàn)闃I(yè)務(wù)異常屬于用戶輸入導(dǎo)致的,服務(wù)正常工作,避免熔斷計(jì)數(shù)和降級);
4、采用JWT+Redis做身份認(rèn)證和權(quán)限校驗(yàn),JWT token在HTTP Header中傳遞,Redis中存放注銷后的token,解決用戶注銷后Token未過期的問題。 并且在網(wǎng)關(guān)上增加攔截器,對用戶Token做過半刷新;
5、對數(shù)據(jù)庫做了拆分,微服務(wù)訪問自己的數(shù)據(jù)庫。 數(shù)據(jù)源配置存在配置中心集中管理,但是不做熱更新,需要微服務(wù)重啟后才能生效。
How,微服務(wù)怎么測試?
開發(fā)伴隨著測試,沒有經(jīng)過測試的代碼等于是無效代碼。微服務(wù)的測試與單體應(yīng)用不同,前后端、服務(wù)間都是Rest接口,如果A服務(wù)依賴了服務(wù)B,而服務(wù)B還沒有開發(fā)完成怎么辦?
公司客戶營銷項(xiàng)目時(shí),微服務(wù)之間有依賴關(guān)系,為了不受依賴服務(wù)的制約,在雙方商定好Rest接口后,由服務(wù)提供方開發(fā)Mock服務(wù),供消費(fèi)方使用, Mock服務(wù)同樣注冊到注冊中心。
開發(fā)人員使用Postman自測自己開發(fā)的服務(wù)。
版本發(fā)布人員專人負(fù)責(zé)每日構(gòu)建,利用Jekins+Maven+SonaQube自動(dòng)執(zhí)行單元測試和代碼檢查。
開發(fā)后期,測試人員利用LoadRunner和Jmeter做壓力測試。
How,微服務(wù)怎么發(fā)布?
在該銀行公司客戶營銷項(xiàng)目建設(shè)過程中,使用我們的Devops平臺(tái),對微服務(wù)做每日構(gòu)建和自動(dòng)發(fā)布。
Devops平臺(tái)在開發(fā)測試環(huán)境上搭建一套,為不同項(xiàng)目組開通租戶即可使用。Devops持續(xù)集成的技術(shù)棧使用的是Jenkins+Maven+Nexus+SonarQube。在Devops前端頁面上創(chuàng)建自動(dòng)部署計(jì)劃,利用Ansible腳本,將打出的部署包自動(dòng)部署在目標(biāo)機(jī)器上,自動(dòng)啟動(dòng)。
前端項(xiàng)目自動(dòng)發(fā)布在Nginx,后端微服務(wù)打包成Fatjar發(fā)布到目標(biāo)服務(wù)器上,利用Spring Boot內(nèi)置容器Tomcat啟動(dòng)。
#目前這套環(huán)境僅在開發(fā)測試環(huán)境上使用。
How,微服務(wù)怎么監(jiān)控?
公司客戶營銷項(xiàng)目利用平臺(tái)提供的日志中心(ELK技術(shù)棧)做日志集中收集和分析。 平臺(tái)自動(dòng)記錄全局流水號、請求流水號和響應(yīng)流水號到日志文件,F(xiàn)ilebeat與微服務(wù)部署在一起,收集到的日志首先發(fā)送到Kafka集群,Logstash從Kafka獲取日志記錄,經(jīng)過過濾、加工(補(bǔ)充了幾個(gè)索引字段,如類型)后發(fā)送到ElasticSearch,最后從Kibana上呈現(xiàn)。
采用開源軟件Skywalking實(shí)現(xiàn)微服務(wù)調(diào)用鏈路跟蹤、服務(wù)進(jìn)程JVM、線程和負(fù)載的監(jiān)控。平臺(tái)提供了管理監(jiān)控頁面,從ElasticSearch中獲取監(jiān)控信息,在Governor頁面呈現(xiàn)。
對于項(xiàng)目中自定義的一些業(yè)務(wù)監(jiān)控,項(xiàng)目組自行組裝消息發(fā)送到MQ,利用該銀行自有的業(yè)務(wù)監(jiān)控平臺(tái),集中展示。
4.總結(jié)
微服務(wù)架構(gòu)是當(dāng)前互聯(lián)網(wǎng)公司普遍采用的技術(shù)架構(gòu),且正在快速地延伸到互聯(lián)網(wǎng)金融行業(yè)。微服務(wù)架構(gòu)技術(shù)優(yōu)勢明顯,但技術(shù)門檻較高,我們的新一代微服務(wù)開發(fā)平臺(tái)整合一系列優(yōu)秀開源技術(shù),形成一套微服務(wù)架構(gòu)落地的最佳實(shí)踐,幫助某銀行安全快速地實(shí)現(xiàn)了技術(shù)架構(gòu)的一次轉(zhuǎn)型升級。