[FollowMe8][B02] 為什麼要自己設計後端

為什麼要自己設計後端

一開始規劃 FollowMe8 的架構時,我第一個評估的就是 Firebase。

畢竟,對於一個獨立開發者來說,要寫一款包含「即時地圖定位」的 App,Firebase 絕對是最有誘惑力的捷徑。只要引入 SDK,寫幾行程式碼,手機位置一改變,其他人的螢幕馬上就會收到更新。不用管伺服器、不用寫後端 API,當時想著如果用它,應該很快就能把 App 趕出來。

但當我滿懷希望地仔細檢視它的付款規則時,我猶豫了。

不可否認,Firebase 給的免費額度其實挺高的。但身為一個獨立開發者,我有一種深層的「帳單恐懼症」。這種按使用量無限擴張的計費模式,總讓我有一種隨時會掉進陷阱的錯覺。

最後我默默關掉網頁,決定回到最原始也是最踏實的做法:自己來架 Server。


帳單恐懼症

我對大廠雲端計費的恐懼,並不是杞人憂天。只要實際推算一下 FollowMe8 的使用場景,就會知道為什麼我不敢冒這個險。

Firebase 的計費邏輯看似合理:免費額度用完後,就依據資料的讀寫次數(Document Reads / Writes)來算錢。

我們來算一下 FollowMe8 實際的使用場景:
假設一個 10 人的重機車隊出遊,為了讓地圖上的頭像平滑移動,每個人每 3 秒鐘更新一次位置。
1 分鐘:每人寫入 20 次,10 人總共寫入 200 次。
1 小時:總寫入 12,000 次。
讀取呢? 每更新一次位置,要發送給另外 9 個人。所以讀取次數是寫入的 9 倍。1 小時總讀取 108,000 次。

這只是一個 10 人車隊、一小時的用量。

週末到了,大家出門騎車,就算只有 10 個這樣的車隊同時在使用,一個 4 小時的下午,就會產生 四百多萬次讀取。如果 App 稍微有點人氣,一兩百個車隊在使用呢?

當一個免費或無獲利模式的 App 變得受歡迎時,它通常是開發者惡夢的開始。因為週末當你在睡覺或出遊時,伺服器背後的計費表正以你無法控制的速度在狂跳。

「不知道下個月信用卡會被刷多少錢」的焦慮,是獨立開發者最不該承受的心理壓力。

所以我默默把 Firebase 關掉。我們回到最原始的路:自己買一台固定月租費的主機(不管流量怎麼衝,每個月就是付幾百塊),自己寫後端。

面對雲端帳單的恐懼


面對海量連線的現實:Go 與 Redis 的組合

既然決定自己架 Server,首先要解決的就是效能與併發這場硬仗。

這套系統有一個無法逃避的現實問題:單一裝置每 3 秒發送一次位置,一個 10 人車隊一分鐘就會產生 200 筆更新。如果週末有一百個活動同時進行,伺服器每秒鐘要面對幾千筆的座標湧入,這些海量的資料該怎麼處理?

要在零環境維護成本下扛住這種高併發,我首先選擇了 Go (Golang)

Go 天生就是為高併發而生的,它的 Goroutine 讓伺服器即使同時處理幾千個連線也輕而易舉。而且它編譯後會產生一個獨立的執行檔,不依賴任何外部環境,丟到 CentOS 或 Ubuntu 敲個指令就能跑。對沒有維運團隊的獨立開發者來說,簡單好部署就是壽命。

但光有 Go 處理網路連線是不夠的。如果把這每秒幾千筆的連線全部轉成對傳統資料庫硬碟的寫入指令,資料庫的 I/O 絕對會瞬間卡死。Go 接連線接得再快也沒用。

Go 的高併發,必須配上一個扛得住高頻寫入的傢伙才能發揮威力。這時,我們才引入了 Redis。

Redis 的讀寫全在記憶體內,我引入它的目的非常單純:純粹把它當作 Cache(快取) 來配合 Go 的節奏。大量的座標更新直接在 Redis 的記憶體裡高速讀寫、並由 Go 即時廣播給同活動的其他成員。這個「Go + Redis」的高效能組合,完美扛住了高併發場景,絲毫不給伺服器磁碟帶來壓力。


資料庫只記錄當下位置,不留軌跡

解決了海量資料的效能挑戰,接著要回答產品理念的核心承諾:隱私。

基本盤的活動資訊與 Token,我們選用最熟悉的 MySQL 來存。但在處理最敏感的「位置資料」時,我們做了非常極端的取捨。

一般定位 App 即使宣稱不留資料,通常你的「最後一筆位置」還是會躺在資料庫裡。如果要落實「不留痕跡」,開發者就得寫定時排程去硬碟裡清資料,但只要是寫出來的程式,就有出 Bug 沒清乾淨的風險。

為了徹底斬斷這個可能性,我們直接在資料表的設計上做限制:MySQL 裡根本沒有建立「歷史軌跡」的資料表,每個成員在資料庫裡永遠只擁有一個「當下位置」的單一欄位。

每次有新位置傳上來,就是直接覆寫掉上一筆。當你關閉 App、結束活動,這個欄位就不再更新。這代表你過去騎了兩個小時的路線圖,從來就不會存在於 Server 端。

為了在絕對隱私跟使用彈性之間取得平衡,所有的歷史軌跡都只會留存在使用者自己的手機裝置上,供使用者自行回查。

「不留痕跡」不是寫在隱私條款裡的一句口號,而是直接在架構上做物理閹割。從資料結構層的源頭,我們就切斷了「在伺服器端記錄軌跡」的可能性。這才是對隱私最絕對的防衛。

架構圖


繞了一大圈,放棄了 Firebase 的便利,選擇自己架主機、學 Go 語言寫後端、引入兩種資料庫。剛開始看起來像是在找自己麻煩,但當架構真正組合起來的那一刻,你會發現:

每個技術選型,都在完美服務最初的產品理念。

處理完了後端的基建,我們這時候可以來談談那個最反直覺的設計了。不需要註冊、不需要登入,到底要怎麼在 App 裡識別「誰是誰」?


想了解更多 FollowMe8 的設計故事,歡迎造訪 FollowMe8 官方網站

分類: [B] 架構奠基, FollowMe8 短期活動追蹤定位 - 開發手記,標籤: , , , , , 。這篇內容的永久連結

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *