萬物皆可 Serverless 之關於雲函數冷熱啓動那些事兒

本文帶你們來了解一下雲函數的冷熱啓動過程,以及面對雲函數這種冷熱啓動模式,開發者須要注意哪些問題。javascript

本文來自 Serverless 社區用戶「乂乂又又」投稿java

效果展現

雲函數被第一次調用(冷啓動)python

雲函數被第一次調用(冷啓動)

雲函數被屢次連續調用(熱啓動)git

雲函數被屢次連續調用(熱啓動)

雲函數的冷、熱啓動模式

先跟你們講下這裏的雲函數冷熱啓動模式是什麼意思。github

  • 冷啓動是指你在服務器中新開闢一塊空間供一個函數實例運行,這個過程有點像你把這個函數放到虛擬機裏去運行,每次運行前都要先啓動虛擬機加載這個函數,這是比較耗時的一個過程,因此雲函數須要儘可能減小自身冷啓動的次數。
  • 熱啓動則是說若是一個雲函數被持續觸發,那我就先不釋放這個雲函數實例,下次請求仍然由以前已經建立了的雲函數實例來運行,就比如咱們打開虛擬機運行完這個函數以後沒有關閉虛擬機,而是讓它待機,等待下一次被從新觸發調用運行,這樣作的好處就是省去了給虛擬機「開機」的一個耗時環節,缺點是要一直維持這個虛擬機的激活狀態,系統開銷會大一些。

固然這裏的雲函數資源分配的問題並不須要咱們操心,雲函數的底層會經過算法自行調配。算法

在騰訊云云函數文檔裏的簡介 裏有這麼一段描述:express

騰訊云云函數是騰訊雲提供的 Serverless 執行環境。您只需編寫簡單的、目的單一的雲函數便可將它與您的騰訊雲基礎設施及其餘雲服務產生的事件關聯。
使用雲函數時,您只需使用平臺支持的語言(Python、Node.js、PHP、Golang 及 Java)編寫代碼。騰訊雲將徹底管理底層計算資源,包括服務器 CPU、內存、網絡和其餘配置/資源維護、代碼部署、彈性伸縮、負載均衡、安全升級、資源運行狀況監控等。但這也意味着您沒法登陸或管理服務器、沒法自定義系統和環境。
雲函數自動地在同一地域內的多個可用區部署,同時提供極高的容錯性。雲函數在執行時將根據請求負載擴縮容,從天天幾個請求到每秒數千個請求,都由雲函數底層自行伸縮。您無需人工配置和介入,只需爲運行中的雲函數付費,便可知足不一樣情景下服務的可用性和穩定性。若雲函數未運行,則不產生任何費用。
您能夠自定義運行雲函數的時機,例如,在 COS Bucket 上傳時、刪除文件時運行雲函數、應用程序經過 SDK 調用時運行雲函數,或指定雲函數按期執行。您可使用雲函數做爲 COS 服務的數據處理觸發程序輕鬆實現 IFTTT 邏輯,您也能夠經過構建靈活的定時自動化任務,用於覆蓋手工完成的操做,輕鬆構建靈活可控的軟件架構。json

你們注意這一句api

雲函數在執行時將根據請求負載擴縮容,從天天幾個請求到每秒數千個請求,都由雲函數底層自行伸縮。瀏覽器

能夠看到雲函數的函數實例個數在系統底層是經過算法自行伸縮的,

咱們再往下看

在 Serverless 2.0 中,咱們不只在控制流和數據流的模塊、虛擬化層、網絡層、調度層都作了完全的重構優化,還在安全性、可用性以及性能方面也進行了全面升級。經過採用輕量級虛擬化技術、VPC Proxy 轉發方案等多種優化手段使用統一的底層架構。針對實時自動擴縮容核心的能力進行優化,完全規避了傳統無服務器架構中飽受詬病的冷啓動問題。
雲函數再也不限制運行時長,支持更豐富的應用場景。例如:
服務型函數不限制單次請求的時長。當請求持續到來時,服務會保持一個長運行的模式,無溫、冷啓動時延。
服務型函數支持 WebSocket 長鏈接。
Event Function(觸發器函數)具有單次調用時長限制,但在請求持續到來時,服務是保持長運行模式,並沒有溫、冷啓動時延。

注意這句:

觸發器函數具有單次調用時長限制,但在請求持續到來時,服務是保持長運行模式,並沒有溫、冷啓動時延。

也就是說咱們經過各類方式來觸發的雲函數實例,並不都是徹底冷啓動的,也有多是以前調用的雲函數的實例。

下面咱們一塊兒來作一個實驗

import json

global_v=1

# api網關回復消息格式化
def apiReply(reply, code=200):
    return {
        "isBase64Encoded": False,
        "statusCode": code,
        "headers": {'Content-Type': 'application/json', "Access-Control-Allow-Origin": "*"},
        "body": json.dumps(reply, ensure_ascii=False)
    }


def main_handler(event, context):
    global global_v
    global_v+=1
    return apiReply({
        'ok': True,
        'message': global_v-1
    })

上面是一個簡單的 python 雲函數,咱們給它添加一個 API 網關觸發器來試驗一下它會返回什麼結果:

  • 第一次調用,返回了1,說明咱們的雲函數被冷啓動了

第一次調用,返回了1,說明咱們的雲函數被冷啓動了

  • 繼續調用,發現此次返回了2,說明咱們的雲函數是在上一個實例的基礎上被熱啓動的:

繼續調用,發現此次返回了2,說明咱們的雲函數是在上一個實例的基礎上被熱啓動的

再試幾回咱們發現有的是被熱啓動,有的依然是被冷啓動:

serverless

serverless

serverless

可是這種表現顯然是與咱們的預期不符的,咱們指望前面的請求是不會影響到後面雲函數運行結果的,這就是問題所在。

好,咱們如今再去看一下官方文檔是怎麼說的

SCF 是否會重複使用函數實例?
爲了提升性能,SCF 會在必定時間內保留您的函數實例,將其再用於服務後續請求。但您的代碼不該假設此操做老是發生。
爲什麼要保持 SCF 函數無狀態?
保持函數的無狀態性可以使函數按須要儘量多地啓動多個實例,從而知足請求的速率。

也就是說,咱們在編輯雲函數時必定要保證 SCF 函數是無狀態的,否則就會出現一些沒法預測的奇怪問題。

那麼什麼是無狀態呢?說白了就是你的雲函數不能依賴以前函數運行的狀態或者是結果,而且要儘可能避免全局變量的使用!

由於就像咱們以前實驗中那樣,全局變量的值會在雲函數的冷熱啓動過程當中變得沒法預測,這在咱們後續的函數調測過程當中,無疑是一場災難~

更多關於騰訊云云函數 SCF 使用的常見問題,可參考官方文檔

Serverless Framework 30 天試用計劃

咱們誠邀您來體驗最便捷的 Serverless 開發和部署方式。在試用期內,相關聯的產品及服務均提供免費資源和專業的技術支持,幫助您的業務快速、便捷地實現 Serverless!

詳情可查閱:Serverless Framework 試用計劃

One More Thing

3 秒你能作什麼?喝一口水,看一封郵件,仍是 —— 部署一個完整的 Serverless 應用?

複製連接至 PC 瀏覽器訪問:https://serverless.cloud.tencent.com/deploy/express

3 秒極速部署,當即體驗史上最快的 Serverless HTTP 實戰開發!

傳送門:

歡迎訪問:Serverless 中文網,您能夠在 最佳實踐 裏體驗更多關於 Serverless 應用的開發!


推薦閱讀:《Serverless 架構:從原理、設計到項目實戰》

相關文章
相關標籤/搜索