中佑集團—技術驅動進步

從 PHP 轉向 Golang 的效能大解放

許多公司的 technology stack 都是以 Linux + PHP + Nginx 為公司標配的開發模式,以初期的發展模式來說PHP有幾個優點:

  • 社群龐大

選擇 PHP 的確是一時之選,但當到了公司的業績逐步成長時,追求的不再是快速開發,反而是需要著重穩定性,且執行效率優良的方案。

在團隊技術評估的過程中,考慮過的語言有:Node.js、Java、Python、Golang,而我們認為符合公司發展的程式語言條件有:

  1. 強型別

至於各語言的淘汰原因為下:

  • Node.js 啟動相關前置套件過於龐大,所以不採用。

Go的優勢:

  • 官方api文件非常好閱讀

基於上述理由,在 2015 年時,決定導入使用 Go 1.5 開發的服務,開啟了團隊的 Golang 旅程。

一開始,從開發獨立服務,到後來著手針對現有系統拆分優化,在 Golang 的使用經驗上逐漸體會到許多的這個語言的優勢,舉以下例子說明:

在 2018 的「雙11」當天,台灣兩大購物平台紛紛掛點。我們就來談談,如何優化系統,把原本的PHP重構成Golang,改善瞬間流量的問題。

首先,為什麼一個系統會掛點?

最終的問題就是:每個 request 的處理速度不夠快,只要 request 處理得不夠快,最前面的服務就會開始卡連線,造成一連串的雪崩效應。當然任何東西還是有所謂的物理極限所在,所以當 request 數量一多,每一台機器單個request 處理速度一定會等比上升。

舉個例子,當時服務單個 request 的平均時間約是 800ms,而那時用壓力測試工具作壓測,設定 1000 req/s;這時測起來,數據想當然慘不忍睹,平均時間拉到 2s 以上了。這個回應時間如果拉得越長,會佔用服務的 port 越久,所以持續下去就會造成服務整個 crash。

於是開始重構的計畫。要重構有歷史的 code,需要非常大量的閱讀,但是大致上整理出當時的幾個消耗點,如果直接針對那幾點作優化,相信也能拉低平均的 request 時間。

  1. 過多的防禦邊界,每個套件間都在作重複的驗證,造成一個 request 可能重複驗證了 3 - 4 次以上。

那接下來,我們來說明一下重構的思維。把重構的目標先類比成一個購物最後結帳的 api,大致上分為以下流程:

  1. 確認使用者身份。

正常的設計流程圖如下:

就是很直線的方式,沒有什麼不對。但其實可以仔細思考:2、3 兩點其實是可以抽出來平行處理作檢查的,如果 2、3 每個各需要花費 50ms,用直線的方式處理,就至少吃了 100ms,所以總時間花費需要 200ms。

那為什麼會挑 2、3 出來說呢?因為1是【身份驗證】,沒有 1 後面什麼都不能做。4 則是【扣款】,也是一個很獨立的流程。反之 2、3 跟主流程沒有絕對的前後依賴關係,所以讓他們併發同時處理再適合不過了。利用 Golang 的特性,很容易做到下圖:

雖然使用 Goroutine 很方便,但是畢竟它是併發運算(concurrency),而不是平行運算(parallel),一定有會有一些 CPU context switch 的相關消耗,所以這邊假設兩個流程併發處理是 60ms,而不是變成 50ms。

用上述的方式就有別於 PHP,而是運用 Golang 的特性做效能上的提升,但這邊還是要注意,不要太過於依賴 Goroutine,任何系統開發都還是有所謂的資源限制。

團隊從導入 Golang 後,跟著技術潮流持續發展,順利接上了 Kubernetes,也朝向微服務、NSQ 事件流、Istio、GitOps、ChatOps 等接軌,從開發、部署,到維運一條龍,不斷進步,品質與效率並進。

關於我們

曾經,我們覺得外面的月亮比較圓,只能對著別人的成功案例流口水;曾經,我們覺得在挖得比海深的專案海中,技術只能被犧牲。

近三年來,我們透過專案管理手法,在專案趕工之餘,工程師們輪流主動的建構著基礎建設。只要流程不順,大家停下手邊工作重新討論工作流程,需要引入新工具,就專案重新分配,指派同仁研究導入。也相揪參與大小研討會,帶回工具外,更重要的是帶回新的觀念。

有好的基建設,才能無後顧之憂的在專案海中奮戰,甚至這樣的開發品質也能回饋在產品運營上,減少 on call 的機會,讓工程師有充足精神持續創造高品質的產出。

永遠不滿足現況,不斷改進、不斷進步,是我們團隊的共同信念,今天多在基礎建設多扎一寸根,明天就能在專案上多建高一寸。

關於筆者

syhlion,今年33歲已婚,育有兩女,兄弟象迷(非中信兄弟),各種雜學皆略懂。

The official blog of GopherCon Taiwan

The official blog of GopherCon Taiwan