本文介紹執行個體並發的背景資訊、應用情境、優勢和使用限制,以及如何在Function Compute控制台設定執行個體並發度。
背景資訊
Function Compute按執行個體佔用時間長度計費。假設訪問資料庫需要10秒,那麼當並發的3個請求分別在3個執行個體內被處理後,3個執行個體總的執行時間長度是30秒。如果能讓這3個請求在同一個執行個體內並發處理,這樣執行個體的佔用時間為10秒。為了協助您節省執行個體資源費用,Function Compute支援單一實例多並發功能,允許您為函數設定執行個體並發度InstanceConcurrency,即單個函數執行個體可以同時處理多個請求。單一實例並發和多執行個體並發的區別如下圖所示。
假設同時有3個請求需要處理:
當執行個體並發度設定為1時,每個執行個體同時只能處理1個請求,Function Compute需要建立3個執行個體來處理這3個請求。
當執行個體並發度設定為10時,每個執行個體同時可以處理10個請求,Function Compute只需要建立1個執行個體就能處理這3個請求。
預設情況下,函數的執行個體並發度為1,也就是一個執行個體同時只會處理一個請求。當您設定單一實例並發度大於1後,Function Compute在Auto Scaling時,充分利用完一個執行個體的並發度後才會建立新的執行個體。
應用情境
單一實例多並發功能適用於函數中有較多時間在等待下遊服務響應的情境。等待響應一般不消耗資源,在一個執行個體內並發處理可以節省費用。
優勢
減少執行時間長度,節省費用。
例如,偏I/O的函數可以在一個執行個體內並發處理,減少執行個體數從而減少總的執行時間長度。
請求之間狀態可共用。
多個請求可以在一個執行個體內共用資料庫連接池,從而減少和資料庫之間的串連數。
降低冷啟動機率。
由於多個請求可以在一個執行個體內處理,建立新執行個體的次數會變少,冷啟動機率降低。
減少VPC IP地址的佔用。
在相同負載下,單一實例多並發可以降低總的執行個體數,從而減少VPC IP地址的佔用。
重要您的VPC綁定的vSwitch中至少需要兩個可用的IP地址,否則可能會導致服務不可用造成請求失敗。
設定單一實例多並發的影響
設定了單一實例多並發(InstanceConcurrency>1)之後,與單一實例單並發(InstanceConcurrency=1)有以下幾個方面的區別:
計費
單一實例單並發
函數執行個體在同一時間只能處理1個請求,1個請求處理完了再處理下一個請求。計費時間長度從處理第一個請求開始,到最後一個請求結束為止。
單一實例多並發
多個請求在一個執行個體並發處理時,以執行個體的實際佔用時間作為計費的執行時間長度,即從第一個請求開始,到最後一個請求結束期間的時間長度。
更多計費詳情,請參見計費概述。
並發度流控
Function Compute在一個地區中按量執行個體數的上限預設值為100,一個地區可以同時處理的最大請求數為“100×InstanceConcurrency”。例如,設定InstanceConcurrency=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());
}
}
監控指標
設定函數的執行個體並發度後,在相同的負載下,可以在控制台的函數按量執行個體數監控圖中看到函數已使用的執行個體數明顯地減少。
使用限制
限制項 | 描述 |
支援的Runtime |
|
單一實例並發度取值範圍 | 1~200 |
調用響應中的函數日誌(X-Fc-Log-Result) | InstanceConcurrency>1時不支援 |
為函數設定單一實例並發度
您可以在建立或更新函數時,指定函數的單一實例並發度InstanceConcurrency。具體操作步驟,請參見管理函數。
如果您使用了預留模式,預留模式下的函數也可以並發處理多個請求。更多資訊,請參見彈性管理(含預留模式)。
更多資訊
關於如何使用Node.js SDK設定執行個體並發度,請參見設定執行個體並發度。