1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        《微服務(wù)架構(gòu)設(shè)計(jì)模式》總結(jié),文末送書

        共 4438字,需瀏覽 9分鐘

         ·

        2021-08-18 18:38


        經(jīng)常翻閱微服務(wù)材料的話,總會(huì)碰到 microservices.io 這個(gè)網(wǎng)站,總結(jié)了微服務(wù)方方面面的設(shè)計(jì)模式。網(wǎng)站的作者是 Chris Richardson。

        這些相關(guān)的經(jīng)驗(yàn)在 2018 年成為了《微服務(wù)架構(gòu)設(shè)計(jì)模式》這本書,并且 2019 年引進(jìn)國內(nèi)。當(dāng)時(shí)我第一時(shí)間購入了這本書,中間斷斷續(xù)續(xù)地一直沒看完。最近準(zhǔn)備分享內(nèi)容的時(shí)候又翻起這本書,這次完整地讀完了一遍。感覺應(yīng)該是目前微服務(wù)領(lǐng)域最好的一本書了。另一本《Building Microservices》也不錯(cuò),不過內(nèi)容還是稍微單薄了一些。

        這本書為我們提供了宏觀上俯瞰微服務(wù)整個(gè)生態(tài)的大圖,比如:

        當(dāng)然,18 年的時(shí)候,service mesh 之類的東西還沒有太火,所以后來在網(wǎng)站上有個(gè)更新的版本:

        個(gè)人很喜歡這種大圖,不管什么領(lǐng)域,我只要照著圖去一點(diǎn)一點(diǎn)填坑就行了,沒有這樣的圖,總覺得是在望不見頭的技術(shù)森林里兜兜轉(zhuǎn)轉(zhuǎn),找不到北。

        下面簡單寫一寫我對(duì)這本書的總結(jié),里面 saga 和測(cè)試的部分我就先省略了。

        單體服務(wù)的困境

        在單體時(shí)代,大家在一個(gè)倉庫里開發(fā),代碼沖突解決起來很麻煩,上線的 CI/CD pipeline 也是等待到死。

        拆分了以后,至少大家有各自的代碼庫,各自的上線流程,各自的線上服務(wù)。這樣上線不打架了,上線以后也可以自己玩自己的灰度流程,一般不會(huì)互相影響。

        服務(wù)拆分

        雖然說是拆了,不過拆分也是要講究方法的。

        書里提供了兩種思路,一種是按照業(yè)務(wù)/商業(yè)能力拆分,一種是按照 DDD 中的 sub domain 拆分。

        • 供應(yīng)商管理

          • 送餐員信息管理

          • 餐館信息管理:管理餐館的訂單、營業(yè)時(shí)間、營業(yè)地點(diǎn)

        • 消費(fèi)者管理

          • 管理消費(fèi)者信息

        • 訂單獲取和履行

          • 消費(fèi)者訂單管理:讓消費(fèi)者可以創(chuàng)建、管理訂單

          • 餐館訂單管理:讓餐館可以管理訂單的準(zhǔn)備過程

        • 送餐管理

          • 送餐員狀態(tài)管理:管理可以進(jìn)行接單操作的送餐員的實(shí)時(shí)狀態(tài)

          • 配送管理:訂單配送追蹤

        • 會(huì)計(jì)

          • 消費(fèi)者記賬:管理消費(fèi)者的訂單記錄

          • 餐館記賬:管理餐館的支付記錄

          • 配送員記賬:管理配送員的收入信息

        最終大概會(huì)形成上面這些服務(wù)。

        用 DDD 來做分析,其實(shí)我們得到的結(jié)果也差不多:

        在拆分時(shí),我們還應(yīng)該用 SOLID 中的 SRP 原則和另外一個(gè)閉包原則 CCP(common closure principle) 來進(jìn)行指導(dǎo)。

        在拆分后,也要注意微服務(wù)的拆分會(huì)額外給我們帶來的問題:

        • 網(wǎng)絡(luò)延遲

        • 服務(wù)間同步通信導(dǎo)致可用性降低

        • 在服務(wù)間維持?jǐn)?shù)據(jù)一致性

        • 獲取一致的數(shù)據(jù)視圖

        • 阻塞拆分的上帝類

        服務(wù)集成

        分布式服務(wù)通信大概可以分為 one-to-one 和 one-to-many:

        RPC 很好理解,同步的 request/response。異步通信,一種是回調(diào)式的 request/response,一種是一對(duì)多的 pub/sub。

        具體到 RPC 的話,可以使用多種協(xié)議和框架:

        不過當(dāng) API 更新時(shí),應(yīng)該遵循 semver 的規(guī)范進(jìn)行更新。社區(qū)里 gRPC 很多次更新都沒有遵守 semver,給它的依賴方都造成了不小的麻煩。感興趣的同學(xué)應(yīng)該可以搜到一些相關(guān)的事件。

        不得不說 Google 的程序員也并不是事事靠譜。

        RPC 進(jìn)行服務(wù)集成的時(shí)候,要注意不要被某些不穩(wěn)定的服務(wù)慢響應(yīng)拖死,要注意設(shè)置超時(shí),熔斷。

        服務(wù)與服務(wù)之間要能找得到彼此,有兩種方式,一種是基于服務(wù)注冊(cè)中心的服務(wù)發(fā)現(xiàn)。

        一種是基于 dns 的服務(wù)發(fā)現(xiàn)?;?DNS 的現(xiàn)在應(yīng)該不太多了。

        除了 RPC 以外,還可以使用消息來進(jìn)行服務(wù)間的集成。

        使用 MQ 也可以模擬 RPC 的 request/response,不過這樣會(huì)使你的服務(wù)強(qiáng)依賴于 MQ,如果 MQ 故障,那整個(gè)系統(tǒng)隨之崩潰。

        一般我們使用的是 broker-based mq 通信,但也有無 broker 的異步通信,書中這里舉了個(gè) ZeroMQ 的例子,之前個(gè)人不是很了解,需要再調(diào)研一下。

        Event Sourcing

        event sourcing 是一種特殊的設(shè)計(jì)模式,不記錄實(shí)體的終態(tài),而是記錄所有狀態(tài)修改的事件。然后通過對(duì)事件進(jìn)行計(jì)算來得到實(shí)體最終的狀態(tài)。

        但這樣事件累積太多以后會(huì)有性能問題,所以可以對(duì)一部分歷史數(shù)據(jù)進(jìn)行計(jì)算,得到一個(gè)中間的快照,之后的計(jì)算在快照的基礎(chǔ)上再疊加。

        看起來方案很酷,我們?cè)趯?shí)際工作中也確實(shí)在一些下游的計(jì)算邏輯中使用過這種設(shè)計(jì)模式,不過它也是有缺陷的:

        • 事件本身結(jié)構(gòu)變化時(shí),新老版本兼容比較難做

        • 如果代碼中要同時(shí)處理新老版本數(shù)據(jù),那么升級(jí)幾次后會(huì)非常難維護(hù)

        • 因?yàn)槿菀鬃匪荩詣h除數(shù)據(jù)變得非常麻煩,GDPR 類的法規(guī)要求用戶注銷時(shí)必須將歷史數(shù)據(jù)刪除干凈,這對(duì) Event Sourcing 是一個(gè)巨大的挑戰(zhàn)

        在使用異步消息來做解耦的時(shí)候,我們也會(huì)遇到一些實(shí)際的業(yè)務(wù)問題:

        • 這個(gè)數(shù)據(jù)我需要,你能不能在消息里幫我透?jìng)饕幌?/p>

        • 你重構(gòu)的時(shí)候怎么把這個(gè)字段刪了,我還要用呢

        • 你們?cè)瓉淼臓顟B(tài)機(jī)變更都有 event,本來有三個(gè),怎么現(xiàn)在變成兩個(gè)了?

        • 你們 API 故障的時(shí)候,怎么消息順序亂了?

        這要求我們能有對(duì)上游的領(lǐng)域事件進(jìn)行校驗(yàn)的系統(tǒng),這里可以參考 Google 的 schema validation 這個(gè)項(xiàng)目,之前我在 《MQ 正在變成臭水溝》一文中有詳述。這里就不提了。

        查詢模式

        很多查詢邏輯其實(shí)就是進(jìn)行 API 的數(shù)據(jù)組合,這個(gè)涉及到需要組合數(shù)據(jù)的 API 組合器,和數(shù)據(jù)提供方:

        • API 組合器:通過查詢數(shù)據(jù)提供方的服務(wù)實(shí)現(xiàn)查詢操作

        • 數(shù)據(jù)提供方:提供數(shù)據(jù)

        雖然看起來挺簡單,寫代碼的時(shí)候,下面這些問題還是難處理:

        • 誰來負(fù)責(zé)拼裝這些數(shù)據(jù)?有時(shí)是應(yīng)用,有時(shí)是外部的 API Gateway,難以定立統(tǒng)一的標(biāo)準(zhǔn),在公司里也經(jīng)常扯皮

        • 增加額外的開銷-一個(gè)請(qǐng)求要查詢很多接口

        • 可用性降低-每個(gè)服務(wù)可用性 99.5%,實(shí)際接口可能是 99.5^5=97.5

        • 事務(wù)數(shù)據(jù)一致性難保障-需要使用分布式事務(wù)框架/使用事務(wù)消息和冪等消費(fèi)

        CQRS

        業(yè)務(wù)開發(fā)經(jīng)常自嘲是 CRUD 工程師,在架構(gòu)設(shè)計(jì)里,CRUD 的 R 可以單獨(dú)拆出來,像下面這樣。

        拆出來的好處?互聯(lián)網(wǎng)大多是寫少讀多的服務(wù),將關(guān)注點(diǎn)分離之后,讀服務(wù)和寫服務(wù)的存儲(chǔ)可以做異構(gòu)。

        比如寫可以是 MySQL,而讀則可以是各種非常容易做橫向擴(kuò)展的 NoSQL。碰到檢索需求,讀還可以是 Elasticsearch。

        讀服務(wù)可以訂閱寫服務(wù)的 domain event,也可以是 MySQL 的 binlog。

        在消費(fèi)上游數(shù)據(jù)時(shí),需要根據(jù)業(yè)務(wù)邏輯去判斷有些狀態(tài)機(jī)要怎么做處理。這里其實(shí)數(shù)據(jù)上是有耦合的,并不是放個(gè) MQ 和 domain event 就能解耦干凈了。

        CQRS 的缺點(diǎn)也比較明顯:

        • 架構(gòu)復(fù)雜

        • 數(shù)據(jù)復(fù)制延遲問題

        • 查詢一致性問題

        • 并發(fā)更新問題處理

        • 冪等問題需要處理

        外部 API 模式

        現(xiàn)在的互聯(lián)網(wǎng)公司一般客戶端都是多端,web、移動(dòng)、向第三方開放的 open API。

        如果我們直接把之前用拆分方法拆出來的這些內(nèi)部 API 開放出去,那未來內(nèi)部的 API 想升級(jí)就會(huì)非常非常地麻煩。

        在單體時(shí)代,客戶端走弱網(wǎng) internet,只需要一次調(diào)用。微服務(wù)化以后,如果不做任何優(yōu)化,那在 internet 這種慢速網(wǎng)絡(luò)上就需要有多次調(diào)用。

        這就是我們?yōu)槭裁葱枰虚g有一個(gè) API Gateway 的原因。

        有了 Gateway 之后,在 internet 依然還是一次調(diào)用,在內(nèi)部 IDC 強(qiáng)網(wǎng)絡(luò)的狀態(tài)下多次網(wǎng)路調(diào)用相對(duì)沒有那么糟糕。

        API Gateway 涉及到這些不同端的 API Gateway 應(yīng)該要誰來維護(hù)的問題。下面是一種理想的情況,Mobile 團(tuán)隊(duì)負(fù)責(zé)維護(hù)他們?cè)?Gateway 里的 API(也可能是單獨(dú)的 Gateway),web 端團(tuán)隊(duì)維護(hù) web 的 Gateway,open API 團(tuán)隊(duì)負(fù)責(zé)維護(hù)第三方應(yīng)用的 Gateway API。

        網(wǎng)關(guān)基礎(chǔ)設(shè)施團(tuán)隊(duì)負(fù)責(zé)提供這三方都需要的基礎(chǔ)庫。

        在研發(fā) API Gateway 的時(shí)候,我們有多種可選項(xiàng):

        • 直接使用開源產(chǎn)品

          • Kong

          • APISix

          • Traefik

        • 自研

          • Zuul

          • Spring Cloud Gateway

          • RESTFul 自己做一個(gè)

          • GraphQL 自己做一個(gè)

        開源的 API Gateway 大多不支持 API 數(shù)據(jù)組合功能,所以公司內(nèi)的 API Gateway 有時(shí)候有兩層,一層是 nginx 之類的負(fù)責(zé)簡單路由和鑒權(quán)的 gateway,后面還有一個(gè)業(yè)務(wù)的 BFF 來負(fù)責(zé)拼裝端上需要的數(shù)據(jù)。

        如果我們都是自研,那就可以在一個(gè)模塊上把 API Gateway 需要的功能都實(shí)現(xiàn)。這里經(jīng)常討論的一個(gè)問題是,我們是要使用 REST 還是類似 GraphQL 的圖查詢。

        Netflix 的工程師在 2012 年發(fā)表過一篇文章:

        《為什么 REST 讓我半夜睡不著》,老哥還挺幽默。內(nèi)容大概是講 Netflix 要面對(duì)成百上千的終端設(shè)備,Netflix 曾經(jīng)希望能給所有終端提供大一統(tǒng)的方案,大家使用統(tǒng)一的 REST API,但后來發(fā)現(xiàn)這種統(tǒng)一的方式是放棄了對(duì)任一有自己特性的設(shè)備的優(yōu)化,比如有些設(shè)備內(nèi)存小,有些設(shè)備屏幕小,這些設(shè)備上你返回的很多字段數(shù)據(jù)對(duì)他們來說根本就用不上,純粹是浪費(fèi)網(wǎng)絡(luò)帶寬。有些設(shè)備用流式響應(yīng)比返回完整響應(yīng)性能更好,這也應(yīng)該是要考慮的優(yōu)化點(diǎn)。

        所以 Netflix 做了一個(gè)叫 falcor 的方案,其實(shí)和后來 Facebook 的 GraphQL 非常類似,是用 JSON Graph 來描述內(nèi)部 API 能提供的數(shù)據(jù),然后用 JS 來定制圖上的查詢。

        現(xiàn)在大多數(shù)人比較熟悉的還是 GraphQL:

        GraphQL 是個(gè)好東西,但之前我個(gè)人對(duì)使用 GraphQL 一直持懷疑態(tài)度,主要是因?yàn)椋?/p>

        • 網(wǎng)關(guān)容易被客戶端的修改直接帶崩

        • 穩(wěn)定性非常難保障

        • 中文互聯(lián)網(wǎng)上講 GraphQL 的基本都沒有提到限流,或者一筆帶過,這是不太負(fù)責(zé)任的

        直到最近我發(fā)現(xiàn)國外某公司公開了他們的 GraphQL 限流方案,這個(gè)方案非常有意思,我會(huì)在下一篇文章進(jìn)行分享。

        這本《微服務(wù)架構(gòu)模式》難能可貴的地方在于幾乎所有的技術(shù)方案,都很詳盡地給出了優(yōu)劣,這在其它書里是比較少見的。我們?cè)谀承┤说奈恼潞头桨咐镉肋h(yuǎn)只能看到優(yōu)點(diǎn),但在實(shí)踐中落地技術(shù)方案的時(shí)候,其實(shí)更關(guān)注缺陷。對(duì)缺陷有心理準(zhǔn)備,才不會(huì)在新方案出問題的時(shí)候心慌。

        個(gè)人覺得這本書,無論是對(duì)微服務(wù)剛?cè)腴T,或是工作幾年的人,都值得一讀。

        在本文最后做個(gè)簡單的抽獎(jiǎng)活動(dòng),本文回復(fù)的第一、第三、第十、第三十個(gè)人,都能夠得到一本《微服務(wù)架構(gòu)模式》,你需要寫寫自己對(duì)微服務(wù)的見解,或者簡短地分享一下自己在公司中碰到的微服務(wù)的坑就可以。

        100 字以內(nèi)就行,不用長篇大論~

        沒抽到的老哥就只能自己買了,[doge]。

        瀏覽 43
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            韩 国 三 级 免 费 看 | 我爱草逼网 | 国产欧美一区二区三区不卡高清 | 国产精品久久久久精 | 极品另类 | 秋霞午夜久久 | 一级特黄60分钟好爽免费看 | 大香蕉操逼视频 | 91美女片黄在线观看游戏 | 91超碰爽图 |