花了1000G,終於弄清楚了Serverless (中):Serverless 架構的優缺點

Serverless 的優點

在我使用 Serverless Framework 開發 AWS Serverless 應用的過程當中,最方便的莫過於,第一次部署和第二次、第三次部署沒有什麼區別。只須要執行 serverless deploy,幾分鐘後,咱們代碼就運行在線上。若是是一個傳統的 AWS 應用,我須要 SSH 到個人服務器上部署,這樣才能寫好個人自動部署腳本。除此,我還須要擔心這個過程當中,有哪些用戶有使用。前端

除了,我以爲的部署方便,還有就是價格合理。個人 AWS EC2 實例上運行着個人博客、以及其餘的一些網絡。然而,我那 PV 只有 500 左右的博客,大部分時間都是在空轉。便以爲有些浪費,但是運行才收費的 Serverless 就不會有這樣的問題。可讓我大膽地去使用這些服務。固然了,還有其它一些顯著的優點。git

下降啓動成本

當咱們做爲一家公司開發一個 Web 應用時,在開發的時候,咱們須要版本管理服務器、持續集成服務器、測試服務器、應用版本管理倉庫等做爲基礎的服務。線上運行的時候,爲了應對大量的請求,咱們須要一個好的數據庫服務器。當咱們的應用面向了普通的用戶時,咱們須要:程序員

  • 郵件服務,用於發送提醒、註冊等服務github

  • 短信服務(依國家實名規定),用於註冊、登陸等用戶受權操做數據庫

對於大公司而言,這些都是現成的基礎設施。可對於新創企業來講,這都是一些啓動成本。安全

減小運營成本

對於初創公司來講,他們沒有基礎設施,也沒有財力,也可能沒有能力去建設基礎設施。採用雲服務每每是最好的選擇,能夠節省大量的資金。他們能夠將注意力放在:創造對用戶有價值的產品上。若是一家創業公司採用雲服務,而不是本身搭建服務器。那麼,他就會擁有更多的時間開發業務功能,而不是關注在這些。只須要爲運行時的軟件付錢。服務器

而採用函數計算的 Serverless 與雲服務器最大的不一樣之處在於:雲服務器須要一直運行,而函數計算是按需計算。按需計算就意味着,在請求到來的時候,才運行函數。沒有請求的時候,是不算錢的。網絡

項目初期,其用戶數每每是緩慢增加的,而咱們在選擇服務器的時候,每每會依可能出現的用戶來估算。在這個時候,每每會浪費一些沒必要要的成本。不過,就算用戶忽然間爆發,Serverless 應用也能夠輕鬆處理。只須要修改一下數據庫配置,再從新部署一份。架構

下降開發成本

一個成功的 Serverless 服務供應商,應該能提供一系列的配套服務。這意味着,你只須要在配置文件上寫下,這個數據庫的表名,那麼咱們的數據就會存儲到對應的數據庫裏。甚至於,**若是一個當服務提供者提供一系列的函數計算模板,那麼咱們只須要寫好咱們的配置便可。這一系列的東西均可以自動、高效的完成。框架

在這種狀況下,使用某一個雲服務,就會調用某一個系統自帶的 API 同樣簡單

固然,將應用設計成無狀態應用,對於早期的系統,多是一種挑戰。除此,諸如 AWS 這樣龐大的系統,對於新手程序員來講,也不能容易消化掉的一個系統。

實現快速上線

對於一個 Web 項目來講,啓動一個項目須要一系列的 hello, world。當咱們在本地搭建環境的時候,是一個 hello, world,當咱們將程序部署到開發環境時,也是一個部署相關的 hello, world。雖然看上去有些不一樣,可是總的來講,都是 it works!。

Serverless 在部署上的優點,使得你能夠輕鬆地實現上線。

更快的部署流水線

實際上,Serverless 應用之因此在部署上有優點,是由於其至關於內建自動化部署——咱們在開發應用的時候,已經在不斷地加強部署功能。

在咱們平常的開發中,爲了實現自動化部署,咱們須要先手動部署,以設計出一個相關無錯的部署配置,如 Docker 的 Dockerfile,又或者是 Ansible 的 playbook。除此,咱們還須要設計好藍綠髮布等等的功能。

而在函數計算、Serverless 應用裏,這些都是由供應商提供的功能。每次咱們寫完代碼,只須要運行一下:sls deploy 就足夠了。在諸如 AWS Lambda 的函數計算裏,函數通常在上傳後幾秒鐘內,就能作好調用準備。

這就意味着,當咱們和平常同樣,使用一個模板來開發咱們的應用。咱們就能夠在 Clone 完代碼後的幾分鐘內,完成第一次部署。

惟一的難點,多是要選用什麼配置類型的服務,如選用哪一個級別吞吐量的 DynamoDB、哪一個內存大小的 Lambda 計算。

更快的開發速度

因爲 Serverless 服務提供者,已經準備好了一系列的基礎服務。做爲開發人員的咱們,只須要關注於如何更好去實現業務,而非技術上的一些限制。

服務提供者已經向咱們準備,並測試好了這一系列的服務。它們基本上是穩定、可靠的,不會趕上特別大的問題。事實上,當咱們擁有足夠強大的代碼,如使用測試來保證健壯性,那麼結合持續集成,咱們就能夠在 PUSH 代碼的時候,直接部署到生產環境。固然,可能不須要這麼麻煩,咱們只須要添加一個 predeploy 的 hook,在這個 hook 裏作一些自動測試的工做,就能夠在本地直接發佈新的版本。

這個過程裏,咱們並不須要考慮太多的發佈事宜。

系統安全性更高

依我維護我博客的經驗來看,要保持服務器一直運行不是一件容易的事。在不經意的時候,總會發現有 Cracker 在攻擊你網站。咱們須要防範不一樣類型的攻擊,如在個人服務器裏一直有黑客在嘗試密碼登陸,但是個人博客的服務器是要密鑰才能登陸的。在一次神奇的嘗試登陸攻擊後,個人 SSH 守護進程崩潰了。這意味着,我只能從 EC2 後臺重啓服務器。

有了 Serverless,我再也不須要擔憂有人嘗試登陸系統,由於我都不知道怎麼登陸服務器。

我再也不須要考慮系統底層安全問題,每次登陸 AWS EC2,我總須要更新一遍軟件;每當我看到某個軟件有漏洞時,如以前的 OpenSSH,我就登陸上去看一下版本,更新一下軟件。真 TM 費時又費力,尚未一點好處。

惟一須要擔憂的,多是有人發起 DDOS 攻擊。而根據Could Zombie Toasters DDoS My Serverless Deployment?的計算,每百萬的請求,大概是 0.2 刀,每小時 360000000 個請求,也就 72 刀。

適應微服務架構

如咱們所見在最近幾年裏看到的那樣,微服務並不沒有大量地替換掉單體應用——畢竟使用新的架構來替換舊的系統,在業務上的價值並不大。所以,對於不少企業來講,並無這樣的強烈需求及緊迫性。活着,纔是一件更緊迫的事。

而 Serverless 天生就與微服務架構是相輔相成的。一個 Serverless 應用擁有本身的網關、數據庫、接口,你可還以使用本身喜歡的語言(受限於服務提供者)來開發服務。換句話來講,在這種情形下,一個 Serverless 多是一個完美的微服務實例。

在可見的一二年裏,Serverless 將替換到某些系統中的一些組件、服務。

自動擴展能力

Serverless 的背後是 諸如 AWS Lambda 這樣的 FaaS(Function as a Services)。

對於傳統應用來講,要應對更多的請求的方式,就是部署更多的實例。然而,這個時候每每已經來不及了。而對於 FaaS 來講,咱們並不須要這麼作,FaaS 會自動的擴展。它能夠在須要時儘量多地啓動實例副本,而不會發生冗長的部署和配置延遲。

這依賴於咱們的服務是無狀態的,咱們才能次無忌憚地不斷運行起新的實例。

Serverless 的問題

做爲一個運行時,才啓動的應用來講,Serverless 也存在着一個個咱們所須要的問題。

不適合長時間運行應用

Serverless 在請求到來時才運行。這意味着,當應用不運行的時候就會進入 「休眠狀態」,下次當請求來臨時,應用將會須要一個啓動時間,即冷啓動。這個時候,能夠結合 CRON 的方式或者 CloudWatch 來按期喚醒應用。

若是你的應用須要一直長期不間斷的運行、處理大量的請求,那麼你可能就不適合採用 Serverless 架構。在這種狀況下,採用 EC2 這樣的雲服務器每每是一種更好的選擇。由於 EC2 從價格上來講,更加便宜。

引用 Lu Zou 在 《花了 1000G,我終於弄清楚了 Serverless 是什麼(上):什麼是 Serverless 架構?》上的評論:

EC2 至關於你買了一輛車,而 Lambda 至關於你租了你一輛車。

長期租車的成本確定比買車貴,可是你就少掉了一部分的維護成本。所以,這個問題其實是一個值得深刻計算的問題。

徹底依賴於第三方服務

是的,當你決定使用某個雲服務的時候,也就意味着你可能走了一條不歸路。在這種狀況下,只能將不重要的 API 放在 Serverless 上。

當你已經有大量的基礎設施的時候,Serverless 對於你來講,並非一個好東西。當咱們採用 Serverless 架構的時候,咱們就和特別的服務供應商綁定了。咱們使用了 AWS 家的服務,那麼咱們再將服務遷到 Google Cloud 上就沒有那麼容易了。

咱們須要修改一下系列的底層代碼,能採起的應對方案,即是創建隔離層。這意味着,在設計應用的時候,就須要:

  • 隔離 API 網關

  • 隔離數據庫層,考慮到市面上尚未成熟的 ORM 工具,讓你即支持 Firebase,又支持 DynamoDB

  • 等等

這些也將帶給咱們一些額外的成本,可能帶來的問題會比解決的問題多

冷啓動時間

如上所說,Serverless 應用存在一個冷啓動時間的問題。

據 New Relic 官方博客《Understanding AWS Lambda Performance—How Much Do Cold Starts Really Matter?》稱,AWS Lambda 的冷啓動時間。

AWS 啓動時間

又或者是我以前統計的請求響應時間:

Serverless 請求時間

儘管這個冷啓動時間大部分狀況下,能夠在 50ms 之內。而這是對於 Node.js 應用來講,對於擁有虛擬機的 Java 和 C# 可能就沒有那麼幸運了。

缺少調試和開發工具

當我使用 Serverless Framework 的時候,遇到了這樣的問題:缺少調試和開發工具。後來,我發現了 serverless-offline、dynamodb-local 等一系列插件以後,問題有一些改善。

然而,對於日誌系統來講,這仍然是一個艱鉅的挑戰。

每次你調試的時候,你須要一遍又一遍地上傳代碼。而每次上傳的時候,你就好像是在部署服務器。而後 Fuck 了,我並不能老是快速地定位出問題在哪。因而,我修改了一下代碼,添加了一行 console.log,而後又一次地部署了下代碼。問題解決了,挺好的,我刪了一下 console.log,而後又一次地部署了下代碼。

後來,我學乖了,找了一個相似於 log4j 這樣的能夠分級別紀錄日誌的 Node.js 庫 winston。它能夠支持 error、warn、info、verbose、debug、silly 六個不一樣級別的日誌。

構建複雜

Serverless 很便宜,可是這並不意味着它很簡單。

早先,在知道 AWS Lambda 以後,我原本想進行一些嘗試。可是 CloudForamtion 讓我以爲太難了,它的配置是如此的複雜,而且難以閱讀及編寫(JSON 格式)。

考慮到 CloudForamtion 的複雜度,我是在接觸了 Serverless Framework 以後,才從新燃起了一些信心。

Serverless Framework 的配置更加簡單,採用的是 YAML 格式。在部署的時候,Serverless Framework 會根據咱們的配置生成 CloudForamtion 配置。

在那篇《Kinesis Firehose 持久化數據到 S3》想着的數據統計文章裏,咱們介紹了 Serverless 框架的配置。與通常的 Lambda 配置來講,這裏的配置就稍微複雜一些。然而,這也並不是是一個真正用於生產的配置。個人意思是,真實的應用場景遠遠比這複雜。

語言版本落後

在 Node.js 6 出來的時候,AWS Lambda 只支持 Node.js 4.3.2;在 Node.js 9.0 出來的時候,AWS Lambda 支持到 6.10.3。

以下是 AWS Lambda 支持如下運行時版本:

  • Node.js – v4.3.2 和 6.10.3

  • Java - Java 8

  • Python – Python 3.6 和 2.7

  • .NET 內核 – .NET 內核 1.0.1 (C#)

對於 Java 和 Python 來講,他們的版本上可能基本都是夠用的,我不知道 C# 怎麼樣。可是 Node.js 的版本顯然是有點老舊的,可是都 Node.js 9.2.0 了。不過,話說來講,這可能與版本帝 Chrome 帶來的前端版本潮有一點關係。

節選自《Serverless 架構應用開發指南

相關文章
相關標籤/搜索