經驗分享:從高流量的單體PHP應用到無伺服器

banq發表於2019-06-23

我們的平臺基於自動擴充套件組中的亞馬遜的AWS EC2例項,它是由強大的RDS MySQL資料庫支援。隨著最近對應用程式的更改,資料庫變得越來越成為環境的瓶頸,因此我們需要將其擴充套件,從而導致更高的AWS賬單。

我們不喜歡這樣工作,並建議與客戶進行頭腦風暴會議,以改善平臺。在與客戶的這次會議中,我們很快得出結論,我們都希望遠離傳統的基礎設施,這將涉及必須從頭開始編碼。我們的想法是將經典的單體PHP設定轉換為完全無伺服器的架構。

為什麼無伺服器

我們需要一個平臺,幾乎可以立即從每分鐘處理0到50k請求以及更多。正常的自動縮放無法處理這個問題所以我們需要在盒子外面思考。

通過使用AWS的無伺服器元件,我們很快意識到這些是這個用例的完美選擇。您只需為實際使用的執行時付費,並且在不需要執行額外容量時沒有任何空閒成本。

怎樣的資料庫

舊平臺在RDS上執行,這是一個瓶頸。我們檢視了儲存的資料並得出結論,nosql資料庫最適合。我們根據需要選擇了最近宣佈的DynamoDB,因為這樣只需支付我們消費的費用,我們就不必過度配置表來處理流量峰值。

為什麼要新增Kinesis

在無伺服器環境中儘可能地解耦是關鍵,因此我們通過在API閘道器和資料庫後面的Lambda函式之間新增Kinesis來應用AWS的一個良好架構模式。通過這樣做,如果資料庫層出現問題,我們將有一個緩衝區。最重要的是,Kinesis提供了在規定時間內儲存記錄的功能。這增加了資料的可靠性。

通過POC和負載測試確認

在進行初始設計之後,我們需要驗證新設計的平臺是否能夠處理估計的負載,最高可達50k請求/分鐘。

在開發基本api功能時,我們已準備好進行測試。很明顯,Lambda不會成為瓶頸。然而,負載測試表明,當負載測試的併發性增加時,記錄從Kinesis到Dynamodb的時間顯著增加。

這需要在我們繼續之前修復......

Kinesis可以輕鬆捕獲所有資料。然而,瓶頸是由Kinesis觸發的Lambda函式,負責將資料推送到DynamoDB。在調整每個Lambda函式處理的塊的批量大小後,我們沒有注意到任何顯著的改進。

在挖掘Kinesis的文件後,我們發現我們達到了Kinesis的讀取限制(每個碎片每秒5次)。有兩個選項:我們可以增加分片,這會將事件增加到Lambda,從而增加並行執行的Lambda函式的數量。選項2是啟用Kinesis的增強扇出功能; 這將通過為每個消費者提供其自己的吞吐量限制來改善每個分片的讀取並行性。

我們選擇增加碎片的數量,並通過負載測試確認,從Kinesis到Lambda功能的6個碎片和批量大小為300,我們可以滿足專案所需的容量。我們還確認該平臺可以通過增加Kinesis中的分片來處理更多。

結果

為了將所有東西粘在一起,我們使用了Concourse CI。在管道中,我們自動化了程式碼和基礎架構的所有部署。這使客戶能夠專注於開發,而不是整理出如何以一致和受控的方式部署程式碼。

這個過程產生了一個新設計的應用程式,可以滿足客戶的未來需求。前端託管在S3和Cloudfront上,與Lambda上執行的後端程式碼完全分開。持久層是未來的證明,基礎設施的空閒成本大大降低。

在此期間,該平臺提供154.396個會話,瀏覽量超過4300萬,峰值為25.000個併發使用者,平均頁面載入時間為1.07秒。

我們能夠將AWS賬單總額從4.636,41美元(對於類似的廣告系列)減少到400,19美元,與之前的廣告系列相比(節省91%),同時正常執行時間為100%。

有趣的事實:注意如何將Lambda的實際計算成本合併到該類別中Other Services; Lambda的總成本僅為2.05美元。

 

相關文章