~ 靈異體附身 ~
相關程式碼:https://github.com/slindevel/modern-aws-marathon
AWS Lambda Function運行在一個被稱為執行環境(execution environment)的受隔離環境中。這使它們與其他Lambda Function隔離開來,並提供了在函數配置中指定的資源,例如記憶體。
AWS Lambda Service會自動管理計算使用Lambda Function資源的生命週期,以便讓您僅支付實際使用的部分。在函數調用之間,AWS Lambda Service會凍結執行環境。如果 AWS Lambda Service需要執行環境來進行後續的調用,它會解凍執行環境。
以前,只有運行時程序能夠影響執行環境的生命週期。它會與Runtime API 進行通信,該 API 在執行環境中提供了一個 HTTP API 端點(HTTP API endpoing),用於與 Lambda 服務進行通信。
運行時(runtime) 使用API從Lambda請求調用事件並將其傳遞給函數代碼。然後,它在完成處理事件時通知Lambda服務。Lambda服務隨後凍結執行環境。
運行時進程以前公開了Lambda執行環境的兩個不同階段:初始化(Init)和調用(Invoke)。
初始化(Init):在初始化階段期間,Lambda服務初始化運行時,然後運行函數的初始化代碼(即主處理程序之外的代碼)。初始化階段在第一次調用時發生,或者如果啟用了預配置並發性能(Provisioned Concurrency),則提前進行。
調用(Invoke):在調用階段期間,運行時通過運行時API向Lambda服務請求調用事件,並調用函數處理程序。然後,它將函數響應返回給運行時API。
函數運行後,Lambda服務凍結執行環境並保持一段時間,以預測是否會有另一個函數調用。
如果Lambda函數在一段時間內未收到任何調用,Lambda服務將關閉並刪除該環境。
Lambda Extensions在Lambda Function運行初始化之前進行初始化。它們在函數執行期間與函數並行運行,並在關閉期間可以執行邏輯。
Lambda Extension通過對Lambda生命週期進行以下更改,實現與Lambda服務的整合:
extension在function執行期間可以與Lambda Service進行更緊密的集成,並具有更大的控制權以滿足特定的需求。
您可以將external extension部署為 Lambda Layer,這些層是包含共享庫或其他依賴項的.zip存檔,或者將它們包含在以容器映像方式部署的function的映像中。
要新增Lambda Layer,可以使用AWS管理控制台、AWS命令行界面 (AWS CLI) 或基礎設施即代碼工具 (如AWS CloudFormation、 AWS Serverless Application Model(AWS SAM) 和 Terraform)。
當Lambda服務為.zip存檔函數啟動函數執行環境時,它會從Lambda層中提取extension檔案並將其放在/opt目錄下。對於容器映像function,extension檔案將作為容器映像的一部分打包到/opt目錄下。然後,Lambda會查找/opt/extensions目錄中的任何可執行程序並開始執行它們。extension需要作為二進制文件或腳本可執行。由於函數代碼目錄是只讀的,extension不能修改函數代碼。
放到Lambda Layer的extension zip檔案內容如下(以”extension.zip"為例子)
├── marathon-lambda-extension-project (隨意名稱,沒用到)
├── extensions (固定名稱)
| └── logs_api_http_extension
| └── __init__.py
| └── extensions_api_client.py
| └── http_listener.py
| └── logs_api_client.py
└── marathon-lambda-extension.py (與Lambda Layers Layer Name一致)
部署 extension 到 Day7 建立的 lambda function:(注意最後 layer-arn 參數要帶版號)
# in Day15/
$ cd marathon-lambda-extension-project
# step 1 - make marathon-lambda-extension.py executable
$ chmod +x extensions/marathon-lambda-extension.py
# step 2 - zip
$ zip -r extension.zip ./extensions
# step 3 - deploy to lambda layers
$ aws lambda publish-layer-version \
--layer-name "marathon-lambda-extension" \
--zip-file "fileb://extension.zip"
{
"Content": {
...
},
"LayerArn": "arn:aws:lambda:ap-northeast-1:<account_id>:layer:marathon-lambda-extension",
"LayerVersionArn": "arn:aws:lambda:ap-northeast-1:<account_id>:layer:marathon-lambda-extension:1",
"Description": "",
"CreatedDate": "2023-09-18T16:03:08.052+0000",
"Version": 1
}
# step 4 - attach layer to lambda function
$ aws lambda update-function-configuration \
--function-name marathon-function \
--layers <layer-arn-with-version>
開新 terminal 使用指令,記得要切換到正確的 AWS Profile
$ export AWS_PROFILE=<your_profile>
# check user
$ aws iam get-user
$ aws logs tail /aws/lambda/marathon-function --follow
回到原本的 terminal,invoke 剛剛 attach 的 lambda
$ aws lambda invoke --function-name marathon-function out.log --log-type Tail
可以看到 aws logs 指令的那個 teminal 顯示以下訊息(在接收 request 之前):
Starting Extensions {'events': ['INVOKE', 'SHUTDOWN']} {'destination': {'protocol': 'HTTP', 'URI': 'http://sandbox:4243'}, 'types': ['platform', 'function'], 'buffering': {'timeoutMs': 1000, 'maxBytes': 262144, 'maxItems': 10000}}
Initializing LogsAPIExternalExtension marathon-lambda-extension.py
Registering to ExtensionsAPIClient on http://127.0.0.1:9001/2020-01-01/extension
Initializing HTTP Server on sandbox:4243
Subscribing to Logs API on http://127.0.0.1:9001/2020-08-15
Serving HTTP Server on sandbox:4243
LOGS Name: marathon-lambda-extension.py State: Subscribed Types: [Platform, Function]
Successfully subscribed to Logs API: b'"OK"'
Serving LogsAPIHTTPExternalExtension marathon-lambda-extension.py
EXTENSION Name: marathon-lambda-extension.py State: Ready Events: [INVOKE, SHUTDOWN]
extensions_api_client.py:
register: 使用Restful POST 向Extension API註冊,使其可以收到關於Runtime時INVOKE, SHUTDOWN的訊息
next: 讀取下一個進來的訊息
register payload如下:
{"events":["INVOKE","SHUTDOWN"]}
marathon-lambda-extension.py 執行步驟解說:
Lambda externel extension 給了我們多一點額外資源可以搜集一些 init/terminate stage 方面的資訊,一般來說第三方的監控軟體都是利用此功能來實作對 AWS Lambda 的監控的
最後,如果是使用 docker image 部署的話,只要把 extension.zip 的內容放到 image 的 /opt/ 目錄下即可(ex. /opt/marathon-lambda-extension.py ...)
https://github.com/aws-samples/aws-lambda-extension
https://docs.aws.amazon.com/lambda/latest/dg/lambda-extensions.html
https://aws.amazon.com/tw/blogs/compute/introducing-aws-lambda-extensions-in-preview/
https://aws.amazon.com/tw/blogs/compute/building-extensions-for-aws-lambda-in-preview/