閱讀595 返回首頁    go 阿裏雲 go 技術社區[雲棲]


對Serverless架構的一點體驗和思考

發端

雲計算機經過這麼多年的發展,逐漸進化到用戶僅需關注業務和所需的資源。通過Swarm、K8S這些編排工具,容器服務讓開發者的體驗達到很完美的境界。我曾經覺得Docker可以替代虛機,用戶隻要關注自己的計算和需要的資源就行,不需要操心到機器這一層。但是因為Docker對資源的隔離不夠好,各大雲廠商的做法還是一個Docker對應一台虛機,不僅成本高,給用戶暴露虛機也多餘了。

用戶為什麼需要關注業務運行所需要的CPU、內存、網絡情況?還有沒有更好的解決方案?Serverless架構應運而生,讓人們不再操心運行所需的資源,隻需關注自己的業務邏輯,並且為實際消耗的資源付費。可以說,隨著Serverless架構的興起,真正的雲計算時代才算到來了。

容器在開發模式方麵並沒有提出新的想法,大家還是在用傳統的那一套開發模式,需要寫一個大而全的後端服務。與之對比,Serverless架構是事件驅動的,這樣讓後端的開發體驗變得跟前端和移動端很類似了。針對不同客戶的需求,先讓其購買好相關的資源,然後一個個填坑,給不同的產品添加各種事件處理邏輯就行。這就跟iOS開發一樣,界麵寫出來,然後處理一個個事件就好了,大家都很容易理解這種開發模式。

image.png

AWS Lambda體驗

AWS在2014年11月的re:Invent大會上推出Lambda,經過將近三年的發展,已經達到了非常完善的程度。Lambda主要有三個作用。

  1. 跟API Gateway結合起來,方便快捷地提供API服務。
  2. 串聯關鍵產品,比如在DDB插入一條新數據之後,觸發Lambda執行,讀取新記錄送給搜索引擎建索引。
  3. 擴展功能,比如Cognito User Pool提供非常多的點,方便用戶在登錄的時候增加自己的處理邏輯。 image.png

AWS Lambda支持多種語言開發,比如C#、Java、Node.js和Python,擁有廣泛的群眾基礎。

AWS Lambda在除北京之外的所有region均可用。AWS中國支持的產品可以參考:地區表

image.png

Serverless Reference Architecture: Mobile Backend是一個非常好的實例,講述了如果通過Serverless架構實現一個App。

這個App的主要功能類似Evernote,支持上傳圖片,編寫和上傳文章。功能非常簡單,但是涉及到的產品非常多,玩法也非常老練。

1 2 3
image.png image.png image.png

整個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。

image.png

配置

CloudFormation真的很方便,template上傳之後,相關的資源就創建和設置好了。cloudformation目錄下有兩個template文件,隻需上傳mobile-backend.template,它會把config-helper.template加載好。阿裏雲對應的產品是:資源編排ROS

image.png

看起來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相關的配置。這樣並不會影響體驗。

image.png

image.png

CloudFormation有一個資源創建失敗後,會rollback。它把資源的創建當做一個事務來處理,全部成功才行。

image.png

客戶端使用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抓包,發現服務器端給了錯誤提示。

image.png

需要在Usage Plans裏麵Add API Stage裏麵操作一下,API和Stage對上就好了。文章中沒有提到這個配置。

image.png

一些技術細節

App直接麵對API Gateway和S3,要先從Cognito Identity Pool獲取到一個id(Unauthenticated),這個Pool對應MobileClientRole角色,可以看一下這個角色的具體配置,主要是針對S3和API Gateway相關action的allow 。

image.png

image.png

/notes的post接口交給NotesApiFunction Lambda來處理,在控製台可以看得很清楚。

image.png

DDB變動會觸發執行DynamoStreamHandlerFunction這個Lambda,從配置裏麵也可以很清楚看到這個trigger。

image.png

效果

S3裏麵可以看到圖片。

image.png

Dynamo DB裏麵可以看到Post數據。

image.png

但是CloudSearch裏麵Searchable Documents卻一直都是0。

image.png

可以看看DynamoStreamHandlerFunction這個Lambda的數據,發現調用都失敗了。

image.png

去CloudWatch裏麵看看。提示TypeError: Cannot read property 'S' of undefined

image.png

對著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~

image.png

image.png

費用

Lambda根據使用內存和調用次數收費。內存最低是128MB。具體信息請參看:Lambda 定價詳情

image.png

image.png

這個App使勁玩,花不了幾塊錢的。Lambda累計運行了240秒,沒有花錢,主要是S3和數據傳輸花了點錢。

image.png

image.png

Serverless成功的關鍵

擁有豐富的產品,並且打通所有的雲產品,是Serverless成功的前提條件。Lambda不適合處理複雜的業務邏輯,比較適合作為膠水代碼,粘合關鍵的產品。另外就是Lambda不管怎麼完善,可能隻能解決80%的問題,剩下20%的邏輯需要用戶自己寫服務,通過docker發布,然後給Lambda或者用戶使用。這種混合的編碼方式可能是未來的主流開發模式。

image.png

Serverless的主要優點

  1. 開發者更加專注於業務邏輯,開發效率更高。開發一個典型的服務器端項目,需要花很多時間處理依賴、線程、日誌、發布和使用服務、部署及維護等相關的工作,基於Serverless架構則不需要操心這些工作。
  2. 用戶為實際使用的資源付費。用戶購買的ECS使用時間一般不到5成,但是為另外5成閑置時間付費了。Lambda按照運行的時間收費,成本會低很多。
  3. NO Architecture,NO Ops。架構師的責任是設計一個高可用、高擴展的架構。運維負責整個係統穩定可靠地運行,適當縮減和增加資源。大型雲廠商能保證產品的高可用,Serverless架構本身就是高擴展的。Serverless不再需要服務器端的工作人員,給客戶節省了大量的資源。架構師和運維的同學應該好好思考一下未來的出路了。架構師可以轉型去做銷售,整理用戶的需求,然後寫寫CloudFormation的template就好了。
  4. 還是成本。IT行業一些領先的公司基礎設施非常完善,開發工程師寫好代碼,然後通過發布平台發布,感覺也是挺方便的。比起Serverless的架構,成本還是要高不少。
    1. 機器成本。日常、預發、線上,1+1+2=4台服務器少不了。
    2. 時刻要關注業務數據,盤點資源,看看是否需要擴容和縮減資源。擴容容易,縮減難,造成大量資源閑置。
    3. 全鏈路壓測是不是很煩?

Serverless的主要缺點

  1. 排查問題困難,因為邏輯散落在各處,一個操作可能觸發成百上千個Lambda執行。AWS的X-Ray和CloudWatch等產品可以幫助用戶排查問題。
    image.png

  2. 準備runtime需要時間,流量瞬間爆發容易導致超時。

  3. 帶狀態的Lambda寫起來很困難。

  4. Lambda運行有諸多資源限製,比如運行時長、內存、磁盤、打開的文件數量等。
    image.png

  5. 廠商鎖定。雲計算是贏者通吃的行業,大而全的雲廠商優勢巨大,Serverless加劇了這種趨勢。以前用戶還需要自己寫很多服務器端的邏輯,遷移的時候,把服務器端代碼重新部署一下。采用Serverless架構之後,代碼都是各個平台的Lambda代碼片段,沒法遷移。從客戶的角度來看,是不希望自己被某家雲廠商所綁架的。所以雲計算需要有一個標準,產品需要標準化,方便用戶無縫在各種雲之間遷移。

阿裏雲對Serverless的支持情況

阿裏雲在今年四月份南京雲棲大會上推出了自己的Serverless產品:函數計算,目前隻支持API Gateway和OSS,並且隻能在華東2區域使用。還沒有形成體係,很難滿足用戶多樣的需求。

推廣Serverless不是一件容易的事情,一是現有產品上雲要接入的東西有點多,比如售賣、權限、風控、服務等級等,未來還需要接入Serverless。開發團隊很累。第二個是,現有大量的產品要一個個去推動做改造,不是一件容易的事情。

不過阿裏雲也在很努力完善對Serverless的支持,未來可期。函數計算攜手API網關輕鬆實踐Serverless架構

image.png

雲棲社區有一些相關的文章:阿裏雲 Serverless Computing,講得非常好,可以了解一下。

MBaaS/MPaaS為什麼不賺錢?

移動開發領域最早有一些廠商提供移動推送、Crash收集分析、移動數據分析等基礎服務,也就是MPaaS。然後逐漸有一些廠商開始提供數據庫、存儲、配置等相關的服務,在Web控製台上操作,移動端直接使用這些服務,不需要經過服務器端中轉,這就是MBaaS。

目前移動開發領域的服務提供商,比如Facebook的Parse(已關閉)、Firebase(已被Google收購,現在很強大)、國內的LeanCloud都發展得不好。我覺得主要還是因為產品線不夠豐富,隻能滿足一些小App或者App發展初期的需要。MBaaS/MPaaS依托主流雲廠商豐富的產品線,通過類似Lambda機製將這些產品串聯起來,應該會有不錯的發展。

參考資料

  1. 十年生聚,十年教訓——我眼中的雲計算
  2. Liming的動態
  3. 夏日清風 - 基於Docker Swarm的極簡Serverless實踐
  4. InfoQ虛擬研討會:無服務器計算的實踐方法
  5. 誘人卻非萬能,理性看待Serverless的落地
  6. 對AWS Cognito的一些理解

最後更新:2017-08-13 22:33:35

  上一篇:go  阿裏雲前端周刊 - 第 18 期
  下一篇:go  Jetson TX2 初體驗