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


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

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

效果展示

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

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

雲函數被多次連續調用(熱啟動)

雲函數被多次連續調用(熱啟動)

雲函數的冷、熱啟動模式

先跟大家講下這里的雲函數冷熱啟動模式是什么意思。

  • 冷啟動是指你在服務器中新開辟一塊空間供一個函數實例運行,這個過程有點像你把這個函數放到虛擬機里去運行,每次運行前都要先啟動虛擬機加載這個函數,這是比較耗時的一個過程,所以雲函數需要盡量減少自身冷啟動的次數。
  • 熱啟動則是說如果一個雲函數被持續觸發,那我就先不釋放這個雲函數實例,下次請求仍然由之前已經創建了的雲函數實例來運行,就好比我們打開虛擬機運行完這個函數之后沒有關閉虛擬機,而是讓它待機,等待下一次被重新觸發調用運行,這樣做的好處就是省去了給虛擬機「開機」的一個耗時環節,缺點是要一直維持這個虛擬機的激活狀態,系統開銷會大一些。

當然這里的雲函數資源分配的問題並不需要我們操心,雲函數的底層會通過算法自行調配。

在騰訊雲雲函數文檔里的簡介 里有這么一段描述:

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

大家注意這一句

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

可以看到雲函數的函數實例個數在系統底層是通過算法自行伸縮的,

我們再往下看

在 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 架構:從原理、設計到項目實戰》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM