Cloudflare 從 PHP 到 Go:遷移與經驗分享
大家好,我是煎魚。
在現代軟件開發中,技術棧的選擇對于項目的成功至關重要。隨著業務需求的演變,技術遷移成為了一個不可避免的話題。
在本文中,我們將探討從 PHP 到 Go 的遷移過程。分享來自 Cloudflare 的資深工程師 Matt Boyle 和 Chris Shepherd 的見解和經驗。
主要內容將涉及他們遷移的動機、挑戰、以及在這個過程中的心得體會。
遷移動機
性能考量
Matt Boyle 指出,他們開始考慮從 PHP 遷移到 Go 的一個主要原因是性能。例如:他們有一個系統在 PHP 中只能處理大約 10 個請求每秒,并且消耗了大量的 CPU 和內存資源。
而在遷移到 Go 后,相同的系統能夠處理數千個請求每秒,同時 CPU 和內存的使用量卻大大降低。
招聘與人才吸引
Go 語言以其高性能和簡潔性而聞名,這使得它成為吸引技術人才的一個亮點。
Chris Shepherd 提到,Go 語言的流行使得公司能夠吸引到更多對新技術有興趣的開發者,比如在柏林的初創公司中,Go 語言的開發人員需求正在增長。
生態系統和工具鏈
Go 語言擁有一個強大的標準庫和活躍的社區,這為開發者提供了豐富的工具和庫。例如,Go 的 net/http 包提供了一個強大的 HTTP 服務器框架,使得構建 RESTful API 變得簡單。
此外,Go 的編譯型特性使得容器化部署變得簡單,相較于 PHP 的解釋型特性,Go 應用的容器鏡像可以做得更小,這在云原生時代尤為重要。
遷移過程
逐步遷移 vs. 重寫
在遷移過程中,Matt Boyle 建議采取逐步遷移的策略,而不是完全重寫應用。
例如,他們沒有選擇一次性將整個應用從 PHP 重寫為 Go,而是構建了新的 Go 服務來處理特定的業務邏輯。
同時保留 PHP 服務處理其他邏輯,這種方法被稱為 “絞殺者模式”(strangler pattern)。
絞殺者模式
數據一致性挑戰
Chris Shepherd 分享了一個關于數據一致性挑戰的故事。
在他早期的一次遷移中,一個簡單的數據類型變更(將字符串類型更改為時間戳)導致了服務間的不一致,從而影響了用戶的數據展示。
這個故事強調了在分布式系統中保持數據一致性的重要性。
學習曲線
兩位嘉賓都提到了從 PHP 到 Go 的學習曲線。例如,Go 語言的并發模型(使用 goroutines 和 channels)與 PHP 的多線程處理有很大的不同,需要時間去適應和學習。
goroutines + channels
Chris 回憶起他最初使用 Go 時,對于如何正確地使用 goroutines 和 channels 進行并發編程感到困惑,但隨著時間的推移,他逐漸掌握了這些概念。
遷移中的挑戰與解決方案
分布式系統的復雜性
遷移到 Go 后,開發者需要面對分布式系統帶來的復雜性,包括網絡延遲、數據同步等問題。
Matt Boyle 強調了在遷移過程中對基礎設施和可觀測性的投資的重要性。
例如:Cloudflare 跟蹤了一個名為 “復制延遲” 的指標,以確保數據在不同的數據庫副本之間同步的時間差異最小化。
Replication Lag
技術債務
Chris Shepherd 提醒我們,即使是使用 Go 語言,技術債務也是不可避免的。新寫的 Go 服務可能并不完美,需要時間去迭代和優化。
例如:他們最初在 Go 中實現的一個服務可能沒有考慮到所有的邊緣情況,導致在高負載下出現性能問題,這需要后續的優化和重構。
依賴管理
Go 語言的依賴管理曾經是一個痛點,但隨著 Go Modules 的引入,這一問題得到了改善。
圖片
Go Modules
Matt Boyle 回憶了過去處理 gopath 的痛苦經歷,并對比了 Go 和 PHP 在依賴管理上的差異。
例如:PHP 的 Composer 可以輕松管理項目依賴,而 Go 直到 Go Modules 出現之前,依賴管理都是一個挑戰。
總結
從 PHP 到 Go 的遷移是一個復雜的過程,涉及到性能優化、團隊技能提升和工具鏈的更新。
通過逐步遷移、重視數據一致性和分布式系統的挑戰,以及對技術債務的管理,團隊可以更平滑地完成這一過程。
Matt Boyle 和 Chris Shepherd 的經驗分享為我們提供了寶貴的洞見,幫助我們理解遷移的動機、過程和挑戰,以及如何成功地完成這一旅程。