Synthetics 執行時間版本 - Amazon CloudWatch

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

Synthetics 執行時間版本

當您建立或更新 Canary 時,您需要為 Canary 選擇 Synthetics 執行時間版本。Synthetics 執行時間是 Synthetics 程式碼的組合,可呼叫指令碼處理常式,以及組合依存項目的 Lambda 層。

CloudWatch Synthetics 目前支持將 Node.js 用於腳本和木偶框架的運行時,以及使用 Python 進行腳本編寫和硒 Web 驅動程序的運行時。

建議您一律使用最新版的 Canary 執行時間,這樣才能使用最新功能和 Synthetics 程式庫的最新更新。

建立金絲雀時,其中一個建立的圖層是附加在前面加上的「Synthetics」圖層。Synthetics此圖層由 Synthetics 服務帳戶擁有,並包含運行時代碼。

注意

每當您升級金絲雀以使用新版本的 Synthetics 執行期時,您的金絲雀使用的所有 Synthetics 程式庫函數也會自動升級到 Synthetics 執行期支援的相同版本的 NodeJS。

CloudWatch Synthetics 運行時支持策略

Synthetics 執行時間版本受維護和安全性更新所拘束。當不再支援執行時間版本的任何元件時,該 Synthetics 執行時間版本則將遭到取代。

您無法使用已取代的執行時間版本來建立 Canary。使用已取代執行時間的 Canary 將繼續執行。您可以停止、開始和刪除這些 Canary。您可以將 Canary 更新為使用支援的執行時間版本,藉此更新使用已取代的執行時間版本的現有 Canary。

CloudWatch 如果您的金絲雀使用運行時計劃在接下來的 60 天內棄用,則 Synthetics 會通過電子郵件通知您。我們建議您將 Canary 遷移至支援的執行時間版本,以便從更新版本中包含的新功能、安全性和效能增強功能受益。

如何將 Canary 更新為新的執行時間版本?

您可以使用 CloudWatch 控制台更新初期測試的執行階段版本, AWS CloudFormation,該 AWS CLI 或 AWS SDK。使用 CloudWatch 主控台時,您可以一次更新最多五個金絲雀,方法是在初期測試清單頁面中選取它們,然後選擇 [動作] > [更新執行階段]。

您可以先使用 CloudWatch 主控台複製初期測試並更新其執行階段版本,以驗證升級。這樣一來,會建立另一個 Canary,它就是原來的 Canary 的複製。一旦您使用新的執行時間版本驗證了您的 Canary,您可以更新原始 Canary 的執行時間版本並刪除複製的 Canary。

您也可以使用升級指令碼更新多個 Canary。如需詳細資訊,請參閱Canary 執行時間升級指令碼

如果您升級 Canary 但失敗了,請參閱 對失敗的 Canary 進行故障診斷

執行時間取代日期

執行時間版本 取代日期

syn-nodejs-puppeteer-6.1

2024年3月8日

syn-nodejs-puppeteer-6.0

2024年3月8日

syn-nodejs-puppeteer-5.1

2024年3月8日

syn-nodejs-puppeteer-5.0

2024年3月8日

syn-nodejs-puppeteer-4.0

2024年3月8日

syn-nodejs-puppeteer-3.9

2024 年 1 月 8 日

syn-nodejs-puppeteer-3.8

2024 年 1 月 8 日

syn-python-selenium-2.0

2024年3月8日

syn-python-selenium-1.3

2024年3月8日

syn-python-selenium-1.2

2024年3月8日

syn-python-selenium-1.1

2024年3月8日

syn-python-selenium-1.0

2024年3月8日

syn-nodejs-puppeteer-3.7

2024 年 1 月 8 日

syn-nodejs-puppeteer-3.6

2024 年 1 月 8 日

syn-nodejs-puppeteer-3.5

2024 年 1 月 8 日

syn-nodejs-puppeteer-3.4

2022 年 11 月 13 日

syn-nodejs-puppeteer-3.3

2022 年 11 月 13 日

syn-nodejs-puppeteer-3.2

2022 年 11 月 13 日

syn-nodejs-puppeteer-3.1

2022 年 11 月 13 日

syn-nodejs-puppeteer-3.0

2022 年 11 月 13 日

syn-nodejs-2.2

2021 年 5 月 28 日

syn-nodejs-2.1

2021 年 5 月 28 日

syn-nodejs-2.0

2021 年 5 月 28 日

syn-nodejs-2.0-beta

2021 年 2 月 8 日

syn-1.0

2021 年 5 月 28 日

Canary 執行時間升級指令碼

若要將 Canary 指令碼升級為支援的執行時間版本,請使用下列指令碼。

const AWS = require('aws-sdk'); // You need to configure your AWS credentials and Region. // https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html // https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-region.html const synthetics = new AWS.Synthetics(); const DEFAULT_OPTIONS = { /** * The number of canaries to upgrade during a single run of this script. */ count: 10, /** * No canaries are upgraded unless force is specified. */ force: false }; /** * The number of milliseconds to sleep between GetCanary calls when * verifying that an update succeeded. */ const SLEEP_TIME = 5000; (async () => { try { const options = getOptions(); const versions = await getRuntimeVersions(); const canaries = await getAllCanaries(); const upgrades = canaries .filter(canary => !versions.isLatestVersion(canary.RuntimeVersion)) .map(canary => { return { Name: canary.Name, FromVersion: canary.RuntimeVersion, ToVersion: versions.getLatestVersion(canary.RuntimeVersion) }; }); if (options.force) { const promises = []; for (const upgrade of upgrades.slice(0, options.count)) { const promise = upgradeCanary(upgrade); promises.push(promise); // Sleep for 100 milliseconds to avoid throttling. await usleep(100); } const succeeded = []; const failed = []; for (let i = 0; i < upgrades.slice(0, options.count).length; i++) { const upgrade = upgrades[i]; const promise = promises[i]; try { await promise; console.log(`The update of ${upgrade.Name} succeeded.`); succeeded.push(upgrade.Name); } catch (e) { console.log(`The update of ${upgrade.Name} failed with error: ${e}`); failed.push({ Name: upgrade.Name, Reason: e }); } } if (succeeded.length) { console.group('The following canaries were upgraded successfully.'); for (const name of succeeded) { console.log(name); } console.groupEnd() } else { console.log('No canaries were upgraded successfully.'); } if (failed.length) { console.group('The following canaries were not upgraded successfully.'); for (const failure of failed) { console.log('\x1b[31m', `${failure.Name}: ${failure.Reason}`, '\x1b[0m'); } console.groupEnd(); } } else { console.log('Run with --force [--count <count>] to perform the first <count> upgrades shown. The default value of <count> is 10.') console.table(upgrades); } } catch (e) { console.error(e); } })(); function getOptions() { const force = getFlag('--force', DEFAULT_OPTIONS.force); const count = getOption('--count', DEFAULT_OPTIONS.count); return { force, count }; function getFlag(key, defaultValue) { return process.argv.includes(key) || defaultValue; } function getOption(key, defaultValue) { const index = process.argv.indexOf(key); if (index < 0) { return defaultValue; } const value = process.argv[index + 1]; if (typeof value === 'undefined' || value.startsWith('-')) { throw `The ${key} option requires a value.`; } return value; } } function getAllCanaries() { return new Promise((resolve, reject) => { const canaries = []; synthetics.describeCanaries().eachPage((err, data) => { if (err) { reject(err); } else { if (data === null) { resolve(canaries); } else { canaries.push(...data.Canaries); } } }); }); } function getRuntimeVersions() { return new Promise((resolve, reject) => { const jsVersions = []; const pythonVersions = []; synthetics.describeRuntimeVersions().eachPage((err, data) => { if (err) { reject(err); } else { if (data === null) { jsVersions.sort((a, b) => a.ReleaseDate - b.ReleaseDate); pythonVersions.sort((a, b) => a.ReleaseDate - b.ReleaseDate); resolve({ isLatestVersion(version) { const latest = this.getLatestVersion(version); return latest === version; }, getLatestVersion(version) { if (jsVersions.some(v => v.VersionName === version)) { return jsVersions[jsVersions.length - 1].VersionName; } else if (pythonVersions.some(v => v.VersionName === version)) { return pythonVersions[pythonVersions.length - 1].VersionName; } else { throw Error(`Unknown version ${version}`); } } }); } else { for (const version of data.RuntimeVersions) { if (version.VersionName === 'syn-1.0') { jsVersions.push(version); } else if (version.VersionName.startsWith('syn-nodejs-2.')) { jsVersions.push(version); } else if (version.VersionName.startsWith('syn-nodejs-puppeteer-')) { jsVersions.push(version); } else if (version.VersionName.startsWith('syn-python-selenium-')) { pythonVersions.push(version); } else { throw Error(`Unknown version ${version.VersionName}`); } } } } }); }); } async function upgradeCanary(upgrade) { console.log(`Upgrading canary ${upgrade.Name} from ${upgrade.FromVersion} to ${upgrade.ToVersion}`); await synthetics.updateCanary({ Name: upgrade.Name, RuntimeVersion: upgrade.ToVersion }).promise(); while (true) { await usleep(SLEEP_TIME); console.log(`Getting the state of canary ${upgrade.Name}`); const response = await synthetics.getCanary({ Name: upgrade.Name }).promise(); const state = response.Canary.Status.State; console.log(`The state of canary ${upgrade.Name} is ${state}`); if (state === 'ERROR' || response.Canary.Status.StateReason) { throw response.Canary.Status.StateReason; } if (state !== 'UPDATING') { return; } } } function usleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }