云函數(shù)基本應(yīng)用
云函數(shù)(Serverless Cloud Function)是騰訊云提供的無服務(wù)器(serverless)執(zhí)行環(huán)境,幫助用戶在沒有購買和管理服務(wù)器時(shí)仍能運(yùn)行代碼。
用戶只需要使用云平臺(tái)支持的語言編寫核心代碼及設(shè)置代碼運(yùn)行的條件,代碼即可在騰訊云基礎(chǔ)設(shè)施上彈性、安全地運(yùn)行,并可完全管理底層計(jì)算資源,包括服務(wù)器CPU、內(nèi)存、網(wǎng)絡(luò)、代碼部署、彈性伸縮、負(fù)載均衡等服務(wù)。
1.服務(wù)端架構(gòu)的演進(jìn)
1.1 物理機(jī)時(shí)代(機(jī)房)
步驟:
購買主機(jī)
托管機(jī)房(備案)
鏈接電源網(wǎng)線
安裝系統(tǒng)
部署運(yùn)行環(huán)境
申請靜態(tài)IP

部署繁瑣,問題多(磁盤受損,停電...)
1.2 虛擬機(jī)時(shí)代
物理機(jī)分割成多臺(tái)虛擬機(jī)提供給用戶使用,硬件設(shè)備管理統(tǒng)一由云廠商負(fù)責(zé),直接在云平臺(tái)購買虛擬機(jī)

問題:用戶增多,數(shù)據(jù)和圖片過多,數(shù)據(jù)庫性能瓶頸,磁盤耗盡、資源不足,服務(wù)器負(fù)載
處理:數(shù)據(jù)庫遷移到云廠商提供的云服務(wù)器上,更穩(wěn)定性能更好;圖片存儲(chǔ)遷移到對象存儲(chǔ)上,無限擴(kuò)容。服務(wù)器只處理請求,將計(jì)算和存儲(chǔ)分離開,降低了系統(tǒng)負(fù)載。
虛擬機(jī)優(yōu)點(diǎn):不用關(guān)心底層硬件
存在問題:服務(wù)器集群管理(服務(wù)器運(yùn)行環(huán)境配置、統(tǒng)一)
1.3 容器時(shí)代(主流服務(wù)器架構(gòu)技術(shù),docker)
在虛擬機(jī)技術(shù)的基礎(chǔ)上把代碼和環(huán)境打包到一起,與服務(wù)器配置分離,使代碼和運(yùn)行環(huán)境保持一致。在服務(wù)器部署容器,不再部署應(yīng)用。
存在問題:容器過多時(shí)的管理
解決方法:容器編排技術(shù)(k8s)
||
問題:流量洪峰(服務(wù)器預(yù)估不到位宕機(jī))-》 服務(wù)器擴(kuò)充、大量編排工作 -》 平時(shí)大量服務(wù)器運(yùn)行浪費(fèi)成本
需要:只關(guān)心業(yè)務(wù)代碼的實(shí)現(xiàn),脫離服務(wù)器管理,不用再關(guān)注運(yùn)行環(huán)境和服務(wù)器擴(kuò)容,流量洪峰來臨時(shí)自動(dòng)調(diào)配更多服務(wù)器資源支撐,流量低谷時(shí)自動(dòng)釋放服務(wù)器資源節(jié)約成本。
解決方案:serverless,自動(dòng)進(jìn)行服務(wù)器資源管理
服務(wù)端發(fā)展(基礎(chǔ)架構(gòu)的抽象)

物理機(jī) -> 虛擬機(jī): 脫離硬件設(shè)備管理,將計(jì)算機(jī)拆分為相互隔離的虛擬機(jī)
虛擬機(jī) -> 容器:擺脫運(yùn)行環(huán)境和集群管理工作,將虛擬機(jī)運(yùn)行環(huán)境抽象為容器
容器 -> serverless:不再關(guān)心運(yùn)行環(huán)境和服務(wù)器資源調(diào)配
2.serverless概念
serverful:服務(wù)器的一切都需要人工進(jìn)行干預(yù)

廣義概念:服務(wù)端架構(gòu)理念,開發(fā)者不用關(guān)心服務(wù)器,將服務(wù)器相關(guān)工作交給云平臺(tái),與服務(wù)器運(yùn)維有關(guān)的所有工作都不再關(guān)心。
開發(fā)者只關(guān)注業(yè)務(wù)邏輯本身,所有與業(yè)務(wù)無關(guān)的基礎(chǔ)設(shè)施都交由云平臺(tái)負(fù)責(zé),由云平臺(tái)統(tǒng)一調(diào)度、管理、運(yùn)維。
狹義概念:Serverless架構(gòu)就是采用FaaS(函數(shù)即服務(wù))和BaaS(后端即服務(wù))服務(wù)來解決問題的一種設(shè)計(jì)。

Baas(backend as a service):(服務(wù)器和開發(fā)環(huán)境)由serverless對后端架構(gòu)進(jìn)行包攬,包括硬件維護(hù)、集群管理、運(yùn)行環(huán)境搭建、緩存等等,由云平臺(tái)做好封裝,以接口方式提供服務(wù)。對開發(fā)者來說,只需要編寫業(yè)務(wù)邏輯代碼,不需要關(guān)心實(shí)現(xiàn),baas作為一個(gè)黑盒,通過接口對黑盒進(jìn)行取用。
-
Faas(function as a service):(運(yùn)行邏輯代碼)以函數(shù)方式運(yùn)行代碼,函數(shù)運(yùn)行平臺(tái)。選擇編程語言編寫函數(shù)。
對開發(fā)來說,faas即serverless,在faas中能體會(huì)到serverless全部特性:
無運(yùn)維:faas函數(shù)運(yùn)行時(shí),開發(fā)者對底層函數(shù)無感知,faas負(fù)責(zé)服務(wù)器資源調(diào)度和運(yùn)維
事件驅(qū)動(dòng):不持續(xù)運(yùn)行,通過一定條件進(jìn)行觸發(fā),集成觸發(fā)器直接使用
按量付費(fèi):根據(jù)faas執(zhí)行次數(shù)和消耗CPU進(jìn)行付費(fèi)
彈性收縮:根據(jù)函數(shù)運(yùn)行需要資源量自動(dòng)調(diào)配服務(wù)器資源,實(shí)時(shí)彈性伸縮
faas進(jìn)行計(jì)算+baas進(jìn)行存儲(chǔ),分開部署收費(fèi)。應(yīng)用存儲(chǔ)被分離成獨(dú)立云服務(wù)器,減少丟失風(fēng)險(xiǎn);應(yīng)用本身變?yōu)闊o狀態(tài),易于調(diào)度和擴(kuò)縮容。
serverless的缺點(diǎn)
嚴(yán)重依賴云平臺(tái)廠商:各云廠商實(shí)現(xiàn)接口的標(biāo)準(zhǔn)不同,同一套代碼無法在不同serverless產(chǎn)品上運(yùn)行,云平臺(tái)遷移成本高
開發(fā)調(diào)試?yán)щy:serverless依賴云服務(wù),本地難以搭建云服務(wù)環(huán)境,在本地開發(fā)調(diào)試復(fù)雜。serverless架構(gòu)飛速發(fā)展,開發(fā)調(diào)試部署等工具不完善。
底層硬件不確定:baas對開發(fā)者來說是個(gè)黑盒,硬件資源不確定。當(dāng)代碼需要在特定CPU和GPU上運(yùn)行時(shí),云廠商未提供對底層硬件的可選項(xiàng),底層硬件的類型和型號(hào)不可知。
(其它:運(yùn)行機(jī)制、開發(fā)方式……)
3.云函數(shù)使用
云平臺(tái):騰訊云(初學(xué)者友好)
云開發(fā)CloudBase:包含整個(gè)使用時(shí)需要的所有服務(wù),用戶驗(yàn)證、數(shù)據(jù)庫存儲(chǔ)、緩存等(不使用服務(wù)器資源時(shí)免費(fèi))
1)登錄騰訊云
2)選擇serverless應(yīng)用
3)選擇函數(shù)服務(wù)
4)創(chuàng)建函數(shù)
用戶帳號(hào)配額限制
| 內(nèi)容 | 默認(rèn)配額限制 |
|---|---|
| 每個(gè)地域下的函數(shù)代碼總體積 | 100GB |
| 每個(gè)地域下的總函數(shù)并發(fā)配額 | 128000MB(廣州、上海、北京、成都、中國香港)64000MB(孟買、新加坡、東京、多倫多、硅谷、法蘭克福、深圳金融、上海金融) |
| 每個(gè)地域下命名空間個(gè)數(shù) | 5 |
| 每個(gè)命名空間下的總函數(shù)并發(fā)配額 | 可購買 函數(shù)套餐包進(jìn)行配額調(diào)整 |
| 每個(gè)命名空間下函數(shù)個(gè)數(shù) | 50 |
函數(shù)類型選擇:
event 函數(shù): 由指定格式的事件觸發(fā),例如定時(shí)觸發(fā)事件、COS 觸發(fā)事件等,事件結(jié)構(gòu)詳情見 觸發(fā)器。
Web 函數(shù):專注于優(yōu)化 Web 服務(wù)場景,可以直接接受并處理 HTTP 請求,詳情見 Web 函數(shù)。
執(zhí)行方法:對應(yīng)項(xiàng)目的主函數(shù),是程序執(zhí)行的起點(diǎn),以文件名.執(zhí)行方法名的形式進(jìn)行設(shè)置,如
index.main_handler。-
函數(shù)入?yún)?/strong>:指函數(shù)在被觸發(fā)調(diào)用時(shí)所傳遞給函數(shù)的內(nèi)容。
event: 觸發(fā)函數(shù)執(zhí)行的基本信息
-
云 API 觸發(fā)函數(shù)執(zhí)行: 在調(diào)用方和函數(shù)代碼之間自定義一個(gè) dict 類型的參數(shù)。調(diào)用方按照定義好的格式傳入數(shù)據(jù),函數(shù)代碼按格式獲取數(shù)據(jù)。
示例: 定義一個(gè) dict 類型的數(shù)據(jù)結(jié)構(gòu)
{"key":"XXX"},當(dāng)調(diào)用方傳入數(shù)據(jù){"key":"abctest"}時(shí),函數(shù)代碼可以通過event[key]來獲得值 abctest。 -
觸發(fā)器觸發(fā)函數(shù)執(zhí)行: SCF 和 API 網(wǎng)關(guān)、對象存儲(chǔ) COS、消息隊(duì)列 Ckafka 等多種云服務(wù)打通,可以通過給函數(shù)綁定對應(yīng)的云服務(wù)觸發(fā)器觸發(fā)函數(shù)執(zhí)行。觸發(fā)器觸發(fā)函數(shù)時(shí),event 會(huì)以一種平臺(tái)預(yù)定義的、不可更改的格式作為 event 參數(shù)傳給函數(shù),可以根據(jù)此格式編寫代碼并從 event 參數(shù)中獲取信息。
示例: 通過對象存儲(chǔ) COS 觸發(fā)函數(shù)時(shí)會(huì)將對象存儲(chǔ)桶及文件的具體信息以JSON 格式 傳遞給 event 參數(shù),在函數(shù)代碼中通過解析 event 信息即可完成對觸發(fā)事件的處理。
-
context: SCF 平臺(tái)提供的入?yún)ⅲ@取到運(yùn)行環(huán)境及當(dāng)前請求的相關(guān)信息。SCF 提供的入?yún)?context 包含的字段及含義如下:
[圖片上傳失敗...(image-ee09f3-1688375998501)]
-
函數(shù)返回:云函數(shù)執(zhí)行完成后的返回值。
callback 是一個(gè)可選參數(shù),在非異步函數(shù)中返回執(zhí)行結(jié)果,參數(shù)包括一個(gè) Error 和一個(gè)返回。
異步函數(shù)將忽略 callback 的返回,必須通過 return、throw exception 或者 promise 來處理返回或錯(cuò)誤。
SCF 平臺(tái)會(huì)獲取到云函數(shù)執(zhí)行完成后的返回值,并根據(jù)下表中不同的觸發(fā)方式進(jìn)行處理。
| 觸發(fā)方式 | 處理方式 |
|---|---|
| 同步觸發(fā) | 通過 API 網(wǎng)關(guān)、云 API 同步 invoke 觸發(fā)函數(shù)的方式為同步觸發(fā)。使用同步方式觸發(fā)的函數(shù)在執(zhí)行期間,SCF 平臺(tái)不會(huì)返回觸發(fā)結(jié)果。在函數(shù)執(zhí)行完成后,SCF 平臺(tái)會(huì)將函數(shù)返回值封裝為 JSON 格式并返回給調(diào)用方。 |
| 異步觸發(fā) | 使用異步方式觸發(fā)的云函數(shù),SCF 平臺(tái)接收觸發(fā)事件后,會(huì)返回觸發(fā)請求 ID 。在函數(shù)執(zhí)行完成后,函數(shù)的返回值會(huì)封裝為 JSON 格式并存儲(chǔ)在日志中。用戶可在函數(shù)執(zhí)行完成后,通過返回的請求 ID 查詢?nèi)罩精@取該異步觸發(fā)函數(shù)的返回值。對于異步函數(shù),可以使用 return 和 throw 來發(fā)送返回或錯(cuò)誤。函數(shù)必須使用 async 關(guān)鍵字。在異步函數(shù)中,第三個(gè)參數(shù) callback 沒有定義。 |
js異步函數(shù)示例:
const httpRequest = url => {
const promise = new Promise(function(resolve, reject) {
https
.get(url, res => {
resolve(res.statusCode)
})
.on('error', e => {
reject(Error(e))
})
})
return promise
}
exports.main_handler = async function(event, context) {
try{
const result = await httpRequest(url)
// 在async函數(shù)中callback未定義
// callback(null, result)
return result
}catch(e) {
throw e
}
}
js同步函數(shù)示例:
exports.main_handler = function(event, context, callback) {
https.get(url, (res) => {
// 只能通過callback返回,return會(huì)被忽略
callback(null, res.statusCode)
}).on('error', (e) => {
callback(Error(e))
})
}
函數(shù)配置:

5)創(chuàng)建事件觸發(fā)器。環(huán)境->訪問服務(wù)->新建觸發(fā)路徑(關(guān)聯(lián)資源:云函數(shù))

4. 云函數(shù)實(shí)戰(zhàn)
-
功能:實(shí)現(xiàn)一個(gè)定時(shí)提醒員工吃飯的企業(yè)微信機(jī)器人
代碼:
/**************************************************
demo-show 說明
postData里的content需要修改為自己需要的
request里的url需要填寫之前創(chuàng)建的機(jī)器人對應(yīng)的WebHook
***************************************************/
const request = require('request')
exports.main_handler = async (event, context, callback) => {
return new Promise((resolve, reject) => {
const date = dateFormat({
time: +new Date(),
format: 'yyyymmdd'
})
const postData = {
"msgtype": "text",
"text": {
"content": "吃飯了\n",
"mentioned_list":["@all"]
}
}
request({
url: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=',
method: 'POST',
headers: {
"content-type": "application/json",
},
body: JSON.stringify(postData)
}, function(err, res) {
if (!err && res.statusCode == 200) {
resolve('success')
} else {
reject(err)
}
});
})
}
觸發(fā)器設(shè)置:

- 創(chuàng)建express項(xiàng)目

-
VSCode開發(fā)
下載Tencent Serverless Toolkit for VS Code,登錄賬戶,通過該插件生成云函數(shù),上傳到云端
