有啲時候我不得不問自己,我係咪真係已經喺呢個行業做咗三年。好長一段時間入面,我一直都喺科技嘅周邊打轉,但大多數都係由消費者嘅角度,即係遊戲。從來冇接觸過佢哋背後嘅系統。
呢個亦都係我一開始由工商管理轉去信息科技嘅部分原因。我鍾意科技,討厭商科嗰種理論化、靠死記硬背嘅苦差事。結果發現編程都冇差幾多,呢度一樣有好多嘢要背。分別在於,編程入面嘅背誦係為咗服務於我真正感興趣嘅嘢。
嗰啲令我措手不及嘅問題
最近,我被問到關於多租戶(multi-tenancy)嘅問題。我嘅答案大致係:「就係你有多個租戶,而你係業主。租戶向業主匯報。」技術上冇錯,但薄弱得令人難堪。當追問跟進,優點同缺點係咩,我攞唔出任何扎實嘅嘢。
令人沮喪嘅係,多租戶對我嚟講並唔係一個陌生嘅概念,我以前接觸過。只係冇接觸到可以喺壓力之下脫口而出、清楚展示出我係真正理解而唔係半吊子記憶嘅程度。
跟住更難嘅問題嚟咗。咩係broker(經紀/代理)?咩係provider(提供者)?「provider」我至少大致知道——我諗我講嘅係同依賴同採購有關,但冇辦法再具體。「broker」直接就係一片空白。然後:API同REST API嘅分別係咩?老實講,我從來冇坐低認真區分過呢兩個概念。我哋工作入面一直係混住用。API係你消費嘅嘢,呢個就係我心智模型嘅極限。直到事後我先去查咗REST到底係咩嘅縮寫、係咩意思。
事後嘅重新梳理
多租戶係真正令我震驚嘅地方,因為我知道自己以前處理過佢嘅一部分,只係冇全貌,更似係麵包碎而唔係成塊麵包。當下冇辦法即刻回憶起嚟。但等我冷靜落嚟、坐低認真諗嘅時候,佢比我預期嘅更快就諗通咗。
業主嘅比喻其實比我當時畀嘅評價要企得住腳得多。想像一棟公寓大廈,對比一片獨立屋嘅社區。喺多租戶入面,你嘅租戶(使用你應用嘅唔同客戶或組織)共享同一套底層資源,即係「呢棟大廈」:一份代碼庫、一個運行中嘅應用程式,通常仲有一個數據庫,每個租戶嘅數據喺邏輯上被分隔開(例如透過一個tenant_id欄位,或者每個租戶一個獨立schema)。業主嘅優勢正正係我當時感覺到但講唔清楚嘅地方:維護、打補丁、擴容一棟大廈,遠比揸車繞住一片獨立屋一戶一戶咁修理要容易得多。而代價就係同一枚硬幣嘅另一面:租戶共享資源,所以一個嘈吵嘅鄰居(例如某個租戶將數據庫打爆,或者一個bug導致數據喺租戶之間洩漏)帶嚟嘅風險,會比喺完全隔離嘅單租戶配置入面大得多。
provider同broker最後發現都冇當時感覺嘅咁陌生。
Provider(提供者)(喺Laravel入面係*service provider*)其實好接近我當時摸索緊想講嘅嘢:佢係啟動引導層。當應用啟動時,provider會將各種構建模塊——數據庫連接、設定、第三方整合——註冊入應用嘅容器入面,咁樣等你嘅代碼開始運行時,佢所依賴嘅一切都已經接好線、準備就緒。與其話係「採購」,不如話更似「應用正式開門營業前嘅裝配線」。
Broker(經紀/代理)係個中間人,我嘅直覺喺呢一點上並冇錯,只係喺壓力下冇能夠將呢個定義抓住。broker坐喺兩個本來唔需要直接互相認識嘅當事方之間。佢由發送方接收訊息,並路由畀應該接收嗰一方,咁樣發送方就永遠唔需要知道另一端係邊個喺度聽。
真正戳中我嘅地方係呢個:我一直大量使用Redis。隊列、快取、pub/sub,好一段時間以嚟都係我技術棧嘅一部分。但我從來冇坐低將「呢個我一直喺用嘅嘢」同「broker」呢個詞聯繫埋一齊。我喺用緊呢個工具,卻從來冇畀佢所屬嗰個類別改過名。RabbitMQ我只係聽講過,從未掂過。Kafka喺呢三者入面係最陌生嘅,我連佢係做咩嘅都講唔出嚟。所以當我被問到broker嘅時候,我腦入面一片空白,唔係因為缺乏經驗,而係因為我從未畀自己已經擁有嘅經驗貼上標籤。
Observer(觀察者)同dispatcher(調度器)都係類似嘅情況,不過等我坐低認真諗過之後,呢個空白就更講得通。當時我可以畀到嘅只有「有啲似係狀態變化時會運行嘅一個worker」。方向冇錯,但好模糊,因為我確實唔知道observer通常係綁定喺一個數據庫模型上嘅:佢監聽一個模型被建立、更新或刪除,並作出反應,而原始代碼完全唔需要知道佢嘅存在。dispatcher我本能上理解得更準啲,我將佢理解為「事件發生咗」,呢個已經比較接近:dispatcher會將一個job、事件或訊息發送畀應該處理佢嘅嗰樣嘢。
事後諗吓,我覺得呢個與其話係知識上嘅空白,不如話係經歷上嘅空白。observer同dispatcher嘅價值,係喺多個用戶或多個服務互相交互、真係有值得反應嘅事情發生時先體現出嚟嘅。我嘅作品集項目從來冇咁複雜過。大多數項目入面都係我一個做用戶,所以好少有需要觸發另一處反應嘅「第二個行動者」。我真正掂過呢個模式嘅地方只有發送電郵嘅調度,而呢個甚至只係呢啲模式用途中好窄嘅一角。有時候我會希望自己作品集裡面有一個更進階嘅項目,一個真正有多用戶交互嘅項目,咁樣我就可以自然咁掂到呢啲嘢,而唔係等到被人問起先第一次聽到佢哋嘅名。
仲有API同REST API嘅問題,事後回想幾乎有啲尷尬。API係一個廣泛嘅總稱:任何兩塊軟件互相通信嘅既定方式都算。REST係構建API嘅一種特定架構風格,基於HTTP,將一切都當作用URL識別嘅「資源」,用標準動詞(GET、POST、PUT、DELETE)去操作佢,無狀態,一次一個請求,唔記得之前發生過咩。所以REST API係API嘅一種特定類型,而唔係佢嘅同義詞。每一個REST API都係API,但唔係每一個API都係REST。
我由呢件事度帶走咗咩
呢啲概念冇一個對我嚟講係真正陌生嘅。呢一點有啲刺痛,但都正正係呢一點令我想將佢寫低。我喺工作中已經接觸過呢啲想法中嘅每一個。我缺嘅唔係接觸經歷,而係將「我用過呢個」變成「我可以清楚咁向第二個人解釋呢個」嘅能力。做同解釋之間嘅呢個落差,顯然係三年經驗都依然可能令你暴露短板嘅地方。
我而家唔將呢個當成一次失敗,而係當成一份清單嚟對待:多租戶、provider、broker、observer、dispatcher、REST。呢啲都係我用過、但從來冇被要求當面辯護清楚過嘅概念。值得喺下次有人再問之前,將佢哋釘牢。