對Serverless架構(gòu)的一點(diǎn)體驗(yàn)和思考

發(fā)端

云計(jì)算機(jī)經(jīng)過這么多年的發(fā)展,逐漸進(jìn)化到用戶僅需關(guān)注業(yè)務(wù)和所需的資源。通過Swarm、K8S這些編排工具,容器服務(wù)讓開發(fā)者的體驗(yàn)達(dá)到很完美的境界。我曾經(jīng)覺得Docker可以替代虛機(jī),用戶只要關(guān)注自己的計(jì)算和需要的資源就行,不需要操心到機(jī)器這一層。但是因?yàn)镈ocker對資源的隔離不夠好,各大云廠商的做法還是一個Docker對應(yīng)一臺虛機(jī),不僅成本高,給用戶暴露虛機(jī)也多余了。

用戶為什么需要關(guān)注業(yè)務(wù)運(yùn)行所需要的CPU、內(nèi)存、網(wǎng)絡(luò)情況?還有沒有更好的解決方案?Serverless架構(gòu)應(yīng)運(yùn)而生,讓人們不再操心運(yùn)行所需的資源,只需關(guān)注自己的業(yè)務(wù)邏輯,并且為實(shí)際消耗的資源付費(fèi)??梢哉f,隨著Serverless架構(gòu)的興起,真正的云計(jì)算時代才算到來了。

容器在開發(fā)模式方面并沒有提出新的想法,大家還是在用傳統(tǒng)的那一套開發(fā)模式,需要寫一個大而全的后端服務(wù)。與之對比,Serverless架構(gòu)是事件驅(qū)動的,這樣讓后端的開發(fā)體驗(yàn)變得跟前端和移動端很類似了。針對不同客戶的需求,先讓其購買好相關(guān)的資源,然后一個個填坑,給不同的產(chǎn)品添加各種事件處理邏輯就行。這就跟iOS開發(fā)一樣,界面寫出來,然后處理一個個事件就好了,大家都很容易理解這種開發(fā)模式。

image.png

AWS Lambda體驗(yàn)

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

  1. 跟API Gateway結(jié)合起來,方便快捷地提供API服務(wù)。
  2. 串聯(lián)關(guān)鍵產(chǎn)品,比如在DDB插入一條新數(shù)據(jù)之后,觸發(fā)Lambda執(zhí)行,讀取新記錄送給搜索引擎建索引。
  3. 擴(kuò)展功能,比如Cognito User Pool提供非常多的點(diǎn),方便用戶在登錄的時候增加自己的處理邏輯。


    image.png

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

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

image.png

Serverless Reference Architecture: Mobile Backend是一個非常好的實(shí)例,講述了如何通過Serverless架構(gòu)實(shí)現(xiàn)一個App。

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

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

整個demo用到的云產(chǎn)品和它們相互之間的關(guān)系如下圖所示。除了Lambda本身,IAM、API Gateway等產(chǎn)品也發(fā)揮了巨大的作用。

$ tree cloudformation lambda-functions 
cloudformation
├── config-helper.template
├── mobile-backend-no-cloudfront.template //去除CloudFront相關(guān)配置的template文件。在CloudFormation控制臺上傳該文件。
└── mobile-backend.template //如果CloudFront可用的話,上傳這個template文件也OK。
lambda-functions //Lambda代碼已經(jīng)壓縮好并放到一個公共的S3 bucket里面,所以不用管這些代碼。
├── search
│   └── index.js //CloudSearch搜索接口的代碼
├── stream-handler
│   └── index.js //DDB觸發(fā)建索引的代碼
└── upload-note
    └── index.js //新增文章接口的代碼,主要是寫DDB。
image.png

配置

CloudFormation真的很方便,template上傳之后,相關(guān)的資源就創(chuàng)建和設(shè)置好了。cloudformation目錄下有兩個template文件,只需上傳mobile-backend.template,它會把config-helper.template加載好。阿里云對應(yīng)的產(chǎn)品是:資源編排ROS。

image.png

看起來API Gateway、Cognito、CloudSearch這幾款個產(chǎn)品對CloudFormation支持的并不好,所以還需要通過文章中那么多命令行和Web控制臺上的設(shè)置。

為了能運(yùn)行這些命令,要把AWS CLI配置好,region設(shè)置為us-east-1(弗吉尼亞北部),因?yàn)槲恼轮写娣臠ambda代碼壓縮包的S3也是在us-east-1區(qū)域的。

$ 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可能沒有初始化好,導(dǎo)致CloudFormation創(chuàng)建失敗。懶得去配置了,所以我干脆刪除了CloudFormation里面CloudFront相關(guān)的配置。這樣并不會影響體驗(yàn)。

image.png
image.png

CloudFormation有一個資源創(chuàng)建失敗后,會rollback。它把資源的創(chuàng)建當(dāng)做一個事務(wù)來處理,全部成功才行。

image.png

客戶端使用Swift 2.3寫的。因?yàn)榇a也比較簡單,所以Convert到3.0就行。后面接著會報(bào)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
})

程序運(yùn)行起來之后,Upload Image到S3沒有問題。但是上傳文章的時候會報(bào)forbidden的錯誤。Xcode里面會打印下面這個錯誤。通過Charles抓包,發(fā)現(xiàn)服務(wù)器端給了錯誤提示。

image.png

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

image.png
一些技術(shù)細(xì)節(jié)

App直接面對API Gateway和S3,要先從Cognito Identity Pool獲取到一個id(Unauthenticated),這個Pool對應(yīng)MobileClientRole角色,可以看一下這個角色的具體配置,主要是針對S3和API Gateway相關(guān)action的allow 。這里直接使用了API Gateway生成的SDK,結(jié)合Cognito Identity Pool用著也挺方便。API Gateway也支持使用Cognito UserPool做驗(yàn)證器,不需要SDK,用起來更加簡單一些,詳細(xì)信息可以參看:對AWS Cognito的一些理解
。

image.png
image.png

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

image.png

DDB變動會觸發(fā)執(zhí)行DynamoStreamHandlerFunction這個Lambda,從配置里面也可以很清楚看到這個trigger。

image.png

效果

S3里面可以看到圖片。

image.png

Dynamo DB里面可以看到Post數(shù)據(jù)。

image.png

但是CloudSearch里面Searchable Documents卻一直都是0。

image.png

可以看看DynamoStreamHandlerFunction這個Lambda的數(shù)據(jù),發(fā)現(xiàn)調(diào)用都失敗了。

image.png

去CloudWatch里面看看。提示TypeError: Cannot read property 'S' of undefined。

image.png

對著stream-handler/index.js看了一下,發(fā)現(xiàn)拿到Dynamo DB的數(shù)據(jù)之后,要通過.S將其轉(zhuǎn)型為字符串類型。再對著文檔看看,其實(shí)是沒有毛病的,所以這個問題還不知道怎么解決。

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

費(fèi)用

Lambda根據(jù)使用內(nèi)存和調(diào)用次數(shù)收費(fèi)。內(nèi)存最低是128MB。具體信息請參看:Lambda 定價詳情。

image.png
image.png

這個App使勁玩,花不了幾塊錢的。Lambda累計(jì)運(yùn)行了240秒,沒有花錢,主要是S3和數(shù)據(jù)傳輸花了點(diǎn)錢。

image.png
image.png

Serverless成功的關(guān)鍵

擁有豐富的產(chǎn)品,并且打通所有的云產(chǎn)品,是Serverless成功的前提條件。Lambda不適合處理復(fù)雜的業(yè)務(wù)邏輯,比較適合作為膠水代碼,粘合關(guān)鍵的產(chǎn)品。另外就是Lambda不管怎么完善,可能只能解決80%的問題,剩下20%的邏輯需要用戶自己寫服務(wù),通過docker發(fā)布,然后給Lambda或者用戶使用。這種混合的編碼方式可能是未來的主流開發(fā)模式。

image.png

Serverless的主要優(yōu)點(diǎn)

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

Serverless的主要缺點(diǎn)

  1. 排查問題困難,因?yàn)檫壿嬌⒙湓诟魈?,一個操作可能觸發(fā)成百上千個Lambda執(zhí)行。AWS的X-Ray和CloudWatch等產(chǎn)品可以幫助用戶排查問題。


    image.png
  2. 準(zhǔn)備runtime需要時間,流量瞬間爆發(fā)容易導(dǎo)致超時。

  3. 帶狀態(tài)的Lambda寫起來很困難。

  4. Lambda運(yùn)行有諸多資源限制,比如運(yùn)行時長、內(nèi)存、磁盤、打開的文件數(shù)量等。


    image.png
  5. 廠商鎖定。云計(jì)算是贏者通吃的行業(yè),大而全的云廠商優(yōu)勢巨大,Serverless加劇了這種趨勢。以前用戶還需要自己寫很多服務(wù)器端的邏輯,遷移的時候,把服務(wù)器端代碼重新部署一下。采用Serverless架構(gòu)之后,代碼都是各個平臺的Lambda代碼片段,沒法遷移。從客戶的角度來看,是不希望自己被某家云廠商所綁架的。所以云計(jì)算行業(yè)需要做很多標(biāo)準(zhǔn)化的工作,方便用戶無縫在各種云之間遷移。

阿里云對Serverless的支持情況

阿里云在今年四月份南京云棲大會上推出了自己的Serverless產(chǎn)品:函數(shù)計(jì)算,目前只支持API Gateway和OSS,并且只能在華東2區(qū)域使用。還沒有形成體系,很難滿足用戶多樣的需求。

推廣Serverless不是一件容易的事情,一是現(xiàn)有產(chǎn)品上云要接入的東西有點(diǎn)多,比如售賣、權(quán)限、風(fēng)控、服務(wù)等級等,未來還需要接入Serverless。開發(fā)團(tuán)隊(duì)很累。第二個是,現(xiàn)有大量的產(chǎn)品要一個個去推動做改造,不是一件容易的事情。

不過阿里云也在很努力完善對Serverless的支持,未來可期。函數(shù)計(jì)算攜手API網(wǎng)關(guān)輕松實(shí)踐Serverless架構(gòu)

image.png

云棲社區(qū)有一些相關(guān)的文章:阿里云 Serverless Computing,講得非常好,可以了解一下。

MBaaS/MPaaS為什么不賺錢?

移動開發(fā)領(lǐng)域最早有一些廠商提供移動推送、Crash收集分析、移動數(shù)據(jù)分析等基礎(chǔ)服務(wù),也就是MPaaS。然后逐漸有一些廠商開始提供數(shù)據(jù)庫、存儲、配置等相關(guān)的服務(wù),管理員在Web控制臺上操作,移動端直接使用這些服務(wù),不需要經(jīng)過服務(wù)器端中轉(zhuǎn),這就是MBaaS。

目前移動開發(fā)領(lǐng)域的服務(wù)提供商,比如Facebook的Parse(已關(guān)閉)、Firebase(已被Google收購,現(xiàn)在很強(qiáng)大)、國內(nèi)的LeanCloud都發(fā)展得不好。我覺得主要還是因?yàn)楫a(chǎn)品線不夠豐富,只能滿足一些小App或者App發(fā)展初期的需要。MBaaS/MPaaS依托主流云廠商豐富的產(chǎn)品線,通過類似Lambda機(jī)制將這些產(chǎn)品串聯(lián)起來,應(yīng)該會有不錯的發(fā)展。

參考資料

  1. 十年生聚,十年教訓(xùn)——我眼中的云計(jì)算
  2. Liming的動態(tài)
  3. 夏日清風(fēng) - 基于Docker Swarm的極簡Serverless實(shí)踐
  4. InfoQ虛擬研討會:無服務(wù)器計(jì)算的實(shí)踐方法
  5. 誘人卻非萬能,理性看待Serverless的落地
  6. 對AWS Cognito的一些理解
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容