微服務(wù)落地,我們?cè)诳紤]什么?

2021-02-14    分類: 網(wǎng)站建設(shè)

微服務(wù)已經(jīng)成為過去幾年軟件架構(gòu)設(shè)計(jì)的“事實(shí)標(biāo)準(zhǔn)”,大多數(shù)企業(yè)在推動(dòng)內(nèi)部數(shù)字化轉(zhuǎn)型的過程中,服務(wù)軟件系統(tǒng)開始由單一或者SOA服務(wù)向微服務(wù)轉(zhuǎn)型。那么轉(zhuǎn)型過程需要遵循哪些原則呢?本文結(jié)合過往博云微服務(wù)落地實(shí)踐經(jīng)驗(yàn),分享微服務(wù)落地實(shí)踐的過程中思考。

目前當(dāng)技術(shù)人員提及微服務(wù)的時(shí)候,首先想到的是Spring Cloud、Dubbo等實(shí)現(xiàn)服務(wù)的技術(shù)框架。這在我們采用微服務(wù)的初期階段是最先考慮的因素??墒请S著服務(wù)化的進(jìn)行,我們并沒有享受到由框架的便利性與快捷性所帶來的業(yè)務(wù)突飛猛進(jìn)的成就感。恰恰相反,過多的服務(wù)化以及服務(wù)間冗余且多元化通信機(jī)制反而加重了業(yè)務(wù)處理的負(fù)擔(dān)。這必然不是我們想要的微服務(wù),卻是大多數(shù)企業(yè)在執(zhí)行的微服務(wù)。

微服務(wù)落地,我們?cè)诳紤]什么?

因此我們開始重新審視整個(gè)行業(yè),審視微服務(wù)的發(fā)展歷程。與過往不同的是:前期階段,我們把更多的精力投入到業(yè)務(wù)上,而一定程度上“忽略”技術(shù),因?yàn)榇藭r(shí)我們建立的信念是無論何種形式的“服務(wù)形態(tài)”一定是為業(yè)務(wù)服務(wù)的。

當(dāng)我們站在全局的角度,觀看整理后的服務(wù),發(fā)現(xiàn)了一個(gè)及其優(yōu)美的圖形化結(jié)構(gòu),各個(gè)節(jié)點(diǎn)的邊界清晰,職責(zé)分明;節(jié)點(diǎn)間的鏈路暢通,協(xié)議規(guī)整。這時(shí)我們知道我們終于走在了正確的道路上。

我們遵循的原則

當(dāng)經(jīng)過一定時(shí)間的掙扎以后,我們覺得微服務(wù)的關(guān)注點(diǎn)不在于技術(shù)本身,但并不意味著不關(guān)注技術(shù)。在反思過程中,我們認(rèn)為微服務(wù)實(shí)踐中有兩個(gè)原則不能變:服務(wù)一定是圍繞業(yè)務(wù)的,服務(wù)的交互是標(biāo)準(zhǔn)的。我們把原則分為兩個(gè)階段:初期階段,實(shí)踐階段。

初期階段

初期階段,遵循第一條原則,服務(wù)一定是圍繞業(yè)務(wù)的。微服務(wù)初期階段,重要的是業(yè)務(wù)梳理,而不是花費(fèi)大量時(shí)間在RPC、Service Discovery、 Circuit Breaker這些概念或者Eureka,Docker,Gateway,Dubbo等技術(shù)框架的調(diào)研上,此時(shí)我們重心關(guān)注服務(wù)的邊界與職責(zé)劃分。

這是遵循的兩條原則:

  • 保證單一業(yè)務(wù)服務(wù)高效聚合;
  • 降低服務(wù)間的相互調(diào)用(此舉是避免陷入大量分布式業(yè)務(wù)的處理)。

這樣的原則下,DDD為我們提供了幫助,也依據(jù)業(yè)務(wù)本身的特性實(shí)現(xiàn)了服務(wù)初期階段的整理。同時(shí)我們發(fā)現(xiàn)就算借助DDD的指導(dǎo),在不同的業(yè)務(wù)應(yīng)用中,各個(gè)服務(wù)也有不同的聚合形態(tài)和調(diào)用方式。因此我們覺得微服務(wù)本身沒有一成不變的模式,一切都是圍繞業(yè)務(wù)動(dòng)態(tài)變化的。合理性也僅僅體現(xiàn)在一定階段的時(shí)間范圍之內(nèi)。

實(shí)踐階段

當(dāng)業(yè)務(wù)建模完成,我們能夠清晰的知道各個(gè)業(yè)務(wù)的職責(zé)以及與其他業(yè)務(wù)的關(guān)聯(lián)關(guān)系,從理論層面我們完成了業(yè)務(wù)微服務(wù)建模。此時(shí)我們開始著手服務(wù)的落地實(shí)踐,在落地實(shí)踐階段我們更多關(guān)注點(diǎn)同樣不在于技術(shù)框架,而是在于技術(shù)框架的內(nèi)涵-即服務(wù)交互標(biāo)準(zhǔn)。

此時(shí)我們遵循了第二條原則:服務(wù)的交互是標(biāo)準(zhǔn)的。所謂服務(wù)交互標(biāo)準(zhǔn)從三個(gè)層面解讀:協(xié)議標(biāo)準(zhǔn),框架標(biāo)準(zhǔn),接口標(biāo)準(zhǔn)。

協(xié)議標(biāo)準(zhǔn)

目前網(wǎng)絡(luò)應(yīng)用的協(xié)議比較復(fù)雜,我們希望選取能夠符合業(yè)務(wù)場(chǎng)景的協(xié)議作為通信標(biāo)準(zhǔn)。因此我們考慮了統(tǒng)一的認(rèn)證鑒權(quán)協(xié)議、加密解密協(xié)議、內(nèi)部接口交互協(xié)議,外圍接口服務(wù)協(xié)議等,各個(gè)協(xié)議各司其職,用來支撐服務(wù)通信的標(biāo)準(zhǔn)化。協(xié)議標(biāo)準(zhǔn)不僅僅為平臺(tái)自身服務(wù),同時(shí)與其他業(yè)務(wù)單元進(jìn)行通信時(shí),只需要遵循協(xié)議標(biāo)準(zhǔn),就可以實(shí)現(xiàn)業(yè)務(wù)單元之間的快速聯(lián)動(dòng)。

框架標(biāo)準(zhǔn)

為了支撐業(yè)務(wù),我們沒有依賴任何的自動(dòng)化代碼生成框架,而是根據(jù)我們的協(xié)議支持情況,選擇最小的服務(wù)運(yùn)行框架,來構(gòu)建統(tǒng)一的業(yè)務(wù)單元支撐框架。這里需要說明的一點(diǎn),框架標(biāo)準(zhǔn)需要考慮業(yè)務(wù)特性,協(xié)議特性,不能一概而論,因此它的有效性也許只在當(dāng)前構(gòu)建的業(yè)務(wù)平臺(tái)本身。構(gòu)建標(biāo)準(zhǔn)框架的好處是針對(duì)應(yīng)用內(nèi)的所有業(yè)務(wù)單元可以快速復(fù)制,簡化因?yàn)楦髯蚤_發(fā)框架不同導(dǎo)致聯(lián)調(diào)階段出現(xiàn)問題。

接口標(biāo)準(zhǔn)

接口分兩種:業(yè)務(wù)內(nèi)部接口和業(yè)務(wù)服務(wù)接口。無論哪種接口同樣遵循標(biāo)準(zhǔn)化原則。

業(yè)務(wù)內(nèi)部接口的核心在于壓縮協(xié)議,加快業(yè)務(wù)的處理流程,因此可以采用RPC等高效率的協(xié)議支持的接口模式;業(yè)務(wù)服務(wù)接口的核心在于表明業(yè)務(wù)攜帶的信息,因此采用restful接口規(guī)范更合適一些。接口設(shè)計(jì)需要涵蓋但不限于標(biāo)準(zhǔn)化的請(qǐng)求方式、統(tǒng)一的參數(shù)處理、統(tǒng)一的結(jié)果返回、統(tǒng)一的異常處理、統(tǒng)一的日志處理等。

服務(wù)拆分與聚合

前提:服務(wù)拆分與聚合在本篇文章中暫時(shí)不考慮web的微服務(wù)化設(shè)計(jì),只說明后端服務(wù)的拆分與聚合實(shí)踐。

服務(wù)拆分與聚合需要遵循的原則:服務(wù)一定是圍繞業(yè)務(wù)的。但事實(shí)情況是,在現(xiàn)在追求“開源整合”的背景下,純粹的業(yè)務(wù)單元在不借助第三方工具的前提下,需要消耗巨大的代價(jià)才能實(shí)現(xiàn)業(yè)務(wù)需求,同時(shí)也出現(xiàn)不同業(yè)務(wù)單元對(duì)同一個(gè)工具的強(qiáng)依賴性。因此在服務(wù)拆分與聚合時(shí),我們考慮了兩種形態(tài)的實(shí)現(xiàn)方式:業(yè)務(wù)支撐與工具支撐。

業(yè)務(wù)支撐

業(yè)務(wù)支撐需要考慮的是業(yè)務(wù)服務(wù)對(duì)象和業(yè)務(wù)內(nèi)部邏輯。業(yè)務(wù)服務(wù)對(duì)象作為整個(gè)業(yè)務(wù)單元的對(duì)外形態(tài),通過命名能夠清晰的表達(dá)其涵蓋的業(yè)務(wù)范圍;業(yè)務(wù)內(nèi)部邏輯需要對(duì)業(yè)務(wù)單元進(jìn)行細(xì)粒度的拆分,類似一個(gè)實(shí)體類可以包括多個(gè)其他相關(guān)聯(lián)的實(shí)體對(duì)象(當(dāng)然如果服務(wù)拆分的足夠細(xì)化,也可以把內(nèi)部邏輯作為獨(dú)立的業(yè)務(wù)單元,但是這樣會(huì)加重業(yè)務(wù)直接的通信負(fù)載)?;跇I(yè)務(wù)內(nèi)部邏輯構(gòu)建業(yè)務(wù)服務(wù)對(duì)象的真實(shí)場(chǎng)景。具體的拆分細(xì)節(jié)可以依賴DDD的實(shí)踐方法進(jìn)行(當(dāng)然也需要根據(jù)業(yè)務(wù)做相應(yīng)調(diào)整,沒有普世之道)。

工具支撐

工具支撐需要結(jié)合業(yè)務(wù)考慮,分為兩種:通用性工具和專用性工具。通用性工具旨在為所有業(yè)務(wù)單元運(yùn)行提供統(tǒng)一的支撐平臺(tái),從而減少由于工具維護(hù)花費(fèi)的精力,使得業(yè)務(wù)開發(fā)人員聚焦業(yè)務(wù)實(shí)現(xiàn),一般通用工具包包括統(tǒng)一日志處理,統(tǒng)一攔截處理,返回?cái)?shù)據(jù)統(tǒng)一封裝,異常統(tǒng)一處理等等;專用性工具聚焦某個(gè)具體的業(yè)務(wù)單元,由業(yè)務(wù)單元自身維護(hù)(例如迭代升級(jí))。工具支撐層面不會(huì)提供對(duì)外restful或者rpc的接口,對(duì)外的表現(xiàn)形式為編譯好的依賴工具包(例如Github的管理接口的封裝)。

服務(wù)架構(gòu)選型

依照?qǐng)?zhí)行原則完成服務(wù)拆分以后,我們需要考慮的是合適的落地選型。選型方案要考慮的因素有很多:技術(shù)背景(尤其是團(tuán)隊(duì)內(nèi)編程語言的設(shè)定),服務(wù)支撐工具(注冊(cè)中心,網(wǎng)關(guān),服務(wù)調(diào)用,負(fù)載均衡數(shù)據(jù)庫等),服務(wù)運(yùn)行工具(tomcat,jetty,jboss等),服務(wù)部署工具(物理部署,虛擬化,容器等),工具的協(xié)議支撐集合(http,rpc,mtqq,idoc等)。但是無論如何選型最終一定要結(jié)合團(tuán)隊(duì)開發(fā)人員當(dāng)下的技能支撐,這也是我們選型的核心因素,因?yàn)榘缀邢鄬?duì)來說始終比黑盒安全,也相對(duì)可控。

這里給出我們的技術(shù)棧選型框架(僅限我們熟悉的內(nèi)容),暫時(shí)不涉及技術(shù)框架的對(duì)比說明。

  • 服務(wù)開發(fā)框架:springboot,dubbo,grpc,ServiceMesh(基于ServiceMesh的開發(fā)服務(wù)框架)
  • 分布式存儲(chǔ)/注冊(cè)中心:Zookeeper,Consul,Eureka,Etcd
  • 服務(wù)網(wǎng)關(guān):Kong,Openresty,Spring cloud Zuul,Spring cloud gateway
  • 負(fù)載均衡:nginx,spring cloud Ribbon,haproxy,Kubernetes service
  • 服務(wù)遠(yuǎn)程調(diào)用:Spring cloud feign
  • 緩存服務(wù):memchace,redis
  • 數(shù)據(jù)庫:mariadb,mysql
  • 消息服務(wù):RabbitMQ,NATS,Kafka
  • 配置中心:spring cloud config,Apollo,Consul
  • 事件機(jī)制:Cloud Event
  • 服務(wù)編排:Conductor ,Kubernetes
  • 服務(wù)治理:spring cloud,Dubbo,ServiceMesh

基于消息機(jī)制的分布式事務(wù)處理(遵循CAP或者BASE理論模型的實(shí)現(xiàn))

  • 業(yè)務(wù)運(yùn)行工具:jvm,nginx或者其他可運(yùn)行環(huán)境支撐
  • 開發(fā)編譯工具:Jenkins,maven,gitlab
  • 接口文檔:Swagger
  • 部署工具:物理部署(jar包或者可運(yùn)行的編譯的二進(jìn)制文件)虛擬化部署(虛擬鏡像模板)容器化部署(Docker)

我們?cè)诼涞氐倪^程中,根據(jù)團(tuán)隊(duì)技術(shù)特點(diǎn)開發(fā)階段重點(diǎn)選擇了Spring Cloud中涵蓋的技術(shù)棧。方便易用,能夠快速入手。運(yùn)行階段選擇具備服務(wù)編排能力的Kubernetes容器化運(yùn)行環(huán)境,并且結(jié)合Devops工具鏈能夠快速迭代部署。

服務(wù)接口設(shè)計(jì)

服務(wù)接口是對(duì)外展現(xiàn)業(yè)務(wù)邏輯的唯一入口,接口定義的規(guī)范與否也是微服務(wù)落地的關(guān)鍵指標(biāo)之一,我們?cè)趯?shí)踐的過程中參考了多個(gè)開源項(xiàng)目的接口設(shè)計(jì),針對(duì)任何一個(gè)資源對(duì)象,整體分為幾類場(chǎng)景:資源集合類操作,資源實(shí)體操作,異常處理,參數(shù)處理,統(tǒng)一數(shù)據(jù)返回,審計(jì)日志以及其他具體場(chǎng)景。

統(tǒng)一的接口請(qǐng)求與響應(yīng)標(biāo)準(zhǔn)

其中業(yè)務(wù)單元絕大多數(shù)端口圍繞著資源集合類、資源實(shí)體類進(jìn)行操作,因此我們從restful接口規(guī)范出發(fā),結(jié)合具體場(chǎng)景,規(guī)范了請(qǐng)求方式,請(qǐng)求url,請(qǐng)求參數(shù),請(qǐng)求header,響應(yīng)header,響應(yīng)值等信息。

請(qǐng)求參數(shù)涵蓋默認(rèn)語義,包括:Get(獲取信息),Post(創(chuàng)建),Put(全量修改),Patch(部分修改),Delete(刪除)

以Students實(shí)體對(duì)象的新建為例,給出請(qǐng)求與響應(yīng)標(biāo)準(zhǔn)。

URL

URL請(qǐng)求包括三部分:請(qǐng)求方式,統(tǒng)一前綴以及具體url,統(tǒng)一前綴具備一定含義的命名規(guī)則,包括api申明,供應(yīng)商標(biāo)識(shí),版本說明等必要信息,例如:

Post /api/cloud/v1/students?exist={skip,replace}

請(qǐng)求header

  • type
  • aplication/json:用于single和bulk時(shí),用來表示請(qǐng)求數(shù)據(jù)為json格式
  • application/vnd.ms-excel:從excel格式的文件導(dǎo)入創(chuàng)建
  • Accept
  • aplication/json:接受json格式的響應(yīng)數(shù)據(jù)
  • Authorization
  • Oauth2.0的access token(bearer token)
  • Accept-Language(可選)
  • 可接受的語言,國際化,en-US表示美國英語

請(qǐng)求數(shù)據(jù)格式+類型

  • json格式:{items:[]}
  • 請(qǐng)求創(chuàng)建students對(duì)象json(表達(dá)):
  • 請(qǐng)求(批量)創(chuàng)建student對(duì)象列表json(表達(dá))
  • 請(qǐng)求(批量)創(chuàng)建student信息excel文

響應(yīng)header

  • Content-Type
  • aplication/json
  • Content-Language(可選)
  • 內(nèi)容語言
  • Last-Modified
  • 數(shù)據(jù)最近一次修改的時(shí)間戳信息

響應(yīng)值

  • Success message:多種類型
  • Error message:多種類型
  • Exception:多種類型

統(tǒng)一異常處理

統(tǒng)一異常處理包括狀態(tài)碼以及狀態(tài)碼涵蓋的異常信息,具體部分定義如下:

  • 200/201+success message(含資源數(shù)量信息+uri信息):創(chuàng)建成功,適用于數(shù)量不多(比如小于500)的創(chuàng)建操作,大于設(shè)定的值時(shí)進(jìn)行異步處理,參加返回值202
  • 202+success message with status uri:異步處理,返回進(jìn)度查詢資源uri(/api/vendor/v1/status/{id})
  • 400+success+errors(含出錯(cuò)項(xiàng)index的錯(cuò)誤列表):批量創(chuàng)建時(shí)部分成功,返回成功信息和錯(cuò)誤信息
  • 401+exception{error_code+message}:缺乏認(rèn)證信息
  • 403+exception{error_code+message}:未授權(quán)訪問,訪問被拒絕
  • 406+exception{ error_code+message}:不支持client要求的格式或語言時(shí)返回該信息(Not Acceptable)
  • 415+exception{error_code+message}:請(qǐng)求中的文檔格式不支持
  • 422+exception{error_code+message}:不能處理的數(shù)據(jù),比如json格式錯(cuò)誤、文件內(nèi)容項(xiàng)錯(cuò)誤或會(huì)破壞業(yè)務(wù)規(guī)則
  • 429+exception{ error_code+message}:太多請(qǐng)求,流控時(shí)使用
  • 500+exception{error_code+message}:服務(wù)器內(nèi)部錯(cuò)誤

統(tǒng)一日志攔截

基于AOP模式攔截所有請(qǐng)求,在請(qǐng)求入站與出站的時(shí)候,做統(tǒng)一日志記錄以及需要的其他非業(yè)務(wù)處理(例如鑒權(quán))

統(tǒng)一的數(shù)據(jù)返回標(biāo)準(zhǔn)

我們參考Restful數(shù)據(jù)返回標(biāo)準(zhǔn),封裝我們自己的數(shù)據(jù)返回格式:code,message,body,error,統(tǒng)一的數(shù)據(jù)返回格式可以在接口層做統(tǒng)一的攔截處理。實(shí)現(xiàn)返回?cái)?shù)據(jù)的標(biāo)準(zhǔn)化。

  • code:返回狀態(tài)碼
  • message:返回響應(yīng)結(jié)果的語義解釋
  • body:響應(yīng)的具體數(shù)據(jù)信息,包括metada信息,具體響應(yīng)數(shù)據(jù)以及請(qǐng)求連接
  • error:代表返回的錯(cuò)誤信息

具體的響應(yīng)格式如下所示:

  1. "code": 200, 
  2. "message": "獲取學(xué)生列表成功", 
  3. "body": { 
  4. "links": [ 
  5. "rel": "self", 
  6. "href": "http://localhost:8080/api/clou ... t%3D0{&fields}", 
  7. "hreflang": null, 
  8. "media": null, 
  9. "title": null, 
  10. "type": null, 
  11. "deprecation": null 
  12. ], 
  13. "metadata": [] 
  14. "content": [ 
  15. "id": 1, 
  16. "name": "test3", 
  17. "status": "running", 
  18. "props": "test", 
  19. "remark": "test", 
  20. "ownerId": 1, 
  21. "createrId": 1, 
  22. "menderId": 1, 
  23. "gmtCreate": "2019-03-11 10:42:15", 
  24. "gmtModify": null, 
  25. "startDate": null, 
  26. "endDate": null, 
  27. "links": [ 
  28. "rel": "self", 
  29. "href": "http://localhost:8080/api/clou ... ot%3B, 
  30. "hreflang": null, 
  31. "media": null, 
  32. "title": null, 
  33. "type": null, 
  34. "deprecation": null 
  35. "errors": {} 

服務(wù)接口的設(shè)計(jì)一定是圍繞標(biāo)準(zhǔn)化的規(guī)則進(jìn)行的,這樣才能在后期減少因?yàn)榻涌谧儎?dòng)導(dǎo)致不斷出現(xiàn)的前后端聯(lián)調(diào)問題。因?yàn)樵趯?shí)踐中我們經(jīng)常遇到格式不統(tǒng)一導(dǎo)致web要寫不同的數(shù)據(jù)解析方式,從而造成大量重復(fù)的工作。

遺留問題

當(dāng)然我們落地過程的選擇也不一定盡善盡美,也有很多隨著業(yè)務(wù)處理能力的加強(qiáng)而在之前沒有考慮到的問題,例如:

  • 各個(gè)服務(wù)自身并發(fā)數(shù)據(jù)支撐能力
  • 服務(wù)交互的內(nèi)部代碼瓶頸,包括調(diào)用鏈路冗余,響應(yīng)偏慢等
  • 數(shù)據(jù)庫的并發(fā)支撐與性能優(yōu)化
  • 與容器服務(wù)集成的參數(shù)配置,開發(fā)與部署環(huán)境的轉(zhuǎn)變
  • 調(diào)用鏈路可能出現(xiàn)的回環(huán)問題,交叉的業(yè)務(wù)單元調(diào)用,導(dǎo)致調(diào)用鏈路混亂
  • 數(shù)據(jù)的緩存設(shè)計(jì),加快業(yè)務(wù)響應(yīng)速率

這些問題我們?cè)诤罄m(xù)不斷深入地理解和探索中會(huì)找到相應(yīng)的解決方案,大家可以在后續(xù)繼續(xù)關(guān)注我們的微服務(wù)解決方案。

文章題目:微服務(wù)落地,我們?cè)诳紤]什么?
網(wǎng)頁鏈接:http://www.muchs.cn/news10/100860.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航電子商務(wù)、App開發(fā)定制網(wǎng)站、網(wǎng)站設(shè)計(jì)公司、搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)