對象存儲與函數計算集成后,對象存儲事件能觸發相關函數執行,實現對對象存儲中的數據的自定義處理。
背景信息
對象存儲和函數計算通過對象存儲觸發器實現無縫集成,可以編寫函數對對象存儲事件進行自定義處理,當對象存儲捕獲到指定類型的事件后,對象存儲事件觸發相應的函數執行。例如,可以設置函數來處理PutObject事件,當上傳圖片到對象存儲后,相關聯的函數會自動被觸發來處理該圖片。
對象存儲和函數計算集成后,可以自由地調用各種函數處理圖像或音頻數據,再把結果寫回到多種存儲服務中。整個架構中,只需要專注于函數邏輯的編寫,系統將以實時的、可靠的、大規模并行的方式處理海量的數據。
對象存儲事件定義
當對象存儲系統捕獲到相關事件后,會將事件信息編碼為JSON字符串,傳遞給事件處理函數。
已支持的對象存儲事件定義如下表所示。
| 事件類型 | 說明 |
|---|---|
| s3:ObjectCreated:Put | 原子上傳對象到Bucket。 |
| s3:ObjectCreated:Post | Post上傳對象到Bucket。 |
| s3:ObjectCreated:CompleteMultipartUpload | 分段上傳對象到Bucket。 |
| s3:ObjectCreated:Copy | 拷貝上傳。 |
| s3:ObjectRemoved:Delete | 刪除Bucket中對象。 |
| s3:ObjectRemoved:DeleteMarkerCreated | 不指定版本號刪除多版本Bucket中對象。 |
| s3:ObjectRestore:Post | 對象解凍。 |
觸發器觸發規則
避免循環觸發
使用對象存儲觸發器時,請注意避免循環觸發。例如,一個典型的循環觸發場景是對象存儲的某個bucket上傳文件事件觸發函數執行,此函數執行完成后又生成了一個或多個文件再寫回到對象存儲的bucket里,這個寫入動作又觸發了函數執行,形成了鏈狀循環。
為了避免循環觸發函數產生不必要的費用,建議配置文件前綴或文件后綴,例如將觸發函數的文件的文件前綴設置為 src,函數執行完成后生成文件的文件前綴設置為 dst,生成的文件將不會再次觸發函數。如果不設置文件前綴和文件后綴,表示匹配任意文件前綴和文件后綴。
配置對象存儲觸發器
創建觸發器
- 登錄,在左側導航欄,單擊函數。
- 在頂部菜單欄,選擇地域,然后在函數頁面,單擊目標函數。
- 在函數配置頁面,選擇配置頁簽,在左側導航欄,單擊觸發器,然后單擊創建觸發器。
- 在創建觸發器面板,填寫相關信息,然后單擊確定。
配置項說明如下。
| 配置項 | 操作 | 示例 |
|---|---|---|
| 觸發器類型 | 選擇對象存儲觸發器。 | 對象存儲觸發器 |
| 名稱 | 填寫自定義的觸發器名稱。 | zos-trigger |
| 版本或別名 | 默認值為LATEST。 | LATEST |
| Bucket 名稱 | 選擇已創建的對象存儲Bucket。 | testbucket |
| 文件前綴 | 輸入要匹配的文件名稱的前綴。建議配置文件前綴和后綴,避免觸發事件嵌套循環觸發引起額外費用。 | source |
| 文件后綴 | 輸入要匹配的文件名稱的后綴。強烈建議配置前綴和后綴,避免觸發事件嵌套循環觸發引起額外費用。 | png |
| 事件類型 | 選擇一個或多個觸發事件。關于對象存儲ZOS的事件類型,請參見對象存儲事件定義。 | s3:ObjectCreated:Put,s3:ObjectCreated:Post,s3:ObjectCreated:CompleteMultipartUpload |
| 調用方式 | 選擇函數調用方式,默認為同步調用。 同步調用:事件觸發函數執行,等待函數調用完成后,函數計算返回執行結果。 異步調用:事件觸發函數執行后,函數計算立即返回響應結果并且確保函數至少被成功執行一次,但不會返回具體執行結果。適用于調度延時較長的函數。 |
同步調用 |
開通事件上報
并非所有Bucket都會主動上報事件,需要通過對象存儲產品的Openapi打開指定Bucket的事件上報,方法步驟如下:
-
Python調用openapi示例
-
結合上述示例,執行如下代碼,打開指定存儲桶的事件上報開關
def main(): params = { "regionID": "bb9fdb42056f11eda1610242ac110002", # 華東1地域ID "bucket": "您的桶名稱", "bucketEventBridgeEnabled": True } result=post("//zos-global.ctapi.daliqc.cn/v4/oss/put-bucket-event-bridge","", params) print(result) if __name__ == "__main__": main() -
接口返回以下內容即可
{"message": "SUCCESS", "description": "成功", "statusCode": 800}
配置函數入口參數
對象存儲觸發器事件源會以CloudEvents模板作為輸入參數傳遞給函數,可以手動將Event傳給函數模擬觸發事件。
Event是函數計算的入口參數,當指定的對象存儲Bucket發生指定事件時,會將事件數據以JSON格式發送給綁定的函數。具體格式如下所示。
{
"id": "1723530386.250878.3f7f5c***",
"source": "ctyun.zos",
"specversion": "1.0",
"type": "s3:ObjectCreated:Post",
"subject": "ctyun.zos:b342b77ef26b11e***:5d4ce56a08db4a***:bucket-***:abc.txt",
"time": "2024-03-05T13:52:18.374Z",
"data": {
"userIdentity": {
"principalId": "testuser_sub1"
},
"responseElements": {
"x-amz-request-id": "ec2906f5-e72t-494f-9aa1-f621108***",
"x-amz-id-2": "1286b9-zone2-zon***"
},
"s3": {
"bucket": {
"name": "bucket-***",
"ownerIdentity": {
"principalId": "testuser"
},
"arn": "arn:aws:s3:::bucket-***",
"id": "ec2906f5-e72f-494f-9aa1-f6211***"
},
"object": {
"key": "abc.txt",
"size": 417791,
"etag": "3f7f 5c925b10c789e3e1389***",
"versionId": "",
"sequencer": "92FCBA66FA6***",
"metadata": []
}
}
},
"datacontenttype": "application/json;charset=utf-8",
"ctyunaccountid": "5d4ce56a08db4ac19***",
"ctyunuserid": "usertest-userid",
"ctyunresourceid": "",
"ctyuneventbusname": "default",
"ctyunregion": "b342b77ef26b11ecb0***"
}
Event參數中不同屬性字段的解釋如下表所示。
| 參數 | 類型 | 示例值 | 描述 |
|---|---|---|---|
| id | String | b5771f76-6cdf-48ed-b1ba-d15418c***** | 事件ID。標識事件的唯一值。 |
| source | String | ctyun.zos | 事件源。對象存儲觸發器固定為ctyun.zos。 |
| specversion | String | 1.0 | CloudEvents協議版本。 |
| type | String | s3:ObjectCreated:Post | 事件類型。 |
| subject | String | ctyun.zos:b342b77ef26***:5d4ce56a08d***:bucketname***:objectname*** | 事件主體。格式為ctyun.zos::::,其中是資源池ID,是天翼云賬號ID,是對象存儲產生事件的bucket名稱,是對象存儲產生事件的文件名稱。 |
| time | Timestamp | 2024-03-05T13:52:18.374Z | 事件產生的時間。 |
| datacontenttype | String | application/json;charset=utf-8 | 參數data的內容形式。 |
| data | Struct | {"abc":"1111", "def":"xxxx"} | 事件內容。JSON對象,內容由發起事件的服務決定。CloudEvents可能包含事件發生時由事件生產者給定的上下文,data中封裝了這些信息。 |
| ctyunaccountid | String | 123456789**** | 天翼云賬號ID。 |
| ctyunuserid | String | 123456789**** | 天翼云用戶ID。 |
| ctyunresourceid | String | 27aadda4-db94-11ee-a6fc-e8b47009**** | 天翼云資源ID |
| ctyuneventbusname | String | default | 接收事件的事件總線名稱,天翼云產品事件為default。 |
| ctyunregion | String | bb9fdb42056fl1eda161**** | 接收事件的地域。 |
編寫函數代碼并測試
對象存儲觸發器創建完成后,可以開始編寫函數代碼并測試,以驗證代碼的正確性。在實際操作過程中發生對象存儲事件時,會自動觸發函數執行。
代碼中一定要避免循環觸發,否則會產生不必要的費用。一個典型的循環觸發場景是對象存儲的某個bucket上傳文件事件觸發函數執行,此函數執行完成后又生成了一個或多個文件再寫回到對象存儲的bucket里,這個寫入動作又觸發了函數執行,形成了鏈狀循環。
Python代碼示例:
# -*- coding: utf-8 -*-
import json
import logging
def handler(event, context):
logger = logging.getLogger()
logger.info("print event payload:")
if event: # 檢查是否為空
try:
json_data = json.loads(event)
logger.info(json.dumps(json_data, indent=4))
except json.JSONDecodeError as e:
logger.info(
"Event is not of JSON type, print raw event data: %s", event)
else:
logger.info("event is empty")
# 測試 CloudEvents 支持(CloudEvents 相關參數編碼在 headers 中)
logger.info("print headers:")
headers_map = context.headersMap # 遵循PEP 8命名規范
logger.info(json.dumps(headers_map, indent=4))
return 'hello world\n'