[前端工程] 打造可規模化前端應用的 6 個原則
Vercel 現任 CTO (同時是前 Google 首席工程師) Malte Ubl 先前給了一個《Principles for Scaling Frontend Application Development》講座,談前端應用規模化的六個原則。
排除障礙 (Tear down the barriers):在規模化的過程中,會遇到多個團隊要共用元件的情境。過去可能用 NPM 來管理共用的元件,但這種方式不僅麻煩且難管理。Malte 的建議是採用 monorepo,可以讓共享的阻礙變低
讓刪除程式碼變簡單 (Make it easy to delete code):大型程式碼庫很長會變難以維護的原因在於,新接手的人不敢刪掉一些沒有在用的程式碼,因為擔心影響到其他有關連的程式碼。要緩解這問題,Malte 推薦盡可能用共置的形式,例如用 TailwindCSS 會把 CSS 跟元件寫一起,這樣要刪就能確保相關的東西會一併處理掉,不擔心刪了某個 CSS 結果影響到其他元件。
漸進式遷移 (Migrate incrementally):一次行大規模遷移往往容易導致遷移失敗,而且可能會遇到發現某個錯誤,整個大規模遷移都要回滾的問題。逐步的遷移可能會因為時間拉長而在過程中被質疑遷移成效,面對這狀況要儘早用範例來證明遷移是有價值的。
永遠變更好就不會變更差 (Always get better, never get worse):要維持程式碼的品質,可以引入一些工具,例如 Linting 工具。越早引入工具,會讓未來寫的新越早程式碼被檢查,會讓引入工具的價值提高。
擁抱缺乏知識 (Embrace lack of knowledge):新加入團隊的人,對於大型程式碼庫一定會缺少相關的背景脈絡,作為團隊領導人要做的是接受這個事實,並打造一個讓人即使有缺乏的背景知識,仍能做對事的系統。前一點提到的 Linting 工具就是一種方式,新加入的人不用有程式碼寫法的背景脈絡,但如果有不符團隊的寫法,系統中會有機制來自動提醒。
減少系統複雜度 (Eliminate systematic complexity):在 Google 這類的大廠很常會有版本偏差 (version skew) 的問題,例如後端做了某個改動,但前端還沒有更新相對應的改動,導致兩者之間有偏差。這種問題不是單一元件的問題,而是需要系統性的解決。舉例來說設計機制,確保前端永遠會請求到相對應版本的後端。
[後端與系統設計] LinkedIn 如何提升資料庫讀取規模,同時降低成本
LinkedIn 是全球最大的職涯社群網站,在尖峰時期每秒鐘要處理將近五百萬個使用者的頁面請求。在《Upscaling LinkedIn's Profile Datastore While Reducing Costs》一文當中,LinkedIn 的工程團隊分享了他們如何導入 Couchbase 資料庫作為快取層,有效提升響應速度,以及降低成本。
在引入到 Couchbase 之前,LinkedIn 的使用者頁面是純透過開源的 Espresso 資料庫來做儲存。該資料庫的規模化很簡單,就是增加新的節點 (增加更多硬體)。但是隨著使用者人數提高,LinkedIn 團隊發現純增加節點的方式不堪負荷,需要投入大量資源改造,才可能持續擴張。因此決定找新的解決方案。
對於 LinkedIn 這種社群網站的應用,在系統設計上有個關鍵點,就是讀 (read) 的比例會遠大於寫 (write),比例上是 99 比 1,因此 LinkedIn 團隊選中 Couchbase 作為快取 (cache) 層,來處理大量的讀的請求,這樣當大量讀的請求進來時,不用一直增加 Espresso 的節點。
在設計快取的解決方案時,LinkedIn 團隊考量三個重點。第一個是韌性 (resilience),意即當快取出問題時不會影響到系統中的其他元件;第二個是快取資料要隨時可用,LinkedIn 團隊的作法是把使用者頁面的資料快取在每個資料中心 (因為資料量不大,所以這可行);第三則是要避免資料分歧,LinkedIn 團隊的作法是透過在有資料被更新時,去比較時間戳記,選最新的那個去更新到所有同鍵的快取。
雖說引入 Couchbase,LinkedIn 團隊沒有只用 Couchbase 作為單獨快取,而是採用 Espresso 與 Couchbase 混合快取的策略。從架構上來看 (原文的圖 2),當使用者頁面的服務發送請求後,會先被判斷要索取的資料是可被快取的,然後判斷 Espresso 路由器有沒有快取,以及快取是否太舊,假如沒有或太舊,就去 Couchbase 拿。如果 Couchbase 沒有該資料的快取,才去儲存節點拿該資料。
當有寫的請求 (使用者頁面的資料被更新時),會確保快取有跟資料庫的資料是一致的。LinkedIn 團隊實作了快取更新機制,是採用最終一致性 (eventual consistency) 來更新。如前面有提到,當有多個寫入,會用時間戳記的方式來比較,藉此確保所有快取都是更新到最新的更動。
透過整合 Couchbase 作為快取,LinkedIn 的使用者頁面團隊,最終能夠更有效處理更大量的讀的請求,加快響應速度超過 60%,同時每年降低將近 10% 的運算成本。
[軟體業職涯] 以產品為中心的開發思維
在全端雙週報 #4 我們曾討論在產品開發、基礎設施這兩條路線中,該選哪一條作為你的職涯發展路徑。今天想透過開源社群中開發出非常多好用工具的 Tanner Linsley 寫的《The Art of Shipping: Prioritizing Product Development Amidst a Developer-Centric Landscape》一文來延續這個討論。
Tanner 本人雖然是以開發開源工具聞名,但他認為工具最終的目的是被使用,所以最終應該要回到使用者為中心。他認為工程師很常會把焦點過度集中在優化工具與流程,但這些元素的存在,應該是為了滿足開發產品的需求。
當然隨著產品所在的階段不同,這些元素的優先順序也會不同。Tanner 的觀點是,在前期應該要放下對工具與流程的執著,等到產品獲得足夠的成功,再來想效能優化與規模化等議題,而在那個階段,流程與工具自然會變得更重要。
對於工程師來說,要在最開始放下這些執著,可能有點困難。但 Tanner 個人的親身經歷是,在轉變成以使用者與產品為中心的想法後,雖然寫出來的程式碼不見得是效能最好,或是最容易規模化,他覺得不要緊,因為那些終究是執行的細節。
這個觀點讓人想到 Google Chrome 的工程總監 Addy Osmani 曾說「軟體是創造價值的媒介,不要迷失在工具當中,要把目光聚焦在創造出的價值 (Software is a vehicle for delivering value to people. Don’t get lost in the tools; keep your sight fixed on the value created)」。
不知道讀者們怎麼看? 是否同意他的觀點? 假如你過去不是以這種角度出發思考,或許可以試試看改變你的觀點,在職涯上可能會創造出更大的影響力。
本期推薦
開源全端框架 Wasp 最近推出一連串的新功能,假如你想用 Rail 式的框架但是寫 JavaScript,不妨可以一試 [連結]
去年發表後在社群轟動的 JavaScript 執行環境 Bun,在經過一年的推近後,終於要進到 1.0 版了,有興趣的人可以看線上發表 [連結]
最近社群中熱門的 ORM 逐漸從 Prisma 轉向 Drizzle 後,Prisma 強勢推出 5.0 版本,在效能上大幅優化。幾個月前 Prisma 團隊發表如何優化冷啟動的文章,很值得大家回味一下 [連結]
近期熱門的向量資料庫,跟其他種類資料庫有什麼區別? 背後是用什麼演算法運作? Pinecone 的《What is a Vector Database?》教學文寫得淺顯易懂,非常推薦
OpenAI 共同創辦人 (也是 Stripe 的前 CTO) 上週分享了一個 API 開發時的要訣,就是在寫錯誤訊息時,要有區別性,即使有些情境可能對 API 使用者來說是相同的,錯誤訊息還是要盡量有微小區別,要盡可能讓你能輕易辨別出錯誤是從程式碼中的何處來的。這個要訣真的是肺腑之言,讓人深有同感 [連結]
Meta 推出的 Threads 在五天達到一億註冊使用者,大廠在推出新產品與功能前,是如何做準備的呢? 可參考這篇短貼文 [連結]
前陣子看到這個圖,覺得是很不錯的提醒,努力與成效不一定是等比,很多時候是累積的。假如你正在往某個方向前進但是覺得止步不前想要放棄,或許再多堅持一下吧!
《設計思維與 ChatGPT,打造人性化的創新產品》工作坊
ExplainThis.io 與 ALPHA Camp 合作,將在 7/29 舉辦《設計思維與 ChatGPT,打造人性化的創新產品》工作坊。如果你對於如何串接 ChatGPT API、如何根據自己的資料來客製化 ChatGPT 的回覆感興趣,千萬不要錯過這場工作坊。工作坊將涵蓋將教大家提示詞工程 (Prompt Engineering)、ChatGPT API 串接、Langchain 使用、向量資料庫等,讓你在工作坊結束後有帶得走的成果!
🔥 早鳥特別優惠倒數 3 天,期待到時候與大家相見