設(shè)置實例并發(fā)度
本文介紹實例并發(fā)的背景信息、應(yīng)用場景、優(yōu)勢和使用限制,以及如何在函數(shù)計算控制臺設(shè)置實例并發(fā)度。
背景信息
函數(shù)計算按實例占用時長計費(fèi)。假設(shè)訪問數(shù)據(jù)庫需要10秒,那么當(dāng)并發(fā)的3個請求分別在3個實例內(nèi)被處理后,3個實例總的執(zhí)行時長是30秒。如果能讓這3個請求在同一個實例內(nèi)并發(fā)處理,這樣實例的占用時間為10秒。為了幫助您節(jié)省實例資源費(fèi)用,函數(shù)計算支持單實例多并發(fā)功能,允許您為函數(shù)設(shè)置實例并發(fā)度InstanceConcurrency,即單個函數(shù)實例可以同時處理多個請求。單實例并發(fā)和多實例并發(fā)的區(qū)別如下圖所示。
假設(shè)同時有3個請求需要處理:
當(dāng)實例并發(fā)度設(shè)置為1時,每個實例同時只能處理1個請求,函數(shù)計算需要創(chuàng)建3個實例來處理這3個請求。
當(dāng)實例并發(fā)度設(shè)置為10時,每個實例同時可以處理10個請求,函數(shù)計算只需要創(chuàng)建1個實例就能處理這3個請求。
默認(rèn)情況下,函數(shù)的實例并發(fā)度為1,也就是一個實例同時只會處理一個請求。當(dāng)您設(shè)置單實例并發(fā)度大于1后,函數(shù)計算在彈性伸縮時,充分利用完一個實例的并發(fā)度后才會創(chuàng)建新的實例。
應(yīng)用場景
單實例多并發(fā)功能適用于函數(shù)中有較多時間在等待下游服務(wù)響應(yīng)的場景。等待響應(yīng)一般不消耗資源,在一個實例內(nèi)并發(fā)處理可以節(jié)省費(fèi)用。
優(yōu)勢
減少執(zhí)行時長,節(jié)省費(fèi)用。
例如,偏I(xiàn)/O的函數(shù)可以在一個實例內(nèi)并發(fā)處理,減少實例數(shù)從而減少總的執(zhí)行時長。
請求之間狀態(tài)可共享。
多個請求可以在一個實例內(nèi)共用數(shù)據(jù)庫連接池,從而減少和數(shù)據(jù)庫之間的連接數(shù)。
降低冷啟動概率。
由于多個請求可以在一個實例內(nèi)處理,創(chuàng)建新實例的次數(shù)會變少,冷啟動概率降低。
減少VPC IP地址的占用。
在相同負(fù)載下,單實例多并發(fā)可以降低總的實例數(shù),從而減少VPC IP地址的占用。
重要您的VPC綁定的vSwitch中至少需要兩個可用的IP地址,否則可能會導(dǎo)致服務(wù)不可用造成請求失敗。
設(shè)置單實例多并發(fā)的影響
設(shè)置了單實例多并發(fā)(InstanceConcurrency>1)之后,與單實例單并發(fā)(InstanceConcurrency=1)有以下幾個方面的區(qū)別:
計費(fèi)
單實例單并發(fā)
函數(shù)實例在同一時間只能處理1個請求,1個請求處理完了再處理下一個請求。計費(fèi)時長從處理第一個請求開始,到最后一個請求結(jié)束為止。
單實例多并發(fā)
多個請求在一個實例并發(fā)處理時,以實例的實際占用時間作為計費(fèi)的執(zhí)行時長,即從第一個請求開始,到最后一個請求結(jié)束期間的時長。
更多計費(fèi)詳情,請參見計費(fèi)概述。
并發(fā)度流控
函數(shù)計算在一個地域中按量實例數(shù)的上限默認(rèn)值為100,一個地域可以同時處理的最大請求數(shù)為“100×InstanceConcurrency”。例如,設(shè)置InstanceConcurrency=10時,則一個地域最多允許同時處理1000個并發(fā)請求。當(dāng)并發(fā)請求數(shù)超過函數(shù)計算可以處理的最大請求數(shù)時,會收到流控錯誤提示ResourceExhausted。
如您需要擴(kuò)大某個地域的按量實例數(shù)上限,請聯(lián)系我們。
日志
在單并發(fā)模式下,在調(diào)用函數(shù)時指定HTTP頭
X-Fc-Log-Type: Tail
,函數(shù)計算會在響應(yīng)頭X-Fc-Log-Result
中包含本次調(diào)用所產(chǎn)生的函數(shù)日志。在多并發(fā)模式下,由于多個請求并發(fā)執(zhí)行,無法獲取某個特定請求的日志,響應(yīng)頭中不再包含本次調(diào)用的函數(shù)日志。針對Node.js Runtime,原來的日志方式是使用
console.info()
函數(shù),該方式會把當(dāng)前請求的Request ID包含在日志內(nèi)容中。當(dāng)多請求在同一個實例并發(fā)處理時,當(dāng)前請求可能有很多個,繼續(xù)使用console.info()
打印日志會導(dǎo)致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
此時應(yīng)該使用
context.logger.info()
函數(shù)打印日志,該方式仍保留了請求的獨(dú)立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); };
錯誤處理
多個請求在一個實例并發(fā)處理時,由于一個請求處理不當(dāng)導(dǎo)致進(jìn)程退出或者崩潰,會導(dǎo)致正在并發(fā)處理的其他請求也收到錯誤信息。這要求您在編寫函數(shù)時,盡量捕獲請求級別的異常,不影響其他請求。Node.js代碼示例如下。
exports.handler = (event, context, callback) => {
try {
JSON.parse(event);
} catch (ex) {
callback(ex);
}
callback(null, 'hello world');
};
共享變量
多個請求在一個實例并發(fā)處理時,同時修改一個共享的變量,可能會導(dǎo)致錯誤。這要求您在編寫函數(shù)時,對于非線程安全的變量修改要進(jìn)行互斥保護(hù)。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());
}
}
監(jiān)控指標(biāo)
設(shè)置函數(shù)的實例并發(fā)度后,在相同的負(fù)載下,可以在控制臺的函數(shù)按量實例數(shù)監(jiān)控圖中看到函數(shù)已使用的實例數(shù)明顯地減少。
使用限制
限制項 | 描述 |
支持的Runtime |
|
單實例并發(fā)度取值范圍 | 1~200 |
調(diào)用響應(yīng)中的函數(shù)日志(X-Fc-Log-Result) | InstanceConcurrency>1時不支持 |
為函數(shù)設(shè)置單實例并發(fā)度
您可以在創(chuàng)建或更新函數(shù)時,指定函數(shù)的單實例并發(fā)度InstanceConcurrency。具體操作步驟,請參見管理函數(shù)。
如果您使用了預(yù)留模式,預(yù)留模式下的函數(shù)也可以并發(fā)處理多個請求。更多信息,請參見彈性管理(含預(yù)留模式)。
更多信息
關(guān)于如何使用Node.js SDK設(shè)置實例并發(fā)度,請參見設(shè)置實例并發(fā)度。