通用能力抽象選擇SDK組件還是API服務(wù)?
大型的后端服務(wù),當(dāng)需要把一部分通用能力抽象出來(lái),通常有兩種方式:SDK組件或者API服務(wù)。

對(duì)于有Java分庫(kù)分表經(jīng)驗(yàn)的同學(xué)來(lái)說(shuō),這兩種形式的選擇類似于Sharding-JDBC和MyCat的選型:前者作為client層方案類似于SDK;后者提供了proxy層類似API的服務(wù)。
關(guān)于Sharding-JDBC和MyCat的選型感興趣的同學(xué),可以查看小輝之前的博客《一文了解數(shù)據(jù)拆分與分庫(kù)分表》
無(wú)論是SDK組件還是API服務(wù),起初可能是一個(gè)人或者一個(gè)小組使用,隨著版本迭代和人力投入,影響力和對(duì)接方越來(lái)越多,這過(guò)程中存在兩個(gè)角色:提供方和使用方。因?yàn)椴煌慕巧珜?duì)于通用能力的訴求是不完全一樣的,本文會(huì)分別從這兩個(gè)角色進(jìn)行討論。
簡(jiǎn)單介紹下概念:
SDK:軟件開(kāi)發(fā)工具包(全稱:Software Development Kit)。一般是指軟件工程師為特定的軟件包、軟件框架、硬件平臺(tái)、操作系統(tǒng)等建立應(yīng)用軟件時(shí)的開(kāi)發(fā)工具的集合。例如Java工程常用maven或gradle引入的依賴組件,Go工程中g(shù)o.mod指定的依賴組件。
API:應(yīng)用程序編程接口(全稱:Application Programming Interface)。一般是指一些預(yù)先定義的函數(shù),目的是提供應(yīng)用程序與開(kāi)發(fā)人員基于某軟件或硬件得以訪問(wèn)一組例程的能力,而又無(wú)需訪問(wèn)源碼,或理解內(nèi)部工作機(jī)制的細(xì)節(jié)。API的定義比較寬泛,本文狹義的認(rèn)為API為后端的微服務(wù),提供遠(yuǎn)程rpc服務(wù)。
兩種方式的優(yōu)缺點(diǎn)區(qū)分如下:
| - | 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|---|
| SDK組件 | 不用單獨(dú)部署,運(yùn)維成本低,不需要作為代理層進(jìn)行二次轉(zhuǎn)發(fā),性能更優(yōu) | 如果需要升級(jí),則需要各個(gè)系統(tǒng)都進(jìn)行部署或者做版本隔離;各個(gè)系統(tǒng)耦合SDK的依賴,對(duì)于復(fù)雜龐大的邏輯不友好。 |
| API服務(wù) | 系統(tǒng)升級(jí)的時(shí)候只需要API服務(wù)自己進(jìn)行兼容升級(jí)即可,生效速度快 | 需要部署和運(yùn)維一套服務(wù),運(yùn)維成本高。下游依賴需要API服務(wù)做路由,多了一次網(wǎng)絡(luò)跳轉(zhuǎn)。 |
無(wú)論是SDK組件還是API服務(wù),對(duì)于提供方的原則:
任何代碼變動(dòng)都需要兼容老版本,不可以升級(jí)后對(duì)相同輸入產(chǎn)生了不同的輸出,
代碼結(jié)構(gòu)最好進(jìn)行足夠的抽象和提供拓展的接口,以便代碼變更盡可能的滿足開(kāi)閉原則。
講述完優(yōu)缺點(diǎn)和原則,再結(jié)合項(xiàng)目中的問(wèn)題討論下。
細(xì)節(jié)討論
1. SDK運(yùn)維成本低?API服務(wù)運(yùn)維成本高?
SDK運(yùn)維成本低這個(gè)優(yōu)點(diǎn)只在SDK使用方和下游是同一個(gè)團(tuán)隊(duì)的場(chǎng)景才更準(zhǔn)確。如果你是SDK的提供方,使用方是其他團(tuán)隊(duì),如果SDK包含有下游依賴。當(dāng)SDK使用方有大型活動(dòng)、流量有徒增或擴(kuò)容的要求時(shí),SDK包含的下游是需要擴(kuò)容的。這個(gè)擴(kuò)容操作時(shí)SDK使用方來(lái)負(fù)責(zé)溝通呢,還是SDK的提供方來(lái)溝通呢?這就存在協(xié)作邊界的模糊性。而且SDK提供方需要維護(hù)好調(diào)用下游的名單以及頻次,成本也是有的。
而對(duì)于API服務(wù)運(yùn)維成本高的問(wèn)題,如果是小團(tuán)隊(duì)協(xié)作,確實(shí)API服務(wù)會(huì)增加一個(gè)微服務(wù)和配套的devops,相比SDK組件有更高的成本。但是對(duì)于成熟工具鏈的團(tuán)隊(duì),新增服務(wù)會(huì)很容易。相對(duì)應(yīng)的好處是,API服務(wù)接入可以將流量評(píng)估收口到API服務(wù)的提供方,更容易控制好風(fēng)險(xiǎn)。
2. SDK的升級(jí)成本高?
當(dāng)SDK使用方越多、迭代越頻繁,升級(jí)成本越高。舉個(gè)栗子,SDK對(duì)于一個(gè)通用函數(shù)進(jìn)行了修改并發(fā)布,部分服務(wù)升級(jí)SDK后發(fā)現(xiàn)該版本SDK有隱藏bug,接下來(lái)所有使用方團(tuán)隊(duì)需要掃描使用該版本SDK的服務(wù)然后進(jìn)行SDK升級(jí)。相對(duì)來(lái)說(shuō),API服務(wù)只需要提供方靜默升級(jí)即可。
3. 各個(gè)系統(tǒng)耦合SDK的依賴,對(duì)于復(fù)雜龐大的邏輯不友好?
這句話的前提是SDK隨著功能迭代變得越來(lái)越臃腫,就會(huì)出現(xiàn)這種問(wèn)題,使得引入SDK就間接引入了很多依賴,增加編譯時(shí)間也增加依賴管理的問(wèn)題。
4. 如果要支持第三方定制化的能力,復(fù)雜度會(huì)如何?
如果你是SDK提供方,你完全可以將一些邏輯通過(guò)模板設(shè)計(jì)模式寫出來(lái),將過(guò)程中的變量或函數(shù),通過(guò)多態(tài)以及接口的形式暴露出去。這樣的話,作為SDK使用方,需要定制化的話,只需要在自己的服務(wù)本地進(jìn)行定制重寫即可。
但如果你是提供API服務(wù),對(duì)于定制化的服務(wù),需要讓使用方mr到你的服務(wù)代碼或者你去實(shí)現(xiàn)定制化。這其中就涉及到服務(wù)保密性的問(wèn)題,如果是非開(kāi)源服務(wù)、使用方是外部用戶的話,那大概率是不能提供mr的權(quán)限了。這樣新功能的開(kāi)發(fā)負(fù)擔(dān)就轉(zhuǎn)移到了提供方。
無(wú)論是提供SDK組件還是API服務(wù),都需要進(jìn)行合理的邏輯抽象,讓使用方盡量可以滿足開(kāi)閉原則的基礎(chǔ)上去增刪代碼。
5. 服務(wù)鑒權(quán)問(wèn)題
背景:在一些大型互聯(lián)網(wǎng)公司,下游服務(wù)對(duì)于它的上游服務(wù)是有白名單限制的。此外,對(duì)于API使用方是公司外部的用戶,在網(wǎng)關(guān)層可能也需要設(shè)置流量白名單。
對(duì)于服務(wù)提供方來(lái)說(shuō),如果使用方無(wú)論是公司內(nèi)部的還是公司外部的,都需要考慮服務(wù)鑒權(quán)問(wèn)題。
如果你是SDK提供方,使用方新接入SDK,他并不清楚下游會(huì)有哪些,如果自測(cè)階段不充分,很有可能有部分流量走到了沒(méi)有申請(qǐng)鑒權(quán)的下游服務(wù),這樣會(huì)造成一定的困擾。你需要提供友好的說(shuō)明或者承擔(dān)這部分工作。
如果你是API服務(wù)提供方,使用方新接入API,只需要配置一個(gè)白名單即可。這方面API服務(wù)就要比SDK組件輕松很多。
6. 接入友好問(wèn)題
對(duì)于提供方來(lái)說(shuō),無(wú)論SDK組件還是API服務(wù),完善的使用文檔都是必要的。
如果使用方是公司內(nèi)部的,兩種服務(wù)的接入友好差不多(前提是API服務(wù)不需要token鑒權(quán))。
如果使用方是公司外部的,對(duì)于用戶來(lái)說(shuō),SDK的接入方式更友好,只需要從多租戶平臺(tái)設(shè)置自己的秘鑰,然后SDK就可以開(kāi)箱即用。相對(duì)來(lái)說(shuō)API服務(wù)就需要自己按照文檔步驟生成token鑒權(quán),管理各種api接口的uri路徑以及創(chuàng)建各種請(qǐng)求/結(jié)果參數(shù)的對(duì)象結(jié)構(gòu)。
總結(jié)
以下僅為小輝個(gè)人使用體驗(yàn)。
作為提供方,對(duì)于公司外部的服務(wù)接入,更傾向于API接入方式。選擇API可以方便系統(tǒng)升級(jí),迭代周期可以更自由。
作為提供方,對(duì)于公司內(nèi)部的服務(wù)接入,兩種方式需要結(jié)合對(duì)服務(wù)未來(lái)的規(guī)劃、人力的規(guī)劃等等來(lái)決定。
作為使用方,對(duì)于公司外部的服務(wù)接入,更傾向于SDK接入方式。前提是SDK的依賴不會(huì)過(guò)于臃腫、SDK功能穩(wěn)定不會(huì)有被經(jīng)常通知強(qiáng)制升級(jí)的情況。
作為使用方,對(duì)于公司內(nèi)的服務(wù)接入,兩種使用方式均可。哪個(gè)形式更省心哪個(gè)就更優(yōu)。
以上討論的使用方,都是以用戶的視角來(lái)討論的。
用戶指的是直接使用SDK的開(kāi)發(fā)同學(xué)
客戶指的是技術(shù)選型或預(yù)算控制的開(kāi)發(fā)同學(xué)或技術(shù)經(jīng)理
這里提一下客戶要關(guān)注的。
作為要選擇三方服務(wù)的客戶來(lái)說(shuō),用戶的體驗(yàn)當(dāng)然很重要,會(huì)影響兄弟們的工作效率和激情。此外,還要考慮的是不同的三方服務(wù)的服務(wù)穩(wěn)定性、功能的完整程度(二次開(kāi)發(fā)的成本)、套餐價(jià)格、問(wèn)題響應(yīng)速度、口碑等。
三方服務(wù)選型要慎重再慎重,因?yàn)楹罄m(xù)想要更換三方服務(wù)的成本可能會(huì)很大。
