對Serverless架構的一點體驗和思考
發端
雲端計算機經過這麼多年的發展,逐漸進化到使用者僅需關注業務和所需的資源。通過Swarm、K8S這些編排工具,容器服務讓開發者的體驗達到很完美的境界。我曾經覺得Docker可以替代虛機,使用者只要關注自己的計算和需要的資源就行,不需要操心到機器這一層。但是因為Docker對資源的隔離不夠好,各大雲廠商的做法還是一個Docker對應一臺虛機,不僅成本高,給使用者暴露虛機也多餘了。
使用者為什麼需要關注業務執行所需要的CPU、記憶體、網路情況?還有沒有更好的解決方案?Serverless架構應運而生,讓人們不再操心執行所需的資源,只需關注自己的業務邏輯,並且為實際消耗的資源付費。可以說,隨著Serverless架構的興起,真正的雲端計算時代才算到來了。
容器在開發模式方面並沒有提出新的想法,大家還是在用傳統的那一套開發模式,需要寫一個大而全的後端服務。與之對比,Serverless架構是事件驅動的,這樣讓後端的開發體驗變得跟前端和移動端很類似了。針對不同客戶的需求,先讓其購買好相關的資源,然後一個個填坑,給不同的產品新增各種事件處理邏輯就行。這就跟iOS開發一樣,介面寫出來,然後處理一個個事件就好了,大家都很容易理解這種開發模式。
AWS Lambda體驗
AWS在2014年11月的re:Invent大會上推出Lambda,經過將近三年的發展,已經達到了非常完善的程度。Lambda主要有三個作用。
- 跟API Gateway結合起來,方便快捷地提供API服務。
- 串聯關鍵產品,比如在DDB插入一條新資料之後,觸發Lambda執行,讀取新記錄送給搜尋引擎建索引。
- 擴充套件功能,比如Cognito User Pool提供非常多的點,方便使用者在登入的時候增加自己的處理邏輯。
AWS Lambda支援多種語言開發,比如C#、Java、Node.js和Python,擁有廣泛的群眾基礎。
AWS Lambda在除北京之外的所有region均可用。AWS中國支援的產品可以參考:地區表。
Serverless Reference Architecture: Mobile Backend是一個非常好的例項,講述瞭如果通過Serverless架構實現一個App。
這個App的主要功能類似Evernote,支援上傳圖片,編寫和上傳文章。功能非常簡單,但是涉及到的產品非常多,玩法也非常老練。
1 | 2 | 3 |
---|---|---|
整個demo用到的雲產品和它們相互之間的關係如下圖所示。除了Lambda本身,IAM、API Gateway等產品也發揮了巨大的作用。
$ tree cloudformation lambda-functions
cloudformation
├── config-helper.template
├── mobile-backend-no-cloudfront.template //去除CloudFront相關配置的template檔案。在CloudFormation控制檯上傳該檔案。
└── mobile-backend.template //如果CloudFront可用的話,上傳這個template檔案也OK。
lambda-functions //Lambda程式碼已經壓縮好並放到一個公共的S3 bucket裡面,所以不用管這些程式碼。
├── search
│ └── index.js //CloudSearch搜尋介面的程式碼
├── stream-handler
│ └── index.js //DDB觸發建索引的程式碼
└── upload-note
└── index.js //新增文章介面的程式碼,主要是寫DDB。
配置
CloudFormation真的很方便,template上傳之後,相關的資源就建立和設定好了。cloudformation目錄下有兩個template檔案,只需上傳mobile-backend.template
,它會把config-helper.template
載入好。阿里雲對應的產品是:資源編排ROS。
看起來API Gateway、Cognito、CloudSearch這幾款個產品對CloudFormation支援的並不好,所以還需要通過文章中那麼多命令列和Web控制檯上的設定。
為了能執行這些命令,要把AWS CLI配置好,region設定為us-east-1(弗吉尼亞北部)
,因為文章中存放Lambda程式碼壓縮包的S3也是在us-east-1區域的。
$ aws configure
AWS Access Key ID [****************X3CA]:
AWS Secret Access Key [****************Qo3J]:
Default region name [us-east-1]:
$ cat ~/.aws/config
[default]
region = us-east-1
配置裡面的一些坑
一個坑是CloudFront可能沒有初始化好,導致CloudFormation建立失敗。懶得去配置了,所以我乾脆刪除了CloudFormation裡面CloudFront相關的配置。這樣並不會影響體驗。
CloudFormation有一個資源建立失敗後,會rollback。它把資源的建立當做一個事務來處理,全部成功才行。
客戶端使用Swift 2.3寫的。因為程式碼也比較簡單,所以Convert到3.0就行。後面接著會報Ambiguous use of `continue`
錯誤,類似下面這樣的程式碼使用一對小括號括住block就行。
let noteApiClient = APINotesApiClient(forKey: "USEast1NoteAPIManagerClient")
noteApiClient?.notesPost(noteRequest).continue ({ (task) -> AnyObject! in
if let error = task?.error {
print("Failed creating note: [(error)]")
}
if let exception = task?.exception {
print("Failed creating note: [(exception)]")
}
if let noteResponse = task?.result as? APICreateNoteResponse {
if((noteResponse.success) != nil) {
print("Saved note successfully")
}else {
print("Unable to save note due to unknown error")
}
}
return task
})
程式執行起來之後,Upload Image到S3沒有問題。但是上傳文章的時候會報forbidden的錯誤。Xcode裡面會列印下面這個錯誤。通過Charles抓包,發現伺服器端給了錯誤提示。
需要在Usage Plans
裡面Add API Stage
裡面操作一下,API和Stage對上就好了。文章中沒有提到這個配置。
一些技術細節
App直接面對API Gateway和S3,要先從Cognito Identity Pool獲取到一個id(Unauthenticated),這個Pool對應MobileClientRole
角色,可以看一下這個角色的具體配置,主要是針對S3和API Gateway相關action的allow 。這裡直接使用了API Gateway生成的SDK,結合Cognito Identity Pool用著也挺方便。API Gateway也支援使用Cognito UserPool做驗證器,不需要SDK,用起來更加方便一些,詳細資訊可以參看:[對AWS Cognito的一些理解
](http://www.jianshu.com/p/112438fb86aa)。
/notes
的post介面交給NotesApiFunction
Lambda來處理,在控制檯可以看得很清楚。
DDB變動會觸發執行DynamoStreamHandlerFunction
這個Lambda,從配置裡面也可以很清楚看到這個trigger。
效果
S3裡面可以看到圖片。
Dynamo DB裡面可以看到Post資料。
但是CloudSearch裡面Searchable Documents
卻一直都是0。
可以看看DynamoStreamHandlerFunction
這個Lambda的資料,發現呼叫都失敗了。
去CloudWatch裡面看看。提示TypeError: Cannot read property `S` of undefined
。
對著stream-handler/index.js
看了一下,發現拿到Dynamo DB的資料之後,要通過.S
將其轉型為字串型別。再對著文件看看,其實是沒有毛病的,所以這個問題還不知道怎麼解決。
function createSearchDocuments(records) {
var searchDocuments = [];
for(var i = 0; i<records.length; i++) {
var record = records[i];
if (record.eventName === "INSERT") {
var searchDocument = {
type : `add`,
id : record.dynamodb.Keys.noteId.S,
fields : {
headline : record.dynamodb.NewImage.headline.S,
note_text : record.dynamodb.NewImage.text.S
}
};
searchDocuments.push(searchDocument);
}
}
return searchDocuments;
}
這個問題突然就消失了,建索引和檢索功能都正常了,amazing~
費用
Lambda根據使用記憶體和呼叫次數收費。記憶體最低是128MB。具體資訊請參看:Lambda 定價詳情。
這個App使勁玩,花不了幾塊錢的。Lambda累計執行了240秒,沒有花錢,主要是S3和資料傳輸花了點錢。
Serverless成功的關鍵
擁有豐富的產品,並且打通所有的雲產品,是Serverless成功的前提條件。Lambda不適合處理複雜的業務邏輯,比較適合作為膠水程式碼,粘合關鍵的產品。另外就是Lambda不管怎麼完善,可能只能解決80%的問題,剩下20%的邏輯需要使用者自己寫服務,通過docker釋出,然後給Lambda或者使用者使用。這種混合的編碼方式可能是未來的主流開發模式。
Serverless的主要優點
- 開發者更加專注於業務邏輯,開發效率更高。開發一個典型的伺服器端專案,需要花很多時間處理依賴、執行緒、日誌、釋出和使用服務、部署及維護等相關的工作,基於Serverless架構則不需要操心這些工作。
- 使用者為實際使用的資源付費。使用者購買的ECS使用時間一般不到5成,但是為另外5成閒置時間付費了。Lambda按照執行的時間收費,成本會低很多。
- NO Architecture,NO Ops。架構師的責任是設計一個高可用、高擴充套件的架構。運維負責整個系統穩定可靠地執行,適當縮減和增加資源。大型雲廠商能保證產品的高可用,Serverless架構本身就是高擴充套件的。Serverless不再需要伺服器端的工作人員,給客戶節省了大量的資源。架構師和運維的同學應該好好思考一下未來的出路了。架構師可以轉型去做銷售,整理使用者的需求,然後寫寫CloudFormation的template就好了。
-
還是成本。IT行業一些領先的公司基礎設施非常完善,開發工程師寫好程式碼,然後通過釋出平臺釋出,感覺也是挺方便的。比起Serverless的架構,成本還是要高不少。
- 機器成本。日常、預發、線上,1+1+2=4臺伺服器少不了。
- 時刻要關注業務資料,盤點資源,看看是否需要擴容和縮減資源。擴容容易,縮減難,造成大量資源閒置。
- 全鏈路壓測是不是很煩?
Serverless的主要缺點
- 排查問題困難,因為邏輯散落在各處,一個操作可能觸發成百上千個Lambda執行。AWS的X-Ray和CloudWatch等產品可以幫助使用者排查問題。
- 準備runtime需要時間,流量瞬間爆發容易導致超時。
- 帶狀態的Lambda寫起來很困難。
- Lambda執行有諸多資源限制,比如執行時長、記憶體、磁碟、開啟的檔案數量等。
- 廠商鎖定。雲端計算是贏者通吃的行業,大而全的雲廠商優勢巨大,Serverless加劇了這種趨勢。以前使用者還需要自己寫很多伺服器端的邏輯,遷移的時候,把伺服器端程式碼重新部署一下。採用Serverless架構之後,程式碼都是各個平臺的Lambda程式碼片段,沒法遷移。從客戶的角度來看,是不希望自己被某家雲廠商所綁架的。所以雲端計算需要有一個標準,產品需要標準化,方便使用者無縫在各種雲之間遷移。
阿里雲對Serverless的支援情況
阿里雲在今年四月份南京雲棲大會上推出了自己的Serverless產品:函式計算,目前只支援API Gateway和OSS,並且只能在華東2區域使用。還沒有形成體系,很難滿足使用者多樣的需求。
推廣Serverless不是一件容易的事情,一是現有產品上雲要接入的東西有點多,比如售賣、許可權、風控、服務等級等,未來還需要接入Serverless。開發團隊很累。第二個是,現有大量的產品要一個個去推動做改造,不是一件容易的事情。
不過阿里雲也在很努力完善對Serverless的支援,未來可期。函式計算攜手API閘道器輕鬆實踐Serverless架構
雲棲社群有一些相關的文章:阿里雲 Serverless Computing,講得非常好,可以瞭解一下。
MBaaS/MPaaS為什麼不賺錢?
移動開發領域最早有一些廠商提供移動推送、Crash收集分析、移動資料分析等基礎服務,也就是MPaaS。然後逐漸有一些廠商開始提供資料庫、儲存、配置等相關的服務,在Web控制檯上操作,移動端直接使用這些服務,不需要經過伺服器端中轉,這就是MBaaS。
目前移動開發領域的服務提供商,比如Facebook的Parse(已關閉)、Firebase(已被Google收購,現在很強大)、國內的LeanCloud都發展得不好。我覺得主要還是因為產品線不夠豐富,只能滿足一些小App或者App發展初期的需要。MBaaS/MPaaS依託主流雲廠商豐富的產品線,通過類似Lambda機制將這些產品串聯起來,應該會有不錯的發展。
參考資料
- 十年生聚,十年教訓——我眼中的雲端計算
- Liming的動態
- 夏日清風 – 基於Docker Swarm的極簡Serverless實踐
- InfoQ虛擬研討會:無伺服器計算的實踐方法
- 誘人卻非萬能,理性看待Serverless的落地
- 對AWS Cognito的一些理解
相關文章
- 我對軟體架構的一些看法和思考架構
- 關於 Serverless 應用架構對企業價值的一些思考Server應用架構
- html與css架構的一點體驗HTMLCSS架構
- Serverless架構的優缺點Server架構
- 對.net系統架構改造的一點經驗和教訓架構
- 關於軟體架構和業務架構的思考架構
- 關於構建自己的知識體系架構的一點個人思考架構
- 流批一體架構在快手的實踐和思考架構
- 我對雲原生軟體架構的觀察與思考架構
- 一名一線開發對於App架構和元件化的思考APP架構元件化
- 架構之:serverless架構架構Server
- 對App應用架構搭建的一些思考APP應用架構
- 對程式碼命名的一點思考和理解
- 我對移動端架構的思考架構
- 移動端架構的幾點思考架構
- 對一邊旅行一邊程式設計的生活方式的體驗和思考程式設計
- 再聊對架構決策記錄的一些思考架構
- Serverless 架構的演進Server架構
- 我對人生的一點思考
- 從單體架構到分散式微服務架構的思考架構分散式微服務
- 關於語義化 HTML 以及前端架構的一點思考HTML前端架構
- Android 開發軟體架構思考以及經驗總結Android架構
- 成為架構師的7個關鍵思考、習慣和經驗架構
- 對專案管理的一點思考專案管理
- 從零入門 Serverless | 一文詳解 Serverless 架構模式Server架構模式
- Serverless 架構開發手冊 — “人人都是 Serverless 架構師”先導篇Server架構
- 軟體架構:問題起源和應對架構
- 經驗篇:對商業分析的一些思考和感悟
- 索引表和 ES 的一點點思考索引
- 對快取擊穿的一點思考快取
- 一個開放平臺架構的思考架構
- 架構師備考的一些思考架構
- 對CQRS架構的幾點疑問架構
- UNIX安全構架的九點經驗(轉)
- 基於 Serverless 的部署平臺構建與思考Server
- 花了1000G,終於弄清楚了Serverless (中):Serverless 架構的優缺點Server架構
- Serverless Devs 重大更新,基於 Serverless 架構的 CI/CD 框架:Serverless-cdServerdev架構框架
- Serverless 架構模式及演進Server架構模式