【知識(shí)點(diǎn)】如何快速開發(fā)、部署 Serverless 應(yīng)用?


點(diǎn)擊上方藍(lán)字關(guān)注我們,免費(fèi)解鎖新書內(nèi)容
文章節(jié)選 | 《Serverless 架構(gòu)下的 AI 應(yīng)用開發(fā)》本文將詳細(xì)介紹如何開發(fā)和部署 Serverless 應(yīng)用,并通過阿里云函數(shù)計(jì)算控制臺(tái)與開發(fā)者工具 Serverless Devs 進(jìn)行應(yīng)用的初始化、部署;最后分享應(yīng)用的調(diào)試,通過科學(xué)發(fā)布、可觀測性等介紹應(yīng)用的部署和運(yùn)維總結(jié),進(jìn)而實(shí)現(xiàn)從應(yīng)用初始化到調(diào)試、發(fā)布、運(yùn)維基礎(chǔ)流程、核心步驟的探索。
01
Serverless應(yīng)用開發(fā)部署
通過控制臺(tái)進(jìn)行函數(shù)創(chuàng)建
阿里云函數(shù)計(jì)算產(chǎn)品首頁
選擇左側(cè)的“服務(wù)及函數(shù)”,并進(jìn)行服務(wù)的創(chuàng)建,如圖所示:
阿里云函數(shù)計(jì)算創(chuàng)建服務(wù)頁面
阿里云函數(shù)計(jì)算創(chuàng)建函數(shù)頁面
相關(guān)聯(lián)的函數(shù)可以放在一個(gè)服務(wù)下進(jìn)行分類,這種分類實(shí)際上比標(biāo)簽分類更直觀明了。 相關(guān)聯(lián)的函數(shù)在同一個(gè)服務(wù)下共享一定的配置,例如 VPC 配置、NAS 配置,甚至某些日志倉庫的配置等。 通過服務(wù),我們可以很好地做函數(shù)環(huán)境的劃分,例如對于一個(gè)相冊項(xiàng)目,該項(xiàng)目可能存在線上環(huán)境、測試環(huán)境、開發(fā)環(huán)境,那么可以在服務(wù)層面做區(qū)分,即可以設(shè)定 album-release、album-test、album-dev 三個(gè)服務(wù),進(jìn)而做環(huán)境的隔離。 通過服務(wù),我們可以很好地收納函數(shù)。如果項(xiàng)目比較大,可能會(huì)產(chǎn)生很多函數(shù),統(tǒng)一放在同一層級(jí)會(huì)顯得非常混亂,這時(shí)就可以通過服務(wù)進(jìn)行有效的收納。


通過工具進(jìn)行函數(shù)創(chuàng)建與部署
通過 Serverless 開發(fā)者工具入門 Serverless 應(yīng)用開發(fā)、部署、運(yùn)維是非常方便的,下面我們以 Serverless Devs 為例介紹阿里云函數(shù)計(jì)算應(yīng)用的部署,并對工具側(cè)的函數(shù)創(chuàng)建、部署以及其他相關(guān)功能進(jìn)行探索。
Serverless Devs 是一個(gè)開源的 Serverless 開發(fā)者平臺(tái),致力于為開發(fā)者提供強(qiáng)大的工具鏈。通過該平臺(tái),開發(fā)者可以一鍵體驗(yàn)多云 Serverless 產(chǎn)品,極速部署 Serverless 項(xiàng)目。按照官方目前的描述,Serverless Devs 已經(jīng)支持包括 AWS Lanbda、阿里云函數(shù)計(jì)算、百度智能云函數(shù)計(jì)算、騰訊云云函數(shù)、華為云函數(shù)工作流等在內(nèi)的多個(gè)云廠商的 Serverless 相關(guān)產(chǎn)品。
我們通過 Serverless Devs 開發(fā)者工具,以阿里云函數(shù)計(jì)算為例進(jìn)行實(shí)踐,探索如何創(chuàng)建、部署 Serverless 應(yīng)用:
1)安裝 Serverless Devs 開發(fā)者工具(執(zhí)行npm install -g @Serverless-devs/s命令)。
2)設(shè)置阿里云憑證信息(執(zhí)行s config add --AccessKeyID AccessKeyID --AccessKeySecret AccessKeySecret --AccountID AccountID命令)。
3)建立模板項(xiàng)目(執(zhí)行s init node.js12-http -d fc-hello-world-demo命令),初始化過程如圖所示:
通過 Serverless Devs 創(chuàng)建項(xiàng)目圖
通過 Serverless Devs 部署項(xiàng)目
通過 Serverless Devs 觸發(fā)函數(shù)
通過 Serverless Devs 查看函數(shù)詳情
通過 Serverless Devs 桌面客戶端查看應(yīng)用列表
通過 Serverless Devs 桌面客戶端管理應(yīng)用
通過 Serverless Devs 桌面客戶端一鍵壓測函數(shù)性能
通過 Serverless Devs 桌面客戶端一鍵對函數(shù)資源進(jìn)行調(diào)試
通過 Serverless Devs 桌面客戶端一鍵查看函數(shù)多維度指標(biāo)信息
通過 Serverless Devs 桌面客戶端進(jìn)行 Yaml 可視化配置02
如何調(diào)試Serverless應(yīng)用
在應(yīng)用開發(fā)過程中,或者應(yīng)用開發(fā)完成后,當(dāng)執(zhí)行結(jié)果不符合預(yù)期時(shí),通常要進(jìn)行一定的調(diào)試。
但是在 Serverless 架構(gòu)下,調(diào)試往往會(huì)受到極大的考驗(yàn),尤其在受環(huán)境因素限制時(shí),通常會(huì)出現(xiàn)這樣的情況:所開發(fā)的應(yīng)用在本地可以健康、符合預(yù)期地運(yùn)行,但是在 FaaS 平臺(tái)上則有一些不可預(yù)測的問題;或者在一些特殊環(huán)境下,本地沒有辦法模擬線上環(huán)境,難以進(jìn)行應(yīng)用的調(diào)試。
雖然 Serverless 應(yīng)用的調(diào)試一直備受詬病,但是各個(gè)云廠商并沒有因此放棄在調(diào)試方向上的深入探索,下面我們介紹幾種方式。
在線調(diào)試
簡單調(diào)試
所謂的簡單調(diào)試,就是在控制臺(tái)進(jìn)行調(diào)試。以阿里云函數(shù)計(jì)算為例,可以在控制臺(tái)通過“代碼執(zhí)行”按鈕進(jìn)行基本的調(diào)試,如下圖所示:
函數(shù)計(jì)算代碼編輯頁面
必要的時(shí)候也可以通過設(shè)置 Event 來模擬一些事件。
阿里云函數(shù)計(jì)算事件頁面
在線調(diào)試的好處是可以使用一些線上環(huán)境進(jìn)行代碼的測試。當(dāng)線上環(huán)境擁有 VPC 等資源時(shí),在本地環(huán)境是很難進(jìn)行調(diào)試的。
斷點(diǎn)調(diào)試
除了簡單的在線調(diào)試之外,部分云廠商還支持?jǐn)帱c(diǎn)調(diào)試,例如阿里云函數(shù)計(jì)算的遠(yuǎn)程調(diào)試。我們以阿里云函數(shù)計(jì)算遠(yuǎn)程調(diào)試為例,可以實(shí)現(xiàn)通過控制臺(tái)進(jìn)行函數(shù)的在線調(diào)試。當(dāng)創(chuàng)建好函數(shù)之后,可以選擇遠(yuǎn)程調(diào)試,并單擊“開啟調(diào)試”按鈕:
函數(shù)計(jì)算遠(yuǎn)程調(diào)試頁面
開啟調(diào)試之后,稍等片刻,系統(tǒng)將會(huì)進(jìn)入遠(yuǎn)程調(diào)試界面:
函數(shù)計(jì)算遠(yuǎn)程調(diào)試開始頁面當(dāng)出現(xiàn)圖
當(dāng)出現(xiàn)下圖所示界面,我們可以進(jìn)行斷點(diǎn)調(diào)試。
函數(shù)計(jì)算遠(yuǎn)程調(diào)試斷點(diǎn)調(diào)試頁面
端云聯(lián)調(diào)
在本地進(jìn)行 Serverless 應(yīng)用開發(fā)時(shí),往往會(huì)涉及一些線上資源,例如通過對象存儲(chǔ)觸發(fā)器觸發(fā)函數(shù)執(zhí)行,通過 VPC 訪問數(shù)據(jù)庫等,此時(shí)線上和線下環(huán)境不一致會(huì)讓線下開發(fā)、調(diào)試面臨極大的挑戰(zhàn)。
Serverless Devs 開發(fā)者工具通過搭建 Proxy 輔助函數(shù)的方法將線上和線下資源打通,可以快速幫助開發(fā)者在本地進(jìn)行應(yīng)用的開發(fā)與調(diào)試,這種調(diào)試方式稱為端云聯(lián)調(diào)。
如下圖所示, Serverless Devs 開發(fā)者工具會(huì)根據(jù) Yaml 配置文件,創(chuàng)建輔助服務(wù)和輔助函數(shù),并通過輔助服務(wù)和輔助函數(shù)實(shí)現(xiàn)線上和線下資源打通,以及完整的端云聯(lián)調(diào)。
Serverless Devs 端云聯(lián)調(diào)原理示意圖
Serverless Devs 開發(fā)者工具會(huì)根據(jù) Yaml 配置文件的內(nèi)容,創(chuàng)建輔助服務(wù)和輔助函數(shù)(輔助服務(wù)和 Yaml 中所聲明的業(yè)務(wù)服務(wù)配置是一致的)。
通過觸發(fā)器(包括通過 SDK、API、s proxied invoke 命令,或者其他觸發(fā)器)觸發(fā)輔助函數(shù)(函數(shù)計(jì)算 C),請求流量回到本地調(diào)試實(shí)例(本地環(huán)境 A),這時(shí)本地調(diào)試實(shí)例(本地函數(shù)執(zhí)行環(huán)境容器)收到的 event 和 context 是真實(shí)來自線上的。
本地調(diào)試實(shí)例(本地環(huán)境 A)可以直接訪問以下內(nèi)容:
VPC 內(nèi)網(wǎng)資源,比如 RDS、Kafka 內(nèi)網(wǎng)地址等; 一些云服務(wù)的內(nèi)網(wǎng)地址; 硬盤掛載服務(wù)(直接訪問 NAS)。
端云聯(lián)調(diào)流程如下:
1)執(zhí)行 s proxied setup 命令準(zhǔn)備端云聯(lián)調(diào)所需的輔助資源以及本地環(huán)境;
2)對于無觸發(fā)器的普通事件函數(shù)或者 HTTP 觸發(fā)器,準(zhǔn)備工作完成后,啟動(dòng)另一個(gè)新的終端,切換到該項(xiàng)目路徑下,執(zhí)行 s proxied invoke 命令調(diào)用本地函數(shù);
3)完成調(diào)試任務(wù)后,執(zhí)行 s proxied cleanup 命令清理端云聯(lián)調(diào)所需的輔助資源以及本地環(huán)境。
除了通過命令使用端云聯(lián)調(diào)功能外,我們也可以在 VSCode 開發(fā)者工具中使用端云聯(lián)調(diào)功能,如圖所示:
在 VSCode 中使用端云聯(lián)調(diào)功能
遠(yuǎn)程調(diào)試
端云聯(lián)調(diào)在本地除了有一個(gè)通道服務(wù)容器外,還有一個(gè)函數(shù)計(jì)算容器,用來執(zhí)行本地函數(shù);遠(yuǎn)程輔助函數(shù)只是單純將遠(yuǎn)程流量發(fā)送到本地。在實(shí)際調(diào)試過程中,需要登錄到實(shí)例進(jìn)行項(xiàng)目調(diào)試,此時(shí)可以選擇使用遠(yuǎn)程調(diào)試。
相比于端云聯(lián)調(diào),遠(yuǎn)程調(diào)試在本地只有一個(gè)通道服務(wù)容器,執(zhí)行過程全部依賴線上;遠(yuǎn)程函數(shù)將執(zhí)行結(jié)果返回。遠(yuǎn)程調(diào)試整體架構(gòu)簡圖如圖所示。

除了通過上面遠(yuǎn)程調(diào)試架構(gòu)簡圖所示的通道服務(wù)登錄線上環(huán)境進(jìn)行代碼調(diào)試或問題定位之外,部分云廠商還提供了直接登錄實(shí)例進(jìn)行代碼調(diào)試的功能。以 Serverless Devs 為例,當(dāng)使用阿里云函數(shù)計(jì)算時(shí),我們就可以直接通過 instance 命令進(jìn)行線上實(shí)例登錄。
盡管實(shí)例登錄命令已經(jīng)提供了便捷的登錄體驗(yàn),能幫助用戶解決復(fù)雜場景下的應(yīng)用異常定位等問題,但是登錄實(shí)例后,用戶無法直接通過函數(shù)日志、監(jiān)控指標(biāo)來具體定位問題,還需要借助例如 coredump、tcpdump、jmap 等工具進(jìn)行問題的深入排查。
例如,某用戶發(fā)現(xiàn)自己的線上程序最近出現(xiàn)一些函數(shù)錯(cuò)誤提示,報(bào)錯(cuò)內(nèi)容都是連接遠(yuǎn)程某服務(wù)時(shí)超時(shí)。該用戶懷疑是函數(shù)實(shí)例與遠(yuǎn)端服務(wù)的網(wǎng)絡(luò)連接不穩(wěn)定,因此想進(jìn)入實(shí)例內(nèi)部,分析實(shí)例與遠(yuǎn)端服務(wù)的網(wǎng)絡(luò)情況。此時(shí),我們可以按照以下步驟進(jìn)行問題的排查。
1)如圖所示,登錄實(shí)例內(nèi)部后,需要執(zhí)行 apt-get update 和 apt-get install tcpdump 兩條命令,進(jìn)行 tcpdump 工具的安裝。
實(shí)例登錄與安裝軟件效果圖
2)安裝完畢后,執(zhí)行 tcpdump 命令,對遠(yuǎn)端服務(wù) IP 的請求進(jìn)行抓包,并將抓包結(jié)果保存在 tcpdump.cap 文件中。
3)抓包完畢后,借助 OSS 命令行工具 ossutil64,將 tcpdump.cap 文件上傳到自己的 OSS,然后下載到本地借助分析工具 Wireshark 進(jìn)行分析。
本地調(diào)試
命令行工具
大部分 FaaS 平臺(tái)會(huì)為用戶提供相對完備的命令行工具,如阿里云的 Funcraft,同時(shí)也有一些開源項(xiàng)目如 Serverless Framework、Serverless Devs 等支持多云廠商的 FaaS 平臺(tái)。
通過命令行工具進(jìn)行代碼調(diào)試的方法很簡單。以 Serverless Devs 為例,本地調(diào)試阿里云函數(shù)計(jì)算方法為:首先確保本地?fù)碛幸粋€(gè)函數(shù)計(jì)算的項(xiàng)目,然后在項(xiàng)目下執(zhí)行調(diào)試指令,例如在 Docker 中進(jìn)行調(diào)試,如下面所示:
通過命令行進(jìn)行本地調(diào)試
編輯器插件
以 VSCode 插件為例,下載好阿里云函數(shù)計(jì)算的 VSCode 插件,并且配置好賬號(hào)信息之后,在本地新建函數(shù),并且在打點(diǎn)之后進(jìn)行斷點(diǎn)調(diào)試,如圖所示:
編輯器插件中進(jìn)行調(diào)試
其他調(diào)試方案
Web 框架的本地調(diào)試
app = bottle.default_app()
并且對 run() 方法進(jìn)行條件限制(if __name__ == '__main__'):
if __name__ == '__main__':bottle.run(host='localhost', port=8080, debug=True)
例如:
# index.pyimport bottle@bottle.route('/hello/<name>')def index(name):return "Hello world"app = bottle.default_app()if __name__ == '__main__':bottle.run(host='localhost', port=8080, debug=True)
本地模擬事件調(diào)試
import jsondef handler(event, context): print(event)def test(): event = { "events": [ { "eventName": "ObjectCreated:PutObject", "eventSource": "acs:oss", "eventTime": "2017-04-21T12:46:37.000Z", "eventVersion": "1.0", "oss": { "bucket": { "arn": "acs:oss:cn-shanghai:123456789:bucketname", "name": "testbucket","ownerIdentity": "123456789", "virtualBucket": "" }, "object": { "deltaSize": 122539, "eTag": "688A7BF4F233DC9C88A80BF985AB7329", "key": "image/a.jpg", "size": 122539 }, "ossSchemaVersion": "1.0", "ruleId": "9adac8e253828f4f7c0466d941fa3db81161****" }, "region": "cn-shanghai", "requestParameters": { "sourceIPAddress": "140.205.***.***" }, "responseElements": { "requestId": "58F9FF2D3DF792092E12044C" }, "userIdentity": { "principalId": "123456789" } } ] } handler(json.dumps(event), None)if __name__ == "__main__": print(test())
03
如何進(jìn)行項(xiàng)目構(gòu)建?
通過開發(fā)者工具去依賴安裝和項(xiàng)目構(gòu)建
Serverless 架構(gòu)下的應(yīng)用開發(fā)和傳統(tǒng)架構(gòu)下的應(yīng)用開發(fā)有一個(gè)比較大的區(qū)別是二者所關(guān)注的內(nèi)容維度是不同的,例如理想狀態(tài)下的前者并不需要人們關(guān)注服務(wù)器等底層資源。
但是在當(dāng)今的 Serverless 發(fā)展階段,Serverless 架構(gòu)下的應(yīng)用開發(fā)真的不需要人們對服務(wù)器等額外關(guān)注嗎?其實(shí)不是的,雖然 Serverless 架構(gòu)強(qiáng)調(diào)的是 Noserver 心智,但是在實(shí)際生產(chǎn)中,有很多依賴等是無法跨平臺(tái)使用的,例如 Python 語言中的某些依賴需要進(jìn)行二進(jìn)制編譯,和操作系統(tǒng)、軟件環(huán)境等有比較大的關(guān)系,所以項(xiàng)目中如果引入這類依賴,需要在和函數(shù)計(jì)算平臺(tái)線上環(huán)境一致的環(huán)境中進(jìn)行依賴的安裝、代碼的打包或項(xiàng)目的部署。
阿里云函數(shù)計(jì)算 FC 對自身的線上函數(shù)環(huán)境有比較細(xì)致的描述,提供了相應(yīng)的文檔,例如使用 C、C++ 、Go 編譯的可執(zhí)行文件,需要與函數(shù)計(jì)算的運(yùn)行環(huán)境兼容。函數(shù)計(jì)算的 Python 運(yùn)行環(huán)境如下:
Linux 內(nèi)核版本:Linux 4.4.24-2.al7.x86_64。 Docker 基礎(chǔ)鏡像:docker pull python:2.7 ; docker pull python:3.6。
但是,在實(shí)際應(yīng)用開發(fā)過程中,依賴的打包依舊是讓一眾開發(fā)者頭疼的事情。他們在很多 Serverless 應(yīng)用開發(fā)過程中都會(huì)面臨類似的挑戰(zhàn):項(xiàng)目在本地可以正常運(yùn)行,一發(fā)布到線上就找不到某個(gè)依賴,但是實(shí)際上依賴是存在的,此時(shí)問題定位就成了非常困難的事情。
目前來看,為 Serverless 應(yīng)用安裝依賴或者項(xiàng)目構(gòu)建的方法通常有 3 種:
1)在本地創(chuàng)建項(xiàng)目之后,自行根據(jù)云廠商提供的環(huán)境數(shù)據(jù)進(jìn)行線上環(huán)境搭建,進(jìn)而進(jìn)行依賴的安裝。這種方法相對來說自主可控,但是難度非常大,操作較為繁瑣。
2)用已有的開發(fā)者工具進(jìn)行依賴的安裝,如圖所示:
通過工具安裝依賴示意圖開發(fā)源代碼; 執(zhí)行 s build –use-docker 命令之后,自動(dòng)根據(jù) requirements.txt 文件下載對應(yīng)的依賴到本地,并且和源碼一起組成交付物; 執(zhí)行 s deploy 命令將整個(gè)交付物打包,創(chuàng)建函數(shù),同時(shí)設(shè)置好依賴包的環(huán)境變量,讓函數(shù)可以直接輸入對應(yīng)的代碼依賴包。
在線安裝依賴示意圖新書推薦


點(diǎn)擊閱讀原文,直達(dá)阿里云函數(shù)計(jì)算 FC!