基于微服务架构,改造企业核心系统之实践
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
1. 背景與挑戰(zhàn)
隨著公司國際化戰(zhàn)略的推行以及本土業(yè)務(wù)的高速發(fā)展,后臺(tái)支撐系統(tǒng)已經(jīng)不堪重負(fù)。在吞吐量、穩(wěn)定性以及可擴(kuò)展性上都無法滿足日益增長的業(yè)務(wù)需求。對(duì)于每10萬元額度的合同,從銷售團(tuán)隊(duì)準(zhǔn)備材料、與客戶簽單、遞交給合同部門,再到合同生效大概需要3.5人天。隨著業(yè)務(wù)量的快速增長,簽訂合同的成本急劇增加。
合同管理系統(tǒng)是后臺(tái)支撐系統(tǒng)中重要的一部分。當(dāng)前的合同系統(tǒng)是5年前使用.NET基于SAGE CRM二次開發(fā)的產(chǎn)品。 一方面,系統(tǒng)架構(gòu)過于陳舊,性能、可靠性無法滿足現(xiàn)有的需求。另一方面,功能繁雜,結(jié)構(gòu)混亂,定制的代碼與SAGE CRM系統(tǒng)耦合度極高。由于是遺留系統(tǒng),熟悉該代碼的人早已離職多時(shí),新團(tuán)隊(duì)對(duì)其望而卻步,只能做些周邊的修補(bǔ)工作。同時(shí),還要承擔(dān)著邊補(bǔ)測(cè)試,邊整理邏輯的工作。
在無法中斷業(yè)務(wù)處理的情況下,為了解決當(dāng)前面臨的問題,團(tuán)隊(duì)制定了如下的策略:
1). 在現(xiàn)有合同管理系統(tǒng)的外圍,構(gòu)建功能服務(wù)接口,將系統(tǒng)核心的功能分離出來。
2). 利用這些功能服務(wù)接口作為代理,解耦原合同系統(tǒng)與其調(diào)用者之間的依賴;
3). 通過不斷構(gòu)建功能服務(wù)接口,逐漸將原有系統(tǒng)分解成多個(gè)獨(dú)立的服務(wù)。
4). 摒棄原有的合同管理系統(tǒng),使用全新構(gòu)建的(微)服務(wù)接口替代。
2. 什么是微服務(wù)
多年來,我們一直在技術(shù)的浪潮中不斷乘風(fēng)破浪,揚(yáng)帆奮進(jìn),尋找更好的方式構(gòu)建IT系統(tǒng)。微服務(wù)架構(gòu)(Micro Service Architect)是近一段時(shí)間在軟件體系架構(gòu)領(lǐng)域里出現(xiàn)的一個(gè)新名詞。它通過將功能分解到多個(gè)獨(dú)立的服務(wù),以實(shí)現(xiàn)對(duì)解決方案或者復(fù)雜系統(tǒng)的解耦。
微服務(wù)的誕生并非偶然: 領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)指導(dǎo)我們?nèi)绾畏治霾⒛P突瘡?fù)雜的業(yè)務(wù);敏捷方法論幫助我們消除浪費(fèi),快速反饋;持續(xù)交付促使我們構(gòu)建更快、更可靠、更頻繁的軟件部署和交付能力;虛擬化和基礎(chǔ)設(shè)施自動(dòng)化( Infrastructure As Code)則幫助我們簡化環(huán)境的創(chuàng)建、安裝;DevOps文化的流行以及特性團(tuán)隊(duì)的出現(xiàn),使得小團(tuán)隊(duì)更加全功能化。這些都是推動(dòng)微服務(wù)誕生的重要因素。
實(shí)際上,微服務(wù)本身并沒有一個(gè)嚴(yán)格的定義。不過從業(yè)界的討論來看,微服務(wù)通常有如下幾個(gè)特征:
小,且專注于做一件事情
每個(gè)服務(wù)都是很小的應(yīng)用,至于有多小,是一個(gè)非常有趣的話題。有人喜歡100行以內(nèi),有人贊成1000行以內(nèi)。數(shù)字并不是最重要的。仁者見仁,智者見智,只要團(tuán)隊(duì)覺得合適就好。只關(guān)注一個(gè)業(yè)務(wù)功能,這一點(diǎn)和我們平常談?wù)摰拿嫦驅(qū)ο笤瓌t中的”單一職責(zé)原則”類似,每個(gè)服務(wù)只做一件事情,并且把它做好。
運(yùn)行在獨(dú)立的進(jìn)程中
每個(gè)服務(wù)都運(yùn)行在一個(gè)獨(dú)立的操作系統(tǒng)進(jìn)程中,這意味著不同的服務(wù)能被部署到不同的主機(jī)上。
輕量級(jí)的通信機(jī)制
服務(wù)和服務(wù)之間通過輕量級(jí)的機(jī)制實(shí)現(xiàn)彼此間的通信。所謂輕量級(jí)通信機(jī)制,通常指基于語言無關(guān)、平臺(tái)無關(guān)的這類協(xié)議,例如XML、JSON,而不是傳統(tǒng)我們熟知的Java RMI或者.Net Remoting等。
松耦合
不需要改變依賴,只更改當(dāng)前服務(wù)本身,就可以獨(dú)立部署。這意味著該服務(wù)和其他服務(wù)之間在部署和運(yùn)行上呈現(xiàn)相互獨(dú)立的狀態(tài)。
綜上所述,微服務(wù)架構(gòu)采用多個(gè)服務(wù)間互相協(xié)作的方式構(gòu)建傳統(tǒng)應(yīng)用。每個(gè)服務(wù)獨(dú)立運(yùn)行在不同的進(jìn)程中,服務(wù)與服務(wù)之間通過輕量的通訊機(jī)制交互,并且每個(gè)服務(wù)可以通過自動(dòng)化部署方式獨(dú)立部署。
3.微服務(wù)的優(yōu)勢(shì)
相比傳統(tǒng)的單塊架構(gòu)系統(tǒng)(monolithic),微服務(wù)在如下諸多方面有著顯著的優(yōu)勢(shì):
異構(gòu)性
問題有其具體性,解決方案也應(yīng)有其針對(duì)性。用最適合的技術(shù)方案去解決具體的問題,往往會(huì)事半功倍。傳統(tǒng)的單塊架構(gòu)系統(tǒng)傾向采用統(tǒng)一的技術(shù)平臺(tái)或方案來解決所有問題。而微服務(wù)的異構(gòu)性,可以針對(duì)不同的業(yè)務(wù)特征選擇不同的技術(shù)方案,有針對(duì)性的解決具體的業(yè)務(wù)問題。
對(duì)于單塊架構(gòu)的系統(tǒng),初始的技術(shù)選型嚴(yán)重限制將來采用不同語言或框架的能力。如果想嘗試新的編程語言或者框架,沒有完備的功能測(cè)試集,很難平滑的完成替換,而且系統(tǒng)規(guī)模越大,風(fēng)險(xiǎn)越高。基于微服務(wù)架構(gòu),使我們更容易在遺留系統(tǒng)上嘗試新的技術(shù)或解決方案。譬如說,可以先挑選風(fēng)險(xiǎn)最小的服務(wù)作為嘗試,快速得到反饋后再?zèng)Q定是否試用于其他服務(wù)。這也意味著,即便對(duì)一項(xiàng)新技術(shù)的嘗試失敗,也可以拋棄這個(gè)方案,并不會(huì)對(duì)整個(gè)產(chǎn)品帶來風(fēng)險(xiǎn)。
該圖引用自Martin Fowler的Microservices一文
獨(dú)立測(cè)試與部署
單塊架構(gòu)系統(tǒng)運(yùn)行在一個(gè)進(jìn)程中,因此系統(tǒng)中任何程序的改變,都需要對(duì)整個(gè)系統(tǒng)重新測(cè)試并部署。 而對(duì)于微服務(wù)架構(gòu)而言,不同服務(wù)之間的打包、測(cè)試或者部署等,與其它服務(wù)都是完全獨(dú)立的。對(duì)某個(gè)服務(wù)所做的改動(dòng),只需要關(guān)注該服務(wù)本身。從這個(gè)角度來說,使用微服務(wù)后,代碼修改、測(cè)試、打包以及部署的成本和風(fēng)險(xiǎn)都比單塊架構(gòu)系統(tǒng)降低很多。
按需伸縮
單塊架構(gòu)系統(tǒng)由于單進(jìn)程的局限性,水平擴(kuò)展時(shí)只能基于整個(gè)系統(tǒng)進(jìn)行擴(kuò)展,無法針對(duì)某一個(gè)功能模塊按需擴(kuò)展。 而服務(wù)架構(gòu)則可以完美地解決伸縮性的擴(kuò)展問題。系統(tǒng)可以根據(jù)需要,實(shí)施細(xì)粒度的自由擴(kuò)展。
錯(cuò)誤隔離性
微服務(wù)架構(gòu)同時(shí)也能提升故障的隔離性。例如,如果某個(gè)服務(wù)的內(nèi)存泄露,只會(huì)影響自己,其他服務(wù)能夠繼續(xù)正常地工作。與之形成對(duì)比的是,單塊架構(gòu)中如果有一個(gè)不合格的組件發(fā)生異常,有可能會(huì)拖垮整個(gè)系統(tǒng)。
團(tuán)隊(duì)全功能化
康威定律(Conway’s law)指出:一個(gè)組織的設(shè)計(jì)成果,其結(jié)構(gòu)往往對(duì)應(yīng)于這個(gè)組織中的溝通結(jié)構(gòu)(organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations)。傳統(tǒng)的開發(fā)模式在分工時(shí)往往以技術(shù)為單位,比如UI團(tuán)隊(duì)、服務(wù)端團(tuán)隊(duì)和數(shù)據(jù)庫團(tuán)隊(duì),這樣的分工可能會(huì)導(dǎo)致任何功能上的改變都需要跨團(tuán)隊(duì)溝通和協(xié)調(diào)。而微服務(wù)則倡導(dǎo)圍繞服務(wù)來分工,團(tuán)隊(duì)需要具備服務(wù)設(shè)計(jì)、開發(fā)、測(cè)試到部署所需的所有技能。
4. 微服務(wù)快速開發(fā)實(shí)踐
隨著團(tuán)隊(duì)對(duì)業(yè)務(wù)的理解加深和對(duì)微服務(wù)實(shí)踐的嘗試,數(shù)個(gè)微服務(wù)程序已經(jīng)成功構(gòu)建出來。不過,問題同時(shí)也出現(xiàn)了:對(duì)于這些不同的微服務(wù)程序而言,雖然具體實(shí)現(xiàn)的代碼細(xì)節(jié)不同,但其結(jié)構(gòu)、開發(fā)方式、持續(xù)集成環(huán)境、測(cè)試策略、部署機(jī)制以及監(jiān)控和告警等,都有著類似的實(shí)現(xiàn)方式。那么如何滿足DRY原則并消除浪費(fèi)呢?帶著這個(gè)問題,經(jīng)過團(tuán)隊(duì)的努力,Stencil誕生了。 Stencil是一個(gè)幫助快速構(gòu)建Ruby微服務(wù)應(yīng)用的開發(fā)框架,主要包括四部分:Stencil模板、代碼生成工具,持續(xù)集成模板以及一鍵部署工具。
Stencil模板
Stencil模板是一個(gè)獨(dú)立的Ruby代碼工程庫,主要包括代碼模板以及一組配置文件模板。
代碼模板使用Webmachine作為Web框架,RESTful和JSON構(gòu)建服務(wù)之間的通信方式,RSpec作為測(cè)試框架。同時(shí),代碼模板還定義了一組Rake任務(wù),譬如運(yùn)行測(cè)試,查看測(cè)試報(bào)告,將當(dāng)前的微服務(wù)生成RPM包,使用Koji給RPM包打標(biāo)簽等。
除此之外,該模板也提供了一組通用的URL,幫助使用者查看微服務(wù)的當(dāng)前版本、配置信息以及檢測(cè)該微服務(wù)程序是否健康運(yùn)行等。
[{rel: "index",path: "/diagnostic/"},{rel: "version",path: "/diagnostic/version"},{rel: "config",path: "/diagnostic/config"},{rel: "hostname",path: "/diagnostic/hostname"},{rel: "heartbeat",path: "/diagnostic/status/heartbeat"},{rel: "nagios",path: "/diagnostic/status/nagios"} ]配置文件模板主要包括NewRelic配置,Passenger配置、Nagios配置、Apache配置以及Splunk配置。通過定義這些配置文件模板,當(dāng)把新的微服務(wù)程序部署到驗(yàn)收環(huán)境或者產(chǎn)品環(huán)境時(shí),我們立刻就可以使用Nagios、NewRelic以及Splunk等第三方服務(wù)提供的功能,幫助我們有效的監(jiān)控微服務(wù),并在超過初始閾值時(shí)獲得告警。
代碼生成工具
借助Stencil代碼生成工具,我們能在很短時(shí)間內(nèi)就構(gòu)建出一個(gè)可以立即運(yùn)行的微服務(wù)應(yīng)用程序。隨著系統(tǒng)越來越復(fù)雜,微服務(wù)程序的不斷增多,Stencil模板和代碼生成工具幫助我們大大簡化了創(chuàng)建微服務(wù)的流程,讓開發(fā)人員更關(guān)注如何實(shí)現(xiàn)業(yè)務(wù)邏輯并快速驗(yàn)證。
Create a project from the stencil template (version 0.1.27)--name, -n <s>: New project name. eg. things-and-stuff--git-owner, -g <s>: Git owner (default: which team or owner)--database, -d: Include database connection code--triggered-task, -t: Include triggered task code--provider, -p: Is it a service provider? (other services use this service)--consumer, -c: Is it a service consumer? (it uses other services)--branch, -b <s>: Specify a particular branch of Stencil--face-palm, -f: Overide name validation --help, -h: Show this message如上代碼所示,通過指定不同參數(shù),我們能創(chuàng)建具有數(shù)據(jù)庫訪問能力的微服務(wù)程序,或者是包含異步隊(duì)列處理的微服務(wù)程序。同時(shí),我們也可以標(biāo)記該服務(wù)是數(shù)據(jù)消費(fèi)者還是數(shù)據(jù)生產(chǎn)者,能幫助我們理解多個(gè)微服務(wù)之間的聯(lián)系。
持續(xù)集成模板
基于持續(xù)集成服務(wù)器Bamboo,團(tuán)隊(duì)創(chuàng)建了針對(duì)Stencil的持續(xù)集成模板工程,并定義了三個(gè)主要階段:
- 打包:運(yùn)行單元測(cè)試,集成測(cè)試,等待測(cè)試通過后生成RPM包。
- 發(fā)布:將RPM包發(fā)布到Koji服務(wù)器上,并打上相應(yīng)的Tag。然后使用Packer在亞馬遜 AWS云環(huán)境中創(chuàng)建AMI,建好的AMI上已經(jīng)安裝了當(dāng)前微服務(wù)程序的最新RPM包。
- 部署:基于指定版本的AMI,將應(yīng)用快速部署到驗(yàn)收環(huán)境或者產(chǎn)品環(huán)境上。
利用持續(xù)集成模板工程,團(tuán)隊(duì)僅需花費(fèi)很少的時(shí)間,就可以針對(duì)新建的微應(yīng)用程序,在Bamboo上快速定義其對(duì)應(yīng)的持續(xù)集成環(huán)境。
一鍵部署工具
所有的微服務(wù)程序都部署并運(yùn)行在亞馬遜AWS云環(huán)境上。同時(shí),我們使用Asgard對(duì)AWS云環(huán)境中的資源進(jìn)行創(chuàng)建、部署和管理。 Asgard是一套功能強(qiáng)大的基于Web的AWS云部署和管理工具,由Netflix采用Groovy on Grails開發(fā),其主要優(yōu)點(diǎn)有:
- 基于B/S的AWS部署及管理工具,使用戶能通過瀏覽器直接訪問AWS云資源,無需設(shè)置Secret Key和Access Key;
- 定義了`Application`以及`Cluster`等邏輯概念,更清晰、有效地描述了應(yīng)用程序在AWS云環(huán)境中對(duì)應(yīng)的部署拓?fù)浣Y(jié)構(gòu)。
- 在對(duì)應(yīng)用的部署操作中,集成了AWS Elastic Load Balancer、AWS EC2以及AWS Autoscaling Group,并將這些資源自動(dòng)關(guān)聯(lián)起來。
- 提供RESTful接口,能夠方便地與其他系統(tǒng)集成。
- 簡潔易用的用戶接口,提供可視化的方式完成一鍵部署以及流量切換。
由于Asgard對(duì)RESTful的良好支持,團(tuán)隊(duì)實(shí)現(xiàn)了一套基于Asgard的命令行部署工具,只需如下一條命令,提供應(yīng)用程序的名稱以及版本號(hào),就可自動(dòng)完成資源的創(chuàng)建、部署、流量切換、刪除舊的應(yīng)用等操作。
asgard-deploy [AppName] [AppVersion]同時(shí),基于命令行的部署工具,也可以很容易的將自動(dòng)化部署集成到Bamboo持續(xù)集成環(huán)境。
通過使用微服務(wù)框架Stencil,大大縮短了團(tuán)隊(duì)開發(fā)微服務(wù)的周期。同時(shí),基于Stencil,我們定義了一套團(tuán)隊(duì)內(nèi)部的開發(fā)流程,幫助團(tuán)隊(duì)的每一位成員理解并快速構(gòu)建微服務(wù)。
微服務(wù)架構(gòu)下的新系統(tǒng)
經(jīng)過5個(gè)月的努力,我們重新構(gòu)建了合同管理系統(tǒng),將之前的產(chǎn)品、價(jià)格、銷售人員、合同簽署、合同審查以及PDF生成都定義成了獨(dú)立的服務(wù)接口。相比之前大而全、難以維護(hù)的合同管理系統(tǒng)而言,新的系統(tǒng)由不同功能的微服務(wù)組成,每個(gè)微服務(wù)程序只關(guān)注單一的功能。每個(gè)微服務(wù)應(yīng)用都有相關(guān)的負(fù)責(zé)人,通過使用Page Duty建立消息通知機(jī)制。每當(dāng)有監(jiān)控出現(xiàn)告警的時(shí)候,責(zé)任人能立即收到消息并快速做出響應(yīng)。
由于微服務(wù)具有高內(nèi)聚,低耦合的特點(diǎn),每個(gè)應(yīng)用都是一個(gè)獨(dú)立的個(gè)體。當(dāng)出現(xiàn)問題時(shí),很容易定位問題并解決問題,大大縮短了修復(fù)缺陷的周期。另外,通過使用不同功能的微服務(wù)接口提供數(shù)據(jù),用戶接口(UI)部分變成了一個(gè)非常簡潔、輕量級(jí)的應(yīng)用,更關(guān)注如何渲染頁面以及表單提交等交互功能。
總結(jié)
通過使用微服務(wù)架構(gòu),在不影響現(xiàn)有業(yè)務(wù)運(yùn)轉(zhuǎn)的情況下,我們有效的將遺留的大系統(tǒng)逐漸分解成不同功能的微服務(wù)接口。同時(shí),通過Stencil微服務(wù)開發(fā)框架,我們能夠快速地構(gòu)建不同功能的微服務(wù)接口,并能方便地將其部署到驗(yàn)收環(huán)境或者產(chǎn)品環(huán)境。最后,得益于微服務(wù)架構(gòu)的靈活性以及擴(kuò)展性,使得我們能夠快速構(gòu)建低耦合、易擴(kuò)展、易伸縮性的應(yīng)用系統(tǒng)。
參考文獻(xiàn)
轉(zhuǎn)載于:https://my.oschina.net/renguijiayi/blog/545541
總結(jié)
以上是生活随笔為你收集整理的基于微服务架构,改造企业核心系统之实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vim快捷键2
- 下一篇: java信息管理系统总结_java实现科