服務間是否應該提供批量介面?

彤哥讀原始碼發表於2021-02-01

背景

昨天跟同事聊天,他提了一個問題,我覺得挺有意思,分享給大家。

原話是這樣的:我提供了一個批量鎖庫存的介面,結果那誰傳了十萬條資料過來,把我弄死了,麻蛋,我就不應該給他提供這個批量的介面,我現在怎麼辦?(頭大)

所以,我們應不應該提供批量的介面呢?

我認為不應該提供。

動機

首先,我們分析一下需要批量的動機。

客戶端(呼叫者)想把資料組裝成一個大List批量呼叫你的介面,肯定是考慮到如果一條一條呼叫你,中間的網路開銷非常大,浪費很多時間,所以,他認為批量呼叫你的介面,可以把這一部分耗時給節約了,提高他介面的響應速度。

危害

然後,我們再分析一下如果你提供了批量介面,會出現哪些危害呢。

第一點,客戶端相當於把他的壓力轉移到你這裡了,整個系統出現問題,誰背鍋,無需多言了。

第二點,本來客戶端一個請求一個請求來呼叫你的,你可以部署10臺機器來抗併發,結果現在一個請求過來10萬資料,全部打到你的一臺機器的一個執行緒中,你怎麼處理?多執行緒?多執行緒你也是在一臺機器裡面搞。加訊息佇列再分發?這無疑大幅度增加了你的設計複雜度。

第三點,現在是10萬資料,以後呢?會不會出現100萬、1000萬來調你?不可控,只要你提供了,別人就可能來搞你。

所以,無論怎麼看,你都不應該提供批量介面,只要你提供了,無疑是在作死,而且死的心安理得,因為確實是你的問題,你跟客戶端撕逼可能都撕不過。

因此,千萬不要提供批量介面。

客戶端呼叫的正確姿勢

那麼,問題來了,如果不提供批量介面,客戶端怎麼加快他的處理速度呢?

客戶端應該改變思維,不是一個請求一個請求的同步呼叫你的介面,而應該多個請求非同步併發呼叫你的介面,這樣,你這邊完全不用修改,只要簡單的加機器就可以輕鬆實現無限擴容。

但是,客戶端的程式碼並沒有那麼好寫,在java中,就是使用Future啦,或者直接使用Completable Future,有興趣的可以去看看Dubbo的原始碼,新版本已經全部改成使用CompletableFuture來實現遠端呼叫了,當然,dubbo本身就是支援非同步呼叫的,用起來很簡單,但是如果你是feign可能需要自己包一層了。

好了,今天我們這裡說的客戶端實際上是後端服務之間的呼叫,不包含前端那種批量匯入的場景,就先分享到這裡了。

結語

最後,我想問,你們的系統服務之間有沒有批量的介面呢?又是怎麼處理這種大請求的呢?

歡迎留言討論。

相關文章