函數(shù)計(jì)算
作為云計(jì)算中新一代的計(jì)算單元,有著不需要管理服務(wù)器設(shè)施和更精準(zhǔn)的計(jì)費(fèi)方式的優(yōu)勢(shì)。它依托于云服務(wù)商的多種云資源(對(duì)象存儲(chǔ),日志服務(wù)等),將需要計(jì)算的業(yè)務(wù)邏輯濃縮在一個(gè)函數(shù)中拟淮,并協(xié)調(diào)多種其他云資源。收費(fèi)方式也采用按調(diào)用次數(shù)和運(yùn)行時(shí)間為計(jì)費(fèi)單位谴忧,使得計(jì)算資源的計(jì)費(fèi)更精準(zhǔn)很泊。對(duì)用戶(hù)來(lái)說(shuō),在保證業(yè)務(wù)正常運(yùn)轉(zhuǎn)的前提下沾谓,節(jié)省下不少業(yè)務(wù)閑時(shí)的服務(wù)器成本委造。
2014年AWS發(fā)布Lambda函數(shù)計(jì)算服務(wù),經(jīng)過(guò)幾年的發(fā)展函數(shù)計(jì)算
也越來(lái)越受到開(kāi)發(fā)者的關(guān)注均驶。
2017年昏兆,阿里云發(fā)布自己的函數(shù)計(jì)算
服務(wù)
本文記錄基于阿里云函數(shù)計(jì)算
服務(wù),簡(jiǎn)單實(shí)現(xiàn)app熱更新后端妇穴。
為什么使用函數(shù)計(jì)算
阿里云的官方文檔中介紹了幾種函數(shù)計(jì)算適用的場(chǎng)景:
- 媒資內(nèi)容分析處理:通過(guò)對(duì)象存儲(chǔ)上傳事件可以觸發(fā)多個(gè)函數(shù)爬虱,完成轉(zhuǎn)碼隶债、元數(shù)據(jù)抽取等功能。通過(guò)事件觸發(fā)機(jī)制跑筝,您能夠快速整合不同服務(wù)死讹,構(gòu)建一個(gè)彈性、高可用的視頻后端系統(tǒng)曲梗。
- Severless后端服務(wù):可以使用 函數(shù)計(jì)算和 API網(wǎng)關(guān) 構(gòu)建后端回俐,以驗(yàn)證和處理 API 請(qǐng)求。采用函數(shù)服務(wù)構(gòu)建靈活拓展架構(gòu),輕松創(chuàng)造豐富稀并、個(gè)性化的應(yīng)用程序體驗(yàn)。
- IoT消息實(shí)時(shí)處理:您可以使用函數(shù)計(jì)算高效的處理實(shí)時(shí)流數(shù)據(jù)单默。例如碘举,實(shí)時(shí)過(guò)濾、聚合搁廓、分析IoT設(shè)備產(chǎn)生的數(shù)據(jù)引颈,并將產(chǎn)生的結(jié)構(gòu)化數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中。
可以看出涨缚,函數(shù)計(jì)算主要應(yīng)用在事件出發(fā)->簡(jiǎn)單處理數(shù)據(jù)->存入數(shù)據(jù)庫(kù)或?qū)ο蟠鎯?chǔ)
場(chǎng)景下鳄梅。
這個(gè)場(chǎng)景也剛好適用于APP熱更新的后端的幾個(gè)核心業(yè)務(wù):
- 上傳新代碼:上傳代碼到OSS事件->分析代碼->更新最新版本信息
- 發(fā)布最新代碼:發(fā)布事件->查詢(xún)要發(fā)布代碼->發(fā)布代碼到環(huán)境
- APP查詢(xún)更新:最新版本查詢(xún)事件->比對(duì)app版本與最新版本->返回結(jié)果
從費(fèi)用方面考慮偷遗,函數(shù)計(jì)算
現(xiàn)在的免費(fèi)配額基本可以滿(mǎn)是日常試用,所以決定用函數(shù)計(jì)算
來(lái)支撐熱更新服務(wù)售滤。
架構(gòu)總覽
使用函數(shù)計(jì)算,主要是通過(guò)云上的資源來(lái)觸發(fā)函數(shù)台诗,然后由函數(shù)處理數(shù)據(jù)完箩,并調(diào)度其他云資源。
熱更新服務(wù)架構(gòu)圖
基本組件
在熱更新業(yè)務(wù)中拉队,主要涉及了以下幾個(gè)組件弊知。
函數(shù)計(jì)算
函數(shù)計(jì)算作為承載業(yè)務(wù)的應(yīng)用層,替代了傳統(tǒng)使用ECS服務(wù)搭建的應(yīng)用服務(wù)器粱快。
對(duì)象存儲(chǔ)
對(duì)象存儲(chǔ)用來(lái)做簡(jiǎn)單的數(shù)據(jù)持久化和存儲(chǔ)熱更新包秩彤。
日志服務(wù)
日志在函數(shù)計(jì)算中很重要。因?yàn)楹瘮?shù)容器在運(yùn)行結(jié)束后立即被銷(xiāo)毀事哭,運(yùn)行過(guò)程中的日志也會(huì)隨著容器同事銷(xiāo)毀漫雷。只有在函數(shù)運(yùn)行時(shí)將日志輸出到日志服務(wù),才能在之后查詢(xún)到函數(shù)的運(yùn)行記錄慷蠕。也因?yàn)槿绱松浩矗诤瘮?shù)調(diào)試時(shí),我們更需要日志服務(wù)來(lái)查看函數(shù)的運(yùn)行狀況流炕。
API網(wǎng)關(guān)
API網(wǎng)關(guān)為函數(shù)計(jì)算提供了對(duì)外提供Web API接口的能力澎现,同時(shí)也提供了身份認(rèn)證和授權(quán)兩大重要功能仅胞。在API網(wǎng)關(guān)中,用戶(hù)可以定義提供的接口簽名剑辫,并授權(quán)給特定的用戶(hù)使用Web API干旧。
業(yè)務(wù)流
上傳代碼
- 用戶(hù)通過(guò)OSS命令行或OSS控制臺(tái)直接上傳代碼到指定目錄
- OSS觸發(fā)函數(shù)計(jì)算執(zhí)行相應(yīng)業(yè)務(wù)
- 函數(shù)計(jì)算將結(jié)果保存回OSS指定目錄
檢查更新
- APP客戶(hù)端訪問(wèn)API網(wǎng)關(guān)提供的API
- API網(wǎng)關(guān)調(diào)用函數(shù)計(jì)算檢查版本
- API網(wǎng)關(guān)將函數(shù)計(jì)算結(jié)果返回給客戶(hù)端
基本概念
函數(shù)計(jì)算有幾個(gè)主要的概念,在開(kāi)始前需要了解妹蔽。
角色和授權(quán)
函數(shù)計(jì)算本身只處理業(yè)務(wù)邏輯椎眯,當(dāng)函數(shù)計(jì)算需要與阿里云上其他資源交互的時(shí)候,就需要利用阿里云的RAM(訪問(wèn)控制)系統(tǒng)來(lái)給函數(shù)一個(gè)角色和授權(quán)
來(lái)和其他云資源交互胳岂。函數(shù)在運(yùn)行時(shí)编整,可以通過(guò)默認(rèn)傳入函數(shù)的context
變量獲取角色的憑證,并扮演該角色與已授權(quán)的云資源進(jìn)行交互乳丰。
關(guān)于如何為函數(shù)服務(wù)創(chuàng)建角色的詳細(xì)內(nèi)容可以參考應(yīng)用示例2 - 授權(quán)函數(shù)訪問(wèn)其他云服務(wù)資源
觸發(fā)器和事件
事件是當(dāng)其他云資源需要觸發(fā)函數(shù)計(jì)算處理時(shí)掌测,發(fā)送給函數(shù)計(jì)算服務(wù)的一段包含特定事件詳情的信息。其他云資源可以定義什么時(shí)候觸發(fā)事件(即定義觸發(fā)器)产园,不同資源汞斧,觸發(fā)事件后發(fā)送給函數(shù)計(jì)算的事件詳情不同。
注:目前阿里云上只有AIP網(wǎng)關(guān)
和OSS對(duì)象存儲(chǔ)
支持創(chuàng)建觸發(fā)器什燕。
更多細(xì)節(jié)可參考應(yīng)用示例4 - 觸發(fā)器管理
服務(wù)
服務(wù)是管理函數(shù)的最小單位粘勒,每個(gè)函數(shù)都只屬于一個(gè)服務(wù)。 服務(wù)中可以定義函數(shù)可以使用的'角色'和日志輸出的倉(cāng)庫(kù)屎即,所有函數(shù)
共享所屬服務(wù)
的這些設(shè)定庙睡。
函數(shù)
函數(shù)
是運(yùn)行代碼的容器。用戶(hù)自己編寫(xiě)需要處理的業(yè)務(wù)技俐,并放在相應(yīng)語(yǔ)言的函數(shù)容器中運(yùn)行埃撵。
注:目前阿里云支持nodejs
, python
和java
實(shí)現(xiàn)步驟
簡(jiǎn)單介紹,搭建熱更新后端的步驟虽另。
工具
用戶(hù)可以在阿里云控制臺(tái)中操作創(chuàng)建服務(wù)
和函數(shù)
暂刘,更方便的做法是使用行數(shù)計(jì)算命令行工具fcli
進(jìn)行創(chuàng)建。在下面的步驟中捂刺,采用fcli的方式介紹谣拣。
fcli下載及文檔
初次使用fcli需要使用阿里云賬號(hào)登陸。 注:如果使用子賬號(hào)登陸族展,子賬號(hào)需要有操作RAM和函數(shù)計(jì)算的授權(quán)森缠。
運(yùn)行:
fcli shell
Please input the endpoint (example: https://account_id.cn-shanghai.fc.aliyuncs.com):
> [ENDPOINT]
Please input the access key id:
> [FAKE_ACCESS_KEY_ID]
Please input the access key secret:
> [FAKE_ACCESS_KEY_SECRET]
Store the configuration in: /Users/testuser/.fcli
Welcome to the function compute world. Have fun!
獲取endpoint,請(qǐng)參考服務(wù)入口文檔仪缸。
獲取access key id/secret贵涵,請(qǐng)參考相關(guān)文檔。
創(chuàng)建角色授權(quán)
當(dāng)函數(shù)計(jì)算和其他云資源有交互的時(shí)候,需要?jiǎng)?chuàng)建兩種角色授權(quán)宾茂,一種是授權(quán)給其他云資源使用觸發(fā)函數(shù)計(jì)算的角色瓷马, 另一種是授權(quán)給函數(shù)計(jì)算使用云資源的角色。
觸發(fā)函數(shù)計(jì)算
創(chuàng)建觸發(fā)函數(shù)計(jì)算角色跨晴,用來(lái)授權(quán)給其他云資源調(diào)用函數(shù)計(jì)算服務(wù)欧聘。 例如,授權(quán)api網(wǎng)關(guān)調(diào)用函數(shù)計(jì)算端盆,或?qū)ο蟠鎯?chǔ)服務(wù)觸發(fā)函數(shù)計(jì)算怀骤。
運(yùn)行:
mkir fc-invoke-function
mkrp fc-invoke-all -a '"fc:InvokeFunction"' -r '"*"'
attach -p /ram/policies/fc-invoke-all -r /ram/roles/fc-invoke-function
對(duì)象存儲(chǔ)及日志服務(wù)讀寫(xiě)
創(chuàng)建其他云資源調(diào)用角色,用來(lái)讓函數(shù)計(jì)算服務(wù)可以訪問(wèn)日志服務(wù)
和OSS對(duì)象存儲(chǔ)
服務(wù)焕妙。
運(yùn)行:
mksr fc-oss-log-op
mkrp fc-oss-log-gp -a '["oss:GetObject", "oss:PutObject", "log:PostLogStoreLogs", "log:GetLogStore"]' -r '"*"'
attach -p /ram/policies/fc-oss-log-gp -r /ram/roles/fc-oss-log-op
mks oss_demo -r acs:ram::[ALIYUN ACCOUNT id]:role/fc-oss-log-op
注:這里為了演示方便蒋伦,并沒(méi)有限制具體可操作資源,用戶(hù)需要更具具體情況合理的限制可操作資源焚鹊。
創(chuàng)建日志庫(kù)
創(chuàng)建日志庫(kù)來(lái)凉敲,用來(lái)收集函數(shù)日志。 具體步驟可以參考函數(shù)訪問(wèn)日志服務(wù)
這里創(chuàng)建一個(gè)日志項(xiàng)目名為fc-beijing
寺旺, 倉(cāng)庫(kù)名為hotpatch
的日志庫(kù)。
創(chuàng)建OSS
熱更新的代碼需要存放在OSS中势决,所以需要?jiǎng)?chuàng)建一個(gè)與函數(shù)服務(wù)在同一個(gè)區(qū)存儲(chǔ)空間阻塑。名字為hotpatch
, 且讀寫(xiě)權(quán)限為‘公共讀,私有寫(xiě)’果复。
創(chuàng)建函數(shù)服務(wù)
在阿里控制臺(tái)選擇函數(shù)服務(wù)陈莽,創(chuàng)建名為hotpatchService
的函數(shù)服務(wù),選擇剛創(chuàng)建的日志庫(kù)hotpatch
和fc-oss-log-op
這個(gè)角色虽抄。
創(chuàng)建項(xiàng)目
函數(shù)服務(wù)本身每一個(gè)函數(shù)都是獨(dú)立的代碼片段處理業(yè)務(wù)的某一個(gè)部分走搁,自身就像一個(gè)小的項(xiàng)目。但是迈窟,一個(gè)服務(wù)下的所有函數(shù)私植,卻是在處理同一塊業(yè)務(wù)。
熱更新項(xiàng)目的結(jié)構(gòu)车酣,借鑒了一些開(kāi)源項(xiàng)目包含多個(gè)子項(xiàng)目的代碼管理思路曲稼,把服務(wù)作為一個(gè)項(xiàng)目,每一個(gè)函數(shù)作為子項(xiàng)目湖员。達(dá)到贫悄,服務(wù)的所有函數(shù)代碼使用同一個(gè)代碼庫(kù)管理,但每個(gè)函數(shù)的代碼又是獨(dú)立的可以自行管理依賴(lài)娘摔,測(cè)試窄坦,發(fā)布等操作。
因?yàn)椴捎胣odejs開(kāi)發(fā),所以使用lerna作為管理項(xiàng)目和子項(xiàng)目的工具鸭津。項(xiàng)目目錄如下:
├── README.md
├── lerna.json
├── package.json
├── packages
│ ├── getLatestBundle
│ │ ├── index.js
│ │ └── package.json
│ └── uploadBundle
│ ├── index.js
│ ├── node_modules
│ ├── package-lock.json
│ └── package.json
packages
目錄下存放著不同的函數(shù)彤侍,每個(gè)函數(shù)是一個(gè)文件夾, 使用函數(shù)名字命名,例如uploadBundle
曙博。沒(méi)個(gè)函數(shù)使用package.json
管理依賴(lài)包拥刻。
上傳UploadBundle代碼
在uploadBunde目錄下運(yùn)行
fcli shell
mkf uploadBundle -h index.handler -t nodejs6
上傳getLatestBundle代碼
上傳getLatestBundle代碼
fcli shell
mkf getLatestBundle -h index.handler -t nodejs6
更新代碼
使用編輯器編輯本地代碼后,在函數(shù)文件夾運(yùn)行
fcli shell
upf [FUNCTION NAME] -h index.handler -t nodejs6
創(chuàng)建觸發(fā)器
目前只有OSS對(duì)象存儲(chǔ)服務(wù)父泳,支持創(chuàng)建函數(shù)觸發(fā)器般哼,用戶(hù)可以定義當(dāng)存儲(chǔ)空間內(nèi)某些操作執(zhí)行后觸發(fā)函數(shù),例如用戶(hù)上傳新的對(duì)象后惠窄,觸發(fā)函數(shù)蒸眠。
在熱更新后臺(tái)中,需要在有新代碼上傳后杆融,對(duì)代碼進(jìn)行md5計(jì)算楞卡,并放入測(cè)試環(huán)境。
創(chuàng)建觸發(fā)器config.yaml, 定義OSS觸發(fā)函數(shù)的事件
triggerConfig:
events:
- oss:ObjectCreated:*
filter:
key:
prefix: src/
suffix: .js
在bash中運(yùn)行:
mkt uploadBundle -t oss -r acs:ram::[ALIYUN ACCOUNT id]:role/fc-invoke-function -s acs:oss:[REGION]:[ALIYUN ACCOUNT ID]:hotpatch -c config.yaml
API網(wǎng)關(guān)
當(dāng)使用函數(shù)計(jì)算作為Web API服務(wù)后端時(shí)脾歇,需要使用API網(wǎng)關(guān)來(lái)定義Web API的接口蒋腮,并由API網(wǎng)關(guān)轉(zhuǎn)換客戶(hù)端請(qǐng)求后,調(diào)用函數(shù)計(jì)算服務(wù)藕各。
在更新后臺(tái)中池摧,檢測(cè)版本更新需要以Web API的形式提供給APP客戶(hù)端訪問(wèn)。
步驟:
在阿里云控制臺(tái)中打開(kāi)API網(wǎng)關(guān)
激况,創(chuàng)建名為hotpatchAPIGroup
的分組
創(chuàng)建名為getLatestBundle
的API
安全方式暫時(shí)選則無(wú)認(rèn)證
作彤,在后面的安全
章節(jié)中會(huì)介紹如何開(kāi)啟認(rèn)證。
創(chuàng)建API
請(qǐng)求基礎(chǔ)定義
后端基礎(chǔ)定義
定義返回結(jié)果
{
"isBase64Encoded":true|false,
"statusCode":httpStatusCode,
"headers":{response headers},
"body":"..."
}
注:更詳細(xì)步驟可參考API網(wǎng)關(guān)觸發(fā)函數(shù)計(jì)算
安全
在之前創(chuàng)建API時(shí)乌逐,選擇了無(wú)認(rèn)證
竭讳,在學(xué)習(xí)使用函數(shù)計(jì)算作為API服務(wù)后端時(shí)是可以簡(jiǎn)化概念,把重點(diǎn)放在如何鏈接兩個(gè)服務(wù)上浙踢。 在真實(shí)項(xiàng)目中绢慢,我們依然希望API的訪問(wèn)是可控的,只有授權(quán)過(guò)的客戶(hù)端才可以訪問(wèn)洛波。
API網(wǎng)關(guān)服務(wù)提供了一種基于應(yīng)用的認(rèn)證授權(quán)的機(jī)制呐芥,用戶(hù)可以在API網(wǎng)關(guān)中創(chuàng)建一個(gè)應(yīng)用,并在API中設(shè)置安全方式為阿里云APP
, 簽名算法為HmacSHA256
奋岁。 之后思瘟,在授權(quán)信息
中添加應(yīng)用訪問(wèn)API的授權(quán)。
注:詳細(xì)步驟可參考授權(quán)給應(yīng)用
后記
熱更新后
端作為技術(shù)驗(yàn)證項(xiàng)目闻伶,已經(jīng)部署在測(cè)試環(huán)境滨攻,生產(chǎn)環(huán)境暫時(shí)沒(méi)有開(kāi)啟。
目前,還有幾處不完善的地方:
- 發(fā)布函數(shù)
- 客戶(hù)端命令行
- 針對(duì)不同版本做diff patch光绕,使更新包更小女嘲。
TODO
- 公開(kāi)項(xiàng)目代碼