最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

模塊化golang工程

2023-08-25 20:23 作者:迷路idea  | 我要投稿

為什么要模塊化

微服務(wù)本身是比較徹底的模塊化方案,但是在部分場(chǎng)景下微服務(wù)不是最好的方案,例如:

  • 事務(wù)比較復(fù)雜

  • 希望內(nèi)存占用盡量低(比如客戶(hù)就給1c2g)

  • 數(shù)據(jù)庫(kù)連接數(shù)量已經(jīng)過(guò)大,不希望引入中間件去解決連接數(shù)問(wèn)題

  • 運(yùn)維能力不足

  • 開(kāi)源項(xiàng)目,希望便于部署

在這些條件下,單服務(wù)+模塊化變成了最好的方案。

模塊化方式對(duì)比

作為云原生的默認(rèn)語(yǔ)言,微服務(wù)化似乎應(yīng)該是與生俱來(lái)的能力。相比其他語(yǔ)言,golang 的模塊化方案被較少的討論。

對(duì)于模塊的需求,我們大致上有: - 可以比較方便的載入,最好能是運(yùn)行時(shí)的 - 可以卸載 - 可以有能力去在某次業(yè)務(wù)邏輯中啟用和禁用

golang官方實(shí)際有模塊化方案:go plugin。有如下特點(diǎn):

  • - 1.8版本引入

  • - 模塊被打包為 so 文件,用代碼動(dòng)態(tài)加載

  • - 只能加載,不能卸載

  • - 主程序與plugin的共同依賴(lài)包的版本必須一致

  • - 如果采用mod=vendor構(gòu)建,那么主程序和plugin必須基于同一個(gè)vendor目錄構(gòu)建

  • - 主程序與plugin使用的編譯器版本必須一致

這些條件中,在常見(jiàn)的業(yè)務(wù)開(kāi)發(fā)中,最難做到的就是依賴(lài)版本一致 假設(shè)主程序與模塊都使用了內(nèi)部 log庫(kù)v1,現(xiàn)在 v1 提供了升級(jí) v1.1,某模塊需要這個(gè)升級(jí)。也就意味著主程序和所有的模塊必須一起升級(jí)才能解決這個(gè)問(wèn)題。如果有幾百個(gè)模塊呢。。。

因此 go plugin 這么久了也很少有人使用這樣的方案去做模塊化,有興趣的可以看這個(gè)例子:https://github.com/pingcap/tidb/blob/master/docs/design/2018-12-10-plugin-framework.md

不用 go plugin,還有什么其他方案嗎?

github.com/hashicorp/go-plugin 使用了“假微服務(wù)”方案,通過(guò)子主進(jìn)程進(jìn)行模塊化啟動(dòng),通信使用 go 喜聞樂(lè)見(jiàn)的 grpc。這個(gè)方案有效的解決了運(yùn)行時(shí)、卸載、依賴(lài)版本的問(wèn)題。 但是他引入了新的問(wèn)題:性能。 假設(shè)一個(gè)調(diào)用需要調(diào)用其他 1 個(gè)模塊的方法,傳了指針進(jìn)去。在 go 層面只占用了一塊內(nèi)存,經(jīng)由 grpc 傳輸后,內(nèi)存占用變成了 3 塊,也就是說(shuō)一個(gè)調(diào)用內(nèi)存就要翻 3 倍。普通業(yè)務(wù)開(kāi)發(fā)其實(shí)到也影響不大,在涉及大流量網(wǎng)絡(luò)開(kāi)發(fā)中,這個(gè)量級(jí)可能太嚇人了。

編輯


對(duì)性能要求比較高,或需要內(nèi)存占用比較低的場(chǎng)景中,這個(gè)方案不太行。如果要使用 rpc,為什么不真的使用微服務(wù)呢,畢竟微服務(wù)體系下是另一套完整的生態(tài)了。監(jiān)控、鏈路、編排等各類(lèi)需求都有完整便捷的解決方案。

如果用 go mod 作為模塊化方案,優(yōu)勢(shì)有:

  • - 完全支持多版本

  • - 沒(méi)有學(xué)習(xí)成本

  • - 沒(méi)有額外的性能開(kāi)銷(xiāo)

相對(duì)的,缺點(diǎn)有:

  • - 不可能運(yùn)行時(shí)載入

  • - 不能卸載

  • - 編譯的時(shí)候不能做單元測(cè)試

  • - 分支管理不能按照普通的方式來(lái)進(jìn)行

  • - 配置管理需要升級(jí)(普通的配置方式對(duì)模塊化不夠靈活)

  • - 不能支持 swagger

go mod模塊化實(shí)現(xiàn)細(xì)節(jié)

模塊化方案是微服務(wù)的前奏,如果模塊化成功,起碼有了向微服務(wù)發(fā)展的基礎(chǔ)。 從這個(gè)角度出發(fā),模塊化方案就必須滿足一些要求:

  • - 依賴(lài) interface 而不是指針

  • - 不使用導(dǎo)出變量的方式使用單例模式,盡量控制模塊權(quán)限

  • - 每個(gè)模塊的配置應(yīng)該是獨(dú)立的

  • - 盡管不要求運(yùn)行時(shí)載入和卸載,起碼載入和卸載應(yīng)該很方便

因此,模塊化方案在 go mod 的基礎(chǔ)上,還應(yīng)該有:

  • - 全面 ioc 的使用和支持,這樣才能夠依賴(lài) interface,盡量控制模塊權(quán)限

  • - 配置覆蓋或組合能力,每個(gè)模塊有獨(dú)立的配置,同時(shí)可被其上層模塊的配置覆蓋,或提供配置組合能力。

模塊的設(shè)計(jì)

模塊的設(shè)計(jì)和微服務(wù)的劃分可以對(duì)應(yīng),甚至可以更細(xì)粒度,畢竟還是單服務(wù),沒(méi)有微服務(wù)的劣勢(shì)。 常見(jiàn)的,按照流程/對(duì)象或者抽象/實(shí)現(xiàn)的方式去劃分,可以解決大部分的問(wèn)題。

什么是好的模塊(基本和微服務(wù)重疊):

  • - 可管理(動(dòng)態(tài)裝載和卸載,golang做不到)

  • - 原生可重用

  • - 可組合

  • - 無(wú)狀態(tài)

一個(gè)模塊設(shè)計(jì)的例子

需求:支付系統(tǒng)。

根據(jù)商品的不同,總價(jià)會(huì)有不同的折扣。但是折扣的計(jì)算比較復(fù)雜,會(huì)根據(jù)商品的不同屬性計(jì)算不同折扣。例如商品上架時(shí)間、庫(kù)存、供應(yīng)商、批次等

第一次設(shè)計(jì)

有一個(gè)獨(dú)立的服務(wù),支付服務(wù),來(lái)處理所有的需求。其會(huì)拉取商品服務(wù)的數(shù)據(jù)進(jìn)行邏輯判斷。

第一次模塊化重構(gòu)

抽取其中的商品拉取部分、數(shù)據(jù)庫(kù)存儲(chǔ)部分進(jìn)行獨(dú)立模塊?,F(xiàn)在邏輯部分在上,商品拉取、存儲(chǔ)部分在下。

遵循一個(gè)原則:上層模塊依賴(lài)下層,反之則不行

現(xiàn)在有2個(gè)模塊:商品拉取、數(shù)據(jù)庫(kù)存儲(chǔ)

第二次模塊化重構(gòu)

邏輯部分在直接調(diào)用商品拉取,抽象其中部分為interface,商品拉取模塊實(shí)現(xiàn)了這個(gè)interfcae。 同樣,商品折扣的計(jì)算也獨(dú)立出了一個(gè)模塊,同樣也實(shí)現(xiàn)了一個(gè)抽象的interface

遵循一個(gè)原則:只能依賴(lài)抽象而不是實(shí)現(xiàn),實(shí)現(xiàn)依賴(lài)了本來(lái)應(yīng)該依賴(lài)它的業(yè)務(wù),依賴(lài)倒置了。

現(xiàn)在有3個(gè)模塊:商品折扣計(jì)算、商品拉取、數(shù)據(jù)庫(kù)存儲(chǔ)

第三次模塊化重構(gòu)

折扣的計(jì)算包含多種多樣,且可能隨時(shí)增加或變更的邏輯。把它們?nèi)糠珠_(kāi)成不同的實(shí)現(xiàn),實(shí)現(xiàn)了相同的interface。用同一個(gè)管理器進(jìn)行管理

遵循一個(gè)原則:適配器模式的使用,帶來(lái)擴(kuò)展的便利性

現(xiàn)在有3+n個(gè)模塊:n個(gè)商品折扣計(jì)算、折扣計(jì)算管理、商品拉取、數(shù)據(jù)庫(kù)存儲(chǔ)

第四次模塊化重構(gòu)

支付的流程也成為了一個(gè)獨(dú)立的模塊,調(diào)用了一個(gè)通用的interface。折扣計(jì)算管理器實(shí)現(xiàn)了這個(gè)interface,因此將來(lái)不僅可以計(jì)算折扣,還通過(guò)擴(kuò)展其他模塊

遵循一個(gè)原則:main里面只剩下了di框架的初始化和配置,代碼不超過(guò)20行了

現(xiàn)在有4+n個(gè)模塊:n個(gè)商品折扣計(jì)算、支付模塊、折扣計(jì)算管理、商品拉取、數(shù)據(jù)庫(kù)存儲(chǔ)

結(jié)果

經(jīng)過(guò)4次重構(gòu)后,系統(tǒng)從以前的一坨變成了一堆,也沒(méi)有進(jìn)行微服務(wù)拆分,但是誰(shuí)都能看出來(lái)他的可維護(hù)性已經(jīng)增加了太多。


更多精彩內(nèi)容


純異步事件驅(qū)動(dòng)構(gòu)建的微服務(wù)體系

我們?yōu)槭裁从钟钟钟中枰粋€(gè)新的mq了

小團(tuán)隊(duì)的實(shí)用云原生指南


研發(fā)團(tuán)隊(duì)新鮮事兒,來(lái)公眾號(hào)「迷路idea」找我一起探討


模塊化golang工程的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
西林县| 焉耆| 松桃| 绍兴市| 屏南县| 齐河县| 临泉县| 乌鲁木齐市| 香格里拉县| 平湖市| 武强县| 安远县| 福安市| 松潘县| 兴宁市| 清流县| 固安县| 黄大仙区| 鄂托克前旗| 平凉市| 四川省| 全南县| 门源| 张掖市| 绩溪县| 天峻县| 辰溪县| 怀仁县| 遵义市| 梨树县| 师宗县| 安吉县| 济南市| 高雄县| 固镇县| 仁寿县| 巴彦淖尔市| 北流市| 新丰县| 潞西市| 南投县|