為什麼要自己設計後端
一開始規劃 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 秒發送一次位置,週末如果有一百個活動同時進行,伺服器每秒鐘會湧入大量座標。
如果用傳統寫法,把這些頻繁的更新直接塞進 MySQL 資料庫,硬碟 I/O 很快就會卡死。伺服器一旦掛掉,戶外的車隊就全部斷線了。我沒有專屬的維運團隊可以 24 小時盯著伺服器,所以我需要一個「丟上去就不用管」的組合。
我選擇了 Go (Golang) 加上 Redis。
Go 編譯後就是一個單獨的執行檔,不依賴任何外部環境。丟到 Linux 主機上敲個指令就能跑。不用管 Node.js 版本、不用裝 Python 套件,對一個人管伺服器的場景來說,部署越單純越好。
而 Redis 則是這套系統的緩衝區。它的讀寫全在記憶體裡,大量的座標更新直接在 Redis 裡高速讀寫,由 Go 即時廣播給同活動的其他成員。這個組合穩穩接住了所有即時更新,完全不給伺服器磁碟壓力。不用整天擔心資料庫卡死。
讓位置資料自然過期
解決了連線壓力,接著是兌現「隱私零煩惱」這個附加價值。
一般定位 App 即使宣稱不保留歷史紀錄,通常還是會把位置寫進資料庫,然後再寫排程去清理。但只要是寫出來的程式,就有出 Bug 沒清乾淨的風險。
為了解決這個疑慮,我在架構上做了一個取捨:位置資料根本不進 MySQL。
MySQL 只負責存活動資訊與 Token,而最敏感的「當下位置」完全交給 Redis 處理。Redis 有一個 TTL(Time To Live)機制,可以設定資料的存活時間。每次位置更新,這筆資料的壽命就被設定為短短幾分鐘。
只要 App 關閉、活動結束,這些位置資料時間一到就會在記憶體裡自動蒸發,連清理的排程都不用寫。過去兩小時騎過的路線圖,從頭到尾就不會存在於 Server 端。
所以當領隊告訴團員「這個 App 不會一直追蹤你」時,這句話不是使用者條款裡的空頭支票,而是系統架構層就切斷了偷存軌跡的可能性。

繞了一大圈,放棄了 Firebase 的便利,選擇自己架主機、用 Go 語言寫後端、引入兩種資料庫。乍看比 Firebase 多繞一段,但當架構組合起來之後,這些選擇就接得起來了。
每個技術選型,都對應到最初的產品理念。
處理完了後端的基建,我們這時候可以來談談那個最反直覺的設計了。不需要註冊、不需要登入,到底要怎麼在 App 裡識別「誰是誰」?
想了解更多 FollowMe8 的設計故事,歡迎造訪 FollowMe8 官方網站。