您可以在Function Compute控制台建立並配置原生OSS觸發器,當在OSS上發生特定事件時會自動觸發函數執行。這可以讓您輕鬆響應如檔案上傳等事件,無需在代碼中增加監聽事件邏輯即可快速實現完整的流程。
樣本情境
您可以配置一個OSS觸發器,並將其檔案首碼設定為source
。當有圖片存入指定的OSS Bucket中的source
目錄下,會自動觸發函數執行。函數將圖片進行縮放處理後存放到同一個Bucket的processed
目錄下,即將source/a.png
處理為processed/a.png
。
前提條件
Function Compute
Object Storage ServiceOSS
使用限制
原生OSS觸發器,一個Bucket最多支援關聯10個觸發器。
說明如果您需要在一個Bucket內,關聯更多的OSS觸發器,可以選擇建立EventBridge類別的OSS觸發器。通常情況下,不推薦一個Bucket關聯10個以上的觸發器。如需建立,建議您建立新的Bucket,並基於新的Bucket建立觸發器。
原生OSS觸發器和EventBridge類別的OSS觸發器配置的檔案首碼和檔案尾碼都不支援模糊比對和正則匹配。如果想配置多個檔案首碼和檔案尾碼,可使用EventBridge類別的OSS觸發器。
步驟一:建立OSS觸發器
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數詳情頁面,選擇配置頁簽,在左側導覽列,單擊觸發器,然後單擊建立觸發器。
在建立觸發程序面板,填寫相關資訊,然後單擊確定。
配置項
操作
本文樣本
觸發器類型
選擇Object Storage Service。
Object Storage Service
名稱
填寫自訂的觸發器名稱。
oss-trigger
版本或別名
預設值為LATEST,如果您需要建立其他版本或別名的觸發器,需先在函數詳情頁的版本或別名下拉式清單選擇該版本。關於版本和別名的簡介,請參見版本管理和別名管理。
LATEST
Bucket 名稱
選擇已建立的OSS Bucket。
testbucket
檔案首碼
輸入要匹配的檔案名稱的首碼。建議您設定檔首碼和尾碼,避免觸發事件嵌套迴圈觸發引起額外費用。此外,一個Bucket的不同觸發器如果指定了相同的事件類型,則首碼和尾碼不能重複。詳細資料,請參見OSS觸發器觸發規則。
重要檔案首碼不能以
/
開頭,否則會導致OSS觸發器無法被觸發。source
檔案尾碼
輸入要匹配的檔案名稱的尾碼。強烈建議您配置首碼和尾碼,避免觸發事件嵌套迴圈觸發引起額外費用。另外,一個Bucket的不同觸發器如果指定了相同的事件類型,則首碼和尾碼不能重複。詳細資料,請參見OSS觸發器觸發規則。
png
觸發事件
選擇一個或多個觸發事件。關於Object Storage Service的事件類型,請參見OSS事件定義。
本樣本選擇oss:ObjectCreated:PutObject。
oss:ObjectCreated:PutObject
,oss:ObjectCreated:PostObject
,oss:ObjectCreated:CompleteMultipartUpload
角色名稱
選擇AliyunOSSEventNotificationRole。
說明如果您第一次建立該類型的觸發器,則需要在單擊確定後,在彈出的對話方塊中選擇立即授權。
AliyunOSSEventNotificationRole
建立完成後,在觸發器名稱列表中顯示已建立的觸發器。如需對建立的觸發器進行修改或刪除,具體操作,請參見觸發器管理。
步驟二:配置函數入口參數
OSS事件來源會以event的形式作為輸入參數傳遞給函數,您可以手動將event傳給函數類比觸發事件。
在函數詳情頁面的代碼頁簽,單擊測試函數右側的表徵圖,從下拉式清單中,選擇配置測試參數。
在配置測試參數面板,選擇建立新測試事件或編輯已有測試事件,填寫事件名稱和事件內容,然後單擊確定。
說明event內容請根據建立觸發器時的資訊進行配置,同時需要確保配置的Bucket中存在指定的檔案(本文樣本中是
source/a.png
檔案),否則會無法觸發函數執行,或者函數執行會失敗。event是Function Compute的入口參數,當指定的OSS Bucket發生對象建立或對象刪除事件時,會將事件數目據以JSON格式發送給綁定的函數。具體格式如下所示。
{ "events": [ { "eventName": "ObjectCreated:PutObject", "eventSource": "acs:oss", "eventTime": "2022-08-13T06:45:43.000Z", "eventVersion": "1.0", "oss": { "bucket": { "arn": "acs:oss:cn-hangzhou:123456789:testbucket", "name": "testbucket", "ownerIdentity": "164901546557****" }, "object": { "deltaSize": 122539, "eTag": "688A7BF4F233DC9C88A80BF985AB****", "key": "source/a.png", "size": 122539 }, "ossSchemaVersion": "1.0", "ruleId": "9adac8e253828f4f7c0466d941fa3db81161****" }, "region": "cn-hangzhou", "requestParameters": { "sourceIPAddress": "140.205.XX.XX" }, "responseElements": { "requestId": "58F9FF2D3DF792092E12044C" }, "userIdentity": { "principalId": "164901546557****" } } ] }
event參數中不同屬性欄位的解釋如下表所示。
參數
類型
樣本值
描述
eventName
String
ObjectCreated:PutObject
事件類型。
eventSource
String
acs:oss
事件來源,固定為
acs:oss
。eventTime
String
2022-08-13T06:45:43.000Z
事件產生的時間。使用ISO-8601標準時間格式。
eventVersion
String
1.0
事件協議的版本。
oss
Map
OSS事件內容。
bucket
Map
bucket參數內容。
name
String
testbucket
Bucket的名稱。
arn
String
acs:oss:cn-hangzhou:123456789:testbucket
Bucket的唯一識別碼。
ownerIdentity
String
164901546557****
建立Bucket的使用者ID。
object
Map
object參數內容。
size
Int
122539
object的大小。單位:Byte。
deltaSize
Int
122539
object的大小變化量。單位:Byte。
如果新增一個檔案,此參數的值表示檔案大小。
如果同名覆蓋一個檔案,此參數的值表示新檔案與舊檔案的大小差值。
eTag
String
688A7BF4F233DC9C88A80BF985AB****
Object的標籤。
key
String
source/a.png
Object的名稱。
ossSchemaVersion
String
1.0
OSS模式的版本號碼。
ruleId
String
9adac8e253828f4f7c0466d941fa3db81161****
事件匹配的規則ID。
region
String
cn-hangzhou
Bucket所在的地區。
requestParameters
Map
請求參數。
sourceIPAddress
String
140.205.XX.XX
請求的源IP地址。
responseElements
Map
響應元素。
requestId
String
58F9FF2D3DF792092E12044C
請求對應的Request ID。
userIdentity
Map
使用者屬性。
principalId
String
164901546557****
請求發起者的阿里雲帳號ID。
步驟三:編寫函數代碼並測試
OSS觸發器建立完成後,您可以開始編寫函數代碼並測試,以驗證代碼的正確性。在實際操作過程中,發生OSS事件時,函數會自動被觸發執行。
代碼中一定要避免迴圈觸發。一個典型的迴圈觸發情境是OSS的某個Bucket上傳檔案事件觸發函數執行,此函數執行完成後又產生了一個或多個檔案再寫回到OSS的Bucket裡,這個寫入動作又觸發了函數執行,形成了鏈狀迴圈。更多資訊,請參見OSS觸發器觸發規則。
在函數詳情頁面的代碼頁簽,在代碼編輯器中編寫代碼,然後單擊部署代碼。
支援線上編輯代碼的運行環境的範例程式碼如下。
說明如果您要在您的函數中讀寫OSS資源,建議使用OSS內網服務地址進行訪問,避免使用公網訪問,產生公網費用。關於OSS內網服務地址的格式,請參見訪問網域名稱和資料中心。
"use strict"; /* 本代碼範例主要實現以下功能: * 1. 從event中解析出OSS事件觸發相關資訊。 * 2. 根據以上擷取的資訊,初始化OSS用戶端。 * 3. 將源圖片resize後持久化到OSS bucket下指定的靶心圖表片路徑,從而實現圖片備份。 This code sample mainly implements the following functions: * 1. Parse the OSS event trigger related information from the event. * 2. According to the above information, initialize the OSS client. * 3. Resize the source image and then store the processed image into the same bucket's copy folder to backup the image. */ const OSS = require("ali-oss"); exports.handler = async function(event, context, callback) { console.log("The content in context entity is: \n"); console.dir(context); const {accessKeyId, accessKeySecret, securityToken} = context.credentials; const events = JSON.parse(event.toString()).events; console.log("The content in event entity is: \n"); console.dir(events); let objectName = events[0].oss.object.key; let region = events[0].region; let bucketName = events[0].oss.bucket.name; // 串連目標OSS。 // Connect to the target OSS const client = new OSS({ region: region, accessKeyId: accessKeyId, accessKeySecret: accessKeySecret, stsToken: securityToken, bucket: bucketName, endpoint: "https://oss-" + region + "-internal.aliyuncs.com" }); console.log("The client entity is: \n"); console.dir(events); const targetImage = objectName.replace("source/", "processed/") // 將圖片縮放為固定寬高128 px。 const processStr = "image/resize,m_fixed,w_128,h_128" // 將源圖片resize後再儲存到靶心圖表片路徑。 const result = await client.processObjectSave( objectName, targetImage, processStr, bucketName ); console.log(result.res.status); callback(null, "done"); }
""" 本代碼範例主要實現以下功能: * 從event中解析出OSS事件觸發相關資訊。 * 根據以上擷取的資訊,初始化OSS bucket用戶端。 * 將源圖片resize後持久化到OSS bucket下指定的靶心圖表片路徑,從而實現圖片備份。 This sample code is mainly doing the following things: * Get OSS processing related information from event. * Initiate OSS client with target bucket. * Resize the source image and then store the processed image into the same bucket's copy folder to backup the image. """ # -*- coding: utf-8 -*- import oss2, json import base64 def handler(event, context): # 可以通過context.credentials擷取密鑰資訊。 # Access keys can be fetched through context.credentials print("The content in context entity is: \n") print(context) creds = context.credentials # 設定權鑒,供OSS sdk使用。 # Setup auth, required by OSS sdk. auth = oss2.StsAuth( creds.access_key_id, creds.access_key_secret, creds.security_token) print("The content in event entity is: \n") print(event) # Load event content. oss_raw_data = json.loads(event) # Get oss event related parameters passed by oss trigger. oss_info_map = oss_raw_data['events'][0]['oss'] # Get oss bucket name. bucket_name = oss_info_map['bucket']['name'] # Set oss service endpoint. endpoint = 'oss-' + oss_raw_data['events'][0]['region'] + '-internal.aliyuncs.com' # Initiate oss client. bucket = oss2.Bucket(auth, endpoint, bucket_name) object_name = oss_info_map['object']['key'] # Download original image from oss bucket. remote_stream = bucket.get_object(object_name) if not remote_stream: print(f'{object_name} does not exist in bucket {bucket_name}') return # Processed images will be saved to processed/ processed_path = object_name.replace('source/', 'processed/') # 將圖片縮放為固定寬高128 px。 style = 'image/resize,m_fixed,w_128,h_128' # 指定處理後圖片名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整訪問路徑,例如exampledir/example.jpg。 process = "{0}|sys/saveas,o_{1},b_{2}".format(style, oss2.compat.to_string(base64.urlsafe_b64encode(oss2.compat.to_bytes(processed_path))), oss2.compat.to_string(base64.urlsafe_b64encode(oss2.compat.to_bytes(bucket_name)))) result = bucket.process_object(object_name, process) print(result)
/*本代碼範例主要實現以下功能: * 1. 從request中解析出 endpoint,bucket,object。 * 2. 根據以上擷取的資訊,初始化OSS用戶端。 * 3. 將源圖片resize後持久化到OSS bucket下指定的靶心圖表片路徑,從而實現圖片備份。 * *This code sample mainly implements the following functions: * 1. Parse out endpoint, bucket, object from request. * 2. According to the information obtained above, initialize the OSS client. * 3. Resize the source image and then store the processed image into the same bucket's copy folder to backup the image. */ <?php use RingCentral\Psr7\Response; use OSS\OssClient; use OSS\Core\OssException; function base64url_encode($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } function handler($event, $context) { $event = json_decode($event, $assoc = true); /* 阿里雲帳號AccessKey擁有所有API的存取權限,建議您使用RAM使用者進行API訪問或日常營運。 建議不要把AccessKey ID和AccessKey Secret儲存到工程代碼裡,否則可能導致AccessKey泄露,威脅您帳號下所有資源的安全。 本樣本以從上下文中擷取AccessKey/AccessSecretKey為例。 */ $accessKeyId = $context["credentials"]["accessKeyId"]; $accessKeySecret = $context["credentials"]["accessKeySecret"]; $securityToken = $context["credentials"]["securityToken"]; $evt = $event['events']{0}; $bucketName = $evt['oss']['bucket']['name']; $endpoint = 'oss-' . $evt['region'] . '-internal.aliyuncs.com'; $objectName = $evt['oss']['object']['key']; $targetObject = str_replace("source/", "processed/", $objectName); try { // 串連OSS。 // Connect to OSS. $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken); // 將圖片縮放為固定寬高128px。 $style = "image/resize,m_fixed,w_128,h_128"; $process = $style. '|sys/saveas'. ',o_'.base64url_encode($targetObject). ',b_'.base64url_encode($bucketName); // 將圖片 Resize 後儲存到目標檔案中。 $result = $ossClient->processObject($bucketName, $objectName, $process); // 列印處理結果。 print($result); } catch (OssException $e) { print_r(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); } print(__FUNCTION__ . ": OK" . "\n"); return $targetObject; }
單擊測試函數。
執行完成後,您可以在代碼頁簽的上方查看執行結果。
常見問題
相關文檔
如果您想瞭解可以配置的OSS事件類型,請參見OSS事件定義。
如果您需要對建立的觸發器進行修改或刪除,具體操作請參見更新觸發器配置。
如果您需要在一個Bucket內關聯10個以上的OSS觸發器,請參見配置EventBridge類別的OSS觸發器。
觸發器相關問題
如果您希望查看函數的執行觸發了哪個事件,可以手動在代碼邏輯中列印事件類型日誌,具體請參見日誌記錄。
如果您希望在函數中調用另一個函數,可以使用API調用指定函數或使用函數工作流程編排函數。如果調用的函數需要執行耗時操作且均為非同步呼叫,可以配置非同步呼叫目標服務。具體請參見函數可以相互調用嗎?和配置非同步呼叫目標服務。