從蛋糕店的例子,學習軟體系統設計

2023年9月3日

💎 加入 E+ 成長計畫 與超過 350+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

本篇最早收錄於《ExplainThis 全端雙週報》第八期

系統設計現在基本上是軟體工程師面試必考的問題。假如你對系統設計沒有概念,讓我們透過這篇文章,用蛋糕店的例子帶你理解在軟體系統設計時要考量的點。

假如今天你是位手藝了得的蛋糕師傅,你決定自己出來創業開蛋糕店。一開始你只有自己一個人,所以什麼都要自己來,需要自己買材料、做蛋糕、顧店等等。顯然假如只有自己一個人,當客人一多就會忙不過來。這跟軟體系統一樣,假如只有一個單機伺服器,流量一大就會有撐不住的狀況。

如何擴展?

這時就要思考如何規模化。一種方式是你每天喝紅牛,讓自己保持滿血狀態一個打十個;在系統設計上這叫垂直擴展,就是把單一機器的性能提升,讓機器能承載更大的流量。然而就像人喝紅牛還是有個極限,單一機器升級也是有其極限所在。因此多數時候,你會需要考慮水平擴展。

所謂的水平擴展是指多加機器,來乘載更大的流量。在蛋糕店中,你可以多雇用更多人,讓每個人分擔你的工作量,這樣你就不需用每天灌紅牛來一打十。然而,當你雇用人來幫你分擔工作,你就需要確保每個人的工作量平均,才不會有人很閒,但有人操得要死做後離職。

選擇水平擴展的方式也是如此,當你有多台機器時,你要確保機器能平均分配到要處理的流量,才不會有的機器閒置沒在運作,但是有的機器處理量爆多導致應付不來。在系統設計中,我們會加入平衡負載器 (Load Balancer) 來解決這件事,透過平衡負載器,能夠有效讓機器平均分擔要處理的量。

從蛋糕師傅晉升蛋糕店長的你,如今顧了人也確保大家不會太閒與太操,好像就可以安心退居幕後了? 當然這樣如意算盤就打得太早,要規模化蛋糕店的事業,還有很多面向要顧及。舉例來說,假如要把服務的客人從原本在某個縣市,拓展到全國,就會遇到一些問題。

如何加快速度?

有些蛋糕店是不開分店,堅持要由本店製作再外送到全國各地,但是這會導致在比較遠的客人,總是需要等很久才能收到訂購的蛋糕。要解決這問題,可以在各地開分店,先把中央工廠做好的蛋糕送到分店,這樣客人要訂購時,就近把蛋糕送給在當地的客人。在系統設計上,(cache) 也是扮演相似的角色,在客戶端要拿資料時,就近跟快取拿,而不用跟資料庫拿,就能加快響應時間。

當蛋糕店生意越做越好,可能會想要多角化服務,像是許多蛋糕店現在也會同時賣飲料。而飲料是要現點現做的,當現場客人多的時候,就會遇到客人要等的狀況。但在做手搖飲的現場通常混亂,要如何有效分派哪個工讀生泡哪杯飲料呢?

很簡單,現在許多手搖飲店,會依照客人點飲料的順序,把要製作飲料的單號按照先來後到的順序貼在成一排,先貼的單號會先被有空擋的工讀生拿下來開始製作。只要該工讀生一泡完手上那杯,就再去拿目前最前面的待做飲料。

如何有效處理繁多的任務?

在系統設計中,隊列 (queue) 的機制,也是類似的方式。所謂的隊列是先進先出,就像飲料店的做,先點的客人的單子會先被處理。在隊列的機制下,就可以有效讓多個 workers 去處理在隊列中的任務,先放到隊列的任務先被處理。而處理完手邊任務的 worker,就去處理目前在隊列中最前面的那個任務。透過隊列的機制,讓管理工讀生們變得輕鬆許多。

在導入了許多機制後,蛋糕店運作相當順利。然而很多時候意外是不可預知的,例如某個地區的店突然遇到店面被閃電打到,以至於電力系統出問題沒辦法正常營業。這時來店的客人就會撲空買不到蛋糕。總店為了解決這問題,導入一個即時監控與通報機制,當某間店有意外出現時,趕緊調派人手到現場把客人引導去鄰近分店,讓客人還是能就近買到蛋糕。

在軟體系統中,也會需要有觀測 (observability) 平台,來做即時記錄 (logging),以及指標 (metrics) 監控,還有警報 (alarm) 發出,確保系統的整體穩定度,不會因為單一個服務掛掉而導致客戶端請求沒辦法被處理。

有了監控報警系統,蛋糕店創始人對於整個品牌的穩定度感到放心許多,似乎可以好好退居幕後了。當然事情沒那麼簡單,身為蛋糕店經營者,在運營蛋糕店時有非常多決策考量。接著我們將進一步從決策者的角度,來談在真實世界的系統設計,有哪些重要的考量點。 󠀠

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們