一篇非常全面的無服務器遷移實踐
“無服務器”這個詞變得很流行。在本文,我將向你介紹如何將本地應用程序遷移至無服務器環境,非常詳細和具體,希望有助于你。
注:本文涵蓋了我在 2019 越南 Web 峰會(越南 IT 界最大的活動)上展示的所有內容。
如今,“無服務器”這個詞變得非常流行。它正在改變開發人員和企業使用公有云交付業務價值的方式。輸入這個“關鍵詞”,你很容易找到相關文章。但是,我確信,沒有幾篇文章會一步一步地向你介紹如何將本地應用程序遷移到無服務器環境,但是在本文中,我將這樣做!
我會向你展示一個案例研究,介紹我和我的項目團隊如何實現并交付給我們的一個客戶。
本文要點:
- 客戶存在的問題,為什么要采用無服務器?
- 通往無服務器解決方案之路;
- 我們的遷移方法;
- 我們面臨的挑戰。
1. 客戶存在的問題
我們的客戶提供了一個在線招聘平臺。下圖說明了該系統是如何工作的。
這是一個很傳統的系統,有 2 個 Web 應用程序:
1.身份服務器 Web 應用程序:
用于身份驗證和授權。這個 Web 應用程序提供了一些基本功能,比如用戶管理(CRUD)、登錄 / 注銷、用戶權限等等。除此之外,它還允許用戶與他們的谷歌 /Facebook 帳戶進行集成。
2.招聘 Web 應用程序:
這是整個系統的核心。作為一個用戶,我們可以使用求職功能來找工作,通過傳文件來上傳簡歷…作為一個管理系統,我們可以使用報表功能以及通過客戶溝通發送電子郵件、短信…
這些 Web 應用程序使用相同的數據庫,稱為“招聘”數據庫。除此之外,系統還包括了消息隊列、發送通知的后臺作業、報表的數據處理……
2. 那么,問題在哪?
問題 1:龐大的代碼庫
遺留系統太大,無法完全理解,特別是對新開發人員來說。
我們的客戶承認,有一次他們不得不編寫一個新函數來修復 Bug,而不是重構,因為導致問題的函數與其他函數緊密耦合。
問題 2:高昂成本
此外,他們必須購買一個好的服務器來部署系統。運營開發成本不小。
問題 3:可伸縮性低
系統中的模塊有沖突資源,所以如果他們想擴展特定功能,例如“JobSearch”,就必須擴展整個應用程序。
這造成資源浪費,即使接受了這種浪費,他們也無法迅速擴大規模。
問題 4:可用性低:
一旦他們發布一個新功能或改進,甚至修復一個小錯誤,他們就必須部署整個系統。
問題 5:可靠性低
任何模塊中的錯誤(如堆棧溢出)都可能導致系統崩潰。
此外,由于應用程序的所有實例都是相同的,因此 Bug 會影響整個應用程序的可用性。
問題 6:對新技術不開放
系統是用.NET 開發的,這意味著 Python、Java 的新特性永遠都無法使用,因為采用新技術會破壞現有的系統。
我想,你可以在你的公司或者你的客戶系統中找到類似的地方:)
3. 為什么要采用無服務器?
我不會直接給你答案,你可以通過以下事實找出答案:
據《財富》雜志報道,“車 95% 的時間都是停著的”。
擁有一輛汽車與購買裸金屬服務器并在該服務器上部署系統類似。日復一日,為了確保服務器正常工作而沒有任何問題,你必須維護服務器。
租車類似于使用 VPS 服務。你可以短期租用 VPS。
例如:圣誕節要到了,你預測很多學生打算找份兼職。在此期間,你可以租用 VPS 來支持應用程序的擴展。
雖然租車有助于改善使用情況,但最好的選擇是共享汽車,如優步、滴滴……
是的,這就相當于軟件領域的無服務器。
4. 通往無服務器解決方案之路
隨著云計算的發展,IT 基礎設施經歷了一場快速革命。為了給云上軟件增加更多的靈活性和可伸縮性,無服務器應運而生。下圖展示了 IT 基礎設施的革命。
20 世紀 90 年代
為了在本地服務器上部署應用程序,我們曾經構建并操作過本地服務器。服務器是為長期使用(并存在多年)而構建的。
但是,安裝、配置、操作都需要做大量工作。為擴展應用程序,我們需要擴展整個服務器。
2000 年以來
我們為部署服務器提供了一個新選項,虛擬機(VM)加入“游戲”中。
隨著 VM 出現的是虛擬專用服務器(VPS)。這便于我們短期使用(幾天或幾周),而且幾分鐘內就可以完成部署。擴展以機器為單位。
2011 年 Docker 出現
docker 的推出,我認為是近十年來 IT 基礎設施最大的變化之一。
它影響了我們設計軟件架構和部署應用程序的方式。與虛擬機(VM)相比,容器不僅可以使用更少的資源來提高應用程序的運行速度,而且還能擴展,使用多個容器協作在生產環境中交付服務。
但是,容器的廣泛使用極大地增加了管理它們的復雜性。
無服務器沒有使用容器來運行應用程序,無服務器計算用另一個抽象層代替了容器,在這個抽象層中,云提供商充當服務器,動態地管理機器資源的分配。
5. 我們的遷移方法
注:希望當你讀到這部分的時候,已經有了一些為什么我們應該采用無服務器的理由。如果沒有,請回到第二節和第三節再讀一遍,或者給我發信息。
下圖是我們系統未來的樣子,換句話說,這是我們和客戶想要達成的目標。
雖然由于某些原因我們選擇 Azure,但你也能很容易找到類似的 AWS 和谷歌云服務。
我們用 Azure Web 應用托管身份服務器,并使用 Azure SQL Server 為它創建獨立的數據庫。
此外,我們還用 Azure 流量管理器實現高可用性和故障轉移計劃。Azure 流量管理器是一個基于 DNS 的流量負載均衡器,它使你能跨全球 Azure 區域將流量以最優方式分配給服務。
未來系統中的求職 Web 應用程序將只包含 UI/UX,因為我們將把整個業務邏輯轉移到 Azure 函數。Azure API 管理(API Gateway)將被用作一個單一的入口,以確保來自求職 Web 應用程序的每個請求都必須通過它才能訪問 Azure 函數。
此外,Azure API 管理還集成了身份服務器來進行身份驗證和授權。
與身份服務器類似,我們還將 Azure Web 應用程序和流量管理器應用于求職 Web 應用程序。Azure 應用網關是我們的求職 Web 應用的防火墻。
即使身份服務器和求職 Web 應用程序被遷移到云服務,但它們不是無服務器,它們只是 PaaS。
要了解關于 PaaS 和無服務器的區別,請閱讀下面的文章:
https://www.cloudflare.com/learning/serverless/glossary/serverless-vs-paas/
Azure 提供了兩種無服務器架構方法:
Azure Function:這是一項無服務器計算服務,允許你運行事件觸發的代碼,而不必顯式地提供或管理基礎設施。
Azure Logic App:它有助于構建自動化的可伸縮工作流、業務流程和企業編排,以便跨云服務和本地系統集成應用程序和數據。
在未來的系統中,我們將包含以下 Azure 函數:
- 職位搜索
- 職位管理
- 客戶溝通
- 報表
- 發送郵件
- 發送 SMS
此外,還有一個用于“文件上傳”功能的 Azure Logic App。該功能需要使用不同的流來提供不同的文件類型。例如,excel 文件用于數據導入,jpeg/png 文件用于圖像上傳,需要調整大小…...
此外,我們還有其他 Azure 服務,比如 Azure 服務總線、用于文件上傳的 Blob 存儲、用于存儲日志數據的表存儲。Azure Application Insight 用于監控。
6. 遷移步驟
我們實現的新體系結構必須與遺留系統并行,以確保對當前業務沒有影響。
第一步,我們必須選擇遷移到無服務器的功能。
要說這不是一場噩夢可不容易。讓我們設想一下,你必須深入研究遺留代碼庫(我在上面提到過——海量代碼庫),并在沒有任何技術文檔或功能規范的情況下選擇對其他人影響較小的功能。
最后,經過業務分析團隊、產品負責人和開發團隊的多次討論,我們決定將“職位管理”作為采用無服務器的第一個功能。
下一步,我們創建一個 Facade 層 (https://sourcemaking.com/design_patterns/facade),它提供了對職位管理功能的高級抽象,重構了該功能的所有使用者以使用該 Facade。這為我們提供了一個單一的阻塞點,我們將從中限制功能。
現在,該做“快樂”的部分了——使用 Azure 函數和 Azure Cosmos 數據庫創建新的實現。在創建新功能時,謹慎起見,我們使用了與構建 Facade 時相同的抽象。
在這一步中,最重要的事情是使用 Cosmos DB 在現有數據庫和新數據庫之間同步數據,我們稱之為“回填”過程。
下一步,我們創建一個 Toggler——Facade 的第三個實現,它充當某種流量路由器,通過 Facade 層將請求轉發給現有功能或新功能(Azure 函數)。
一旦 Azure 函數可以使用了。我們從 Canary Launch 開始,配置 Toggler 的特性標志,使 2% 的請求被發送到 Azure 函數,而其余 98% 的請求被路由到現有的實現。
假設一切順利,我們可以慢慢地增加到新實現的流量,直到最終 100% 的職位管理功能請求都是通過我們的新 Azure 函數交付。如果在新實現中發現任何問題,將觸發回滾函數來回滾請求并將請求重定向到現有函數。
一旦我們覺得新實現令人滿意了——Azure 函數正在按預期執行——我們就進入另一個有趣的部分——刪除代碼!現在,我們可以刪除已經廢棄的“職位管理”功能的實現。我們現在也可以移除 Toggler 了。
7. 我們面臨的挑戰
無服務器是個好主意!這是一種新范式,可以應用于在云中開發和運行的現代化應用程序,從而極大提高開發人員的注意力和工作效率。
但是在開發和交付階段,我們必須克服一些挑戰甚至“陷阱”。
1.新技術
在項目開始時,只有兩個人曾經使用過云服務和無服務器。
我們組織了許多培訓課程。要使新技術的應用在項目中獲得成功,就需要說服團隊成員使用它。
理想情況下,你可以讓他們看到這些新技術的好處,讓他們對這些好處感到興奮。
2.調試
分布式應用程序意味著你更依賴日志跟蹤來查找問題根源。
你可以下載 Azure 函數 CLI,這是一個幫助你在開發階段調試 Azure 函數的工具。為調試云上的 Azure 函數,你必須安裝遠程調試,這也不容易。
3.集成
如上所述,我們需要實現新的 Azure 函數——與遺留系統并行的無服務器。因此,新的 Azure 函數與現有函數的集成存在很多問題。
4.測試
使用無服務器時測試非常困難,因為使用無服務器意味著你無法直接訪問執行代碼的環境。
請記住,單元測試必須完整而審慎地編寫。
5.監控
無服務器允許將應用程序分解為更小的模塊。但這可能會導致分布式監控的新問題。
通過將一組無服務器組件鏈接在一起,端到端跟蹤請求 / 響應的能力變得非常重要,但是與遺留監控工具一起使用會非常麻煩。
雖然 Azure 應用程序洞察可以幫助我們監控 Azure 函數,但是熟悉度量標準并不容易。
8. 小結
從單一服務器遷移到無服務器很不容易。它需要大量投資和管理層的參與。最重要的是,實際負責開發的團隊需要具備難以置信的紀律和技能。
不過,這樣做的好處很多。
通常,從小事做起是一個好主意。與其等待一個大的一次性動作,不如試著采取漸進步驟,從錯誤中學習、迭代、再試一次。另外,不要一開始就追求完美的設計。相反,你應該愿意進行迭代和改進。
最后請記住,無服務器不是一個目的地,而是一個旅程,一個持續改進的旅程。
英文原文:
https://hackernoon.com/migration-on-premises-application-to-serverless-72w32ju