Revert "perf: 添加AWS Rate Limit应对措施 (#748)"

This reverts commit 56b8c689ec.
This commit is contained in:
greper
2026-06-08 10:29:24 +08:00
committed by GitHub
parent 56b8c689ec
commit 8a5eff6581
2 changed files with 27 additions and 81 deletions
@@ -188,51 +188,4 @@ export class AwsClient {
throw err;
}
}
/**
* Retries an AWS SDK call with exponential backoff when throttled.
* Handles: TooManyRequestsException, ThrottlingException, RequestLimitExceeded, Throttling
*/
async withRetry<T>(call: () => Promise<T>, maxAttempts = 5, baseDelayMs = 2000): Promise<T> {
const throttlingCodes = new Set([
"TooManyRequestsException",
"ThrottlingException",
"RequestLimitExceeded",
"Throttling",
]);
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await call();
} catch (err: any) {
const code = err?.name || err?.Code || err?.code || "";
const isThrottle = throttlingCodes.has(code) || err?.message?.toLowerCase().includes("rate exceeded");
if (isThrottle && attempt < maxAttempts) {
const delay = baseDelayMs * Math.pow(2, attempt - 1); // 2s, 4s, 8s, 16s …
this.logger.warn(`AWS rate limit hit (${code}), attempt ${attempt}/${maxAttempts}, retrying in ${delay}ms…`);
await utils.sleep(delay);
} else {
throw err;
}
}
}
}
/**
* Polls a CloudFront distribution until its Status becomes "Deployed".
* CloudFront propagates changes globally and can take several minutes.
*/
async waitForDistributionDeployed(cloudFrontClient: any, distributionId: string, timeoutMs = 600_000, pollIntervalMs = 15_000): Promise<void> {
const { GetDistributionCommand } = await import("@aws-sdk/client-cloudfront");
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const res = await this.withRetry(() => cloudFrontClient.send(new GetDistributionCommand({ Id: distributionId })));
const status = res?.Distribution?.Status;
this.logger.info(`CloudFront distribution ${distributionId} status: ${status}`);
if (status === "Deployed") {
return;
}
await utils.sleep(pollIntervalMs);
}
throw new Error(`Timed out waiting for CloudFront distribution ${distributionId} to reach Deployed status`);
}
}
@@ -72,16 +72,10 @@ export class AwsDeployToCloudFront extends AbstractTaskPlugin {
async execute(): Promise<void> {
const access = await this.getAccess<AwsAccess>(this.accessId);
const acmClient = new AwsClient({
access,
region: this.region,
logger: this.logger,
});
let certId = this.cert as string;
if (typeof this.cert !== "string") {
//先上传
certId = await this.uploadToACM(acmClient, this.cert);
certId = await this.uploadToACM(access, this.cert);
}
//部署到CloudFront
@@ -96,39 +90,38 @@ export class AwsDeployToCloudFront extends AbstractTaskPlugin {
// update-distribution
for (const distributionId of this.distributionIds) {
// get-distribution-config (with retry for throttling)
const configData = await acmClient.withRetry(() =>
cloudFrontClient.send(new GetDistributionConfigCommand({ Id: distributionId }))
);
// get-distribution-config
const getDistributionConfigCommand = new GetDistributionConfigCommand({
Id: distributionId,
});
await acmClient.withRetry(() =>
cloudFrontClient.send(
new UpdateDistributionCommand({
DistributionConfig: {
...configData.DistributionConfig,
ViewerCertificate: {
...configData.DistributionConfig.ViewerCertificate,
CloudFrontDefaultCertificate: false,
ACMCertificateArn: certId,
},
},
Id: distributionId,
IfMatch: configData.ETag,
})
)
);
const configData = await cloudFrontClient.send(getDistributionConfigCommand);
this.logger.info(`证书已提交到 ${distributionId},等待全局部署完成…`);
// Wait for this distribution to fully propagate before moving to the next one.
// Updating a distribution that is still InProgress results in a PreconditionFailed error.
await acmClient.waitForDistributionDeployed(cloudFrontClient, distributionId);
this.logger.info(`部署 ${distributionId} 完成`);
const updateDistributionCommand = new UpdateDistributionCommand({
DistributionConfig: {
...configData.DistributionConfig,
ViewerCertificate: {
...configData.DistributionConfig.ViewerCertificate,
CloudFrontDefaultCertificate: false,
ACMCertificateArn: certId,
},
},
Id: distributionId,
IfMatch: configData.ETag,
});
await cloudFrontClient.send(updateDistributionCommand);
this.logger.info(`部署${distributionId}完成:`);
}
this.logger.info("部署完成");
}
private async uploadToACM(acmClient: AwsClient, cert: CertInfo) {
const awsCertARN = await acmClient.withRetry(() => acmClient.importCertificate(cert));
private async uploadToACM(access: AwsAccess, cert: CertInfo) {
const acmClient = new AwsClient({
access,
region: this.region,
logger: this.logger,
});
const awsCertARN = await acmClient.importCertificate(cert);
this.logger.info("证书上传成功,id=", awsCertARN);
return awsCertARN;
}