執行個體並發度指定了每個函數執行個體可以同時處理的最大並發請求數。通過在Function Compute中設定執行個體並發度,您可以在流量高峰期有效管理資源使用,降低冷啟動影響,從而達到提升效能和控製成本的目的。
背景資訊
Function Compute按執行個體規格乘以執行時間長度來計量資源使用量,從而得到資源使用的總費用,因此,函數執行時間長度越長,相應的使用成本越高。
假設同時有3個請求需要處理,每個請求需要10秒,並發度不同執行時間長度也不同。
當執行個體並發度設定為1時,每個執行個體同時只能處理1個請求,Function Compute需要建立3個執行個體來處理這3個請求,總的執行時間長度是30秒。
當執行個體並發度設定為10時,如果不超過單個執行個體最大能承受的QPS範圍,理論上每個執行個體同時可以處理10個請求,Function Compute只需要建立1個執行個體就能處理這3個請求,總的執行時間長度是10秒。
函數執行個體並發度為1時,一個執行個體同時只會處理一個請求。當您設定單一實例並發度大於1後,Function Compute在Auto Scaling時,充分利用完一個執行個體的並發度後才會建立新的執行個體。
函數執行個體並發度通常要和執行個體規格同時進行評估,能更好地最佳化函數的效能和成本。您可以使用函數效能探測功能,得到最佳執行個體規格和並發度值。
執行個體並發度設定為不同的值時,請求執行的區別如下圖所示。
功能優勢
減少執行時間長度,節省費用。
例如,偏I/O的函數可以在一個執行個體內並發處理,減少執行個體數從而減少總的執行時間長度。
請求之間狀態可共用。
多個請求可以在一個執行個體內共用資料庫連接池,從而減少和資料庫之間的串連數。
降低冷啟動機率。
由於多個請求可以在一個執行個體內處理,建立新執行個體的次數會變少,冷啟動機率降低。
減少VPC IP地址的佔用。
在相同負載下,單一實例多並發可以降低總的執行個體數,從而減少VPC IP地址的佔用。
重要您的VPC綁定的vSwitch中至少需要兩個可用的IP地址,否則可能會導致服務不可用造成請求失敗。
應用情境
單一實例多並發功能適用於函數中有較多時間在等待下遊服務響應的情境。等待響應一般不消耗資源,在一個執行個體內並發處理,不僅可以節省費用,還能提高應用響應能力和輸送量。
使用限制
限制項 | 描述 |
支援的運行環境 |
|
單一實例並發度取值範圍 | 1~200 |
調用響應中的函數日誌(X-Fc-Log-Result) | 執行個體並發數>1時不支援 |
操作步驟
您可以在建立函數時,指定函數的單一實例並發度。
函數建立完成後,您可以在函數詳情頁簽,選擇配置頁簽,選擇運行時,單擊編輯,修改函數的單一實例並發度。
如果您使用了預留模式,預留模式下的函數也可以並發處理多個請求。更多資訊,請參見配置預留執行個體。
設定單一實例多並發的影響
設定了單一實例多並發(執行個體並發數>1)之後,與單一實例單並發(執行個體並發數=1)在以下幾個方面有區別。
計費
單一實例單並發與單一實例多並發在執行時間長度上會不同,從而費用也不同。更多計費詳情,請參見計費概述。
單一實例單並發
函數執行個體在同一時間只能處理1個請求,1個請求處理完了再處理下一個請求。計費時間長度從處理第一個請求開始,到最後一個請求結束為止。
單一實例多並發
多個請求在一個執行個體並發處理時,以執行個體的實際佔用時間作為計費的執行時間長度,即從第一個請求開始,到最後一個請求結束期間的時間長度。
並發度流控
Function Compute在一個地區中按量執行個體數的上限預設值為100,一個地區可以同時處理的最大請求數為“100×執行個體並發數”。例如,設定執行個體並發數=10時,則一個地區最多允許同時處理1000個並發請求。當並發請求數超過Function Compute可以處理的最大請求數時,會收到流控錯誤提示ResourceExhausted。
如您需要擴大某個地區的按量執行個體數上限,請聯絡我們。
日誌
在單併發模式下,在調用函數時指定HTTP頭
X-Fc-Log-Type: Tail
,Function Compute會在回應標頭X-Fc-Log-Result
中包含本次調用所產生的函數日誌。在多併發模式下,由於多個請求並發執行,無法擷取某個特定請求的日誌,回應標頭中不再包含本次調用的函數日誌。針對Node.js Runtime,原來的日誌方式是使用
console.info()
函數,該方式會把當前請求的Request ID包含在日誌內容中。當多請求在同一個執行個體並發處理時,當前請求可能有很多個,繼續使用console.info()
列印日誌會導致Request ID錯亂,Request ID都會變成req 2
。列印日誌樣本如下。2019-11-06T14:23:37.587Z req1 [info] logger begin 2019-11-06T14:23:37.587Z req1 [info] ctxlogger begin 2019-11-06T14:23:37.587Z req2 [info] logger begin 2019-11-06T14:23:37.587Z req2 [info] ctxlogger begin 2019-11-06T14:23:40.587Z req1 [info] ctxlogger end 2019-11-06T14:23:40.587Z req2 [info] ctxlogger end 2019-11-06T14:23:37.587Z req2 [info] logger end 2019-11-06T14:23:37.587Z req2 [info] logger end
此時應該使用
context.logger.info()
函數列印日誌,該方式仍保留了請求的獨立Request ID。程式碼範例如下。exports.handler = (event, context, callback) => { console.info('logger begin'); context.logger.info('ctxlogger begin'); setTimeout(function() { context.logger.info('ctxlogger end'); console.info('logger end'); callback(null, 'hello world'); }, 3000); };
錯誤處理
多個請求在一個執行個體並發處理時,由於一個請求處理不當導致進程退出或者崩潰,會導致正在並發處理的其他請求也收到錯誤資訊。這要求您在編寫函數時,盡量捕獲請求層級的異常,不影響其他請求。Node.js程式碼範例如下。
exports.handler = (event, context, callback) => {
try {
JSON.parse(event);
} catch (ex) {
callback(ex);
}
callback(null, 'hello world');
};
共用變數
多個請求在一個執行個體並發處理時,同時修改一個共用的變數,可能會導致錯誤。這要求您在編寫函數時,對於非安全執行緒的變數修改要進行互斥保護。Java程式碼範例如下。
public class App implements StreamRequestHandler
{
private static int counter = 0;
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
synchronized (this) {
counter = counter + 1;
}
outputStream.write(new String("hello world").getBytes());
}
}
監控指標
設定函數的執行個體並發度後,在相同的負載下,可以在控制台的函數按量執行個體數監控圖中看到函數已使用的執行個體數明顯地減少。