デジタル資産管理システムであるアプリを持っています。サムネイルを表示します。これらのサムネイルは、AWS S3の署名付きURL(https://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html)で提供されるように設定されています。このコードは、リクエストで処理されるアイテムの数を変更するまで機能します。アプリケーションには25、50、100、200の選択肢があります。100または200を選択すると、「エラー:com.amazonaws.AmazonServiceException:Too Many Requests(Service:null; Status Code:429; Error Code:null」でプロセスが失敗します。 ;リクエストID:null) "
現在、プロセスは次のとおりです。検索を実行し、そのオブジェクトの署名付きURLを返すメソッドを介して各オブジェクトキーを実行します。
このアプリケーションはElastic Container Serviceを介して実行されます。これにより、ContainerCredentialsProviderを介して認証情報を取得できます。
レビューのための関連コード:
String s3SignedUrl(String objectKeyUrl) {
// Environment variables for S3 client.
String clientRegion = System.getenv("REGION");
String bucketName = System.getenv("S3_BUCKET");
try {
// S3 credentials get pulled in from AWS via ContainerCredentialsProvider.
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withRegion(clientRegion)
.withCredentials(new ContainerCredentialsProvider())
.build();
// Set the pre-signed URL to expire after one hour.
java.util.Date expiration = new java.util.Date();
long expTimeMillis = expiration.getTime();
expTimeMillis += 1000 * 60 * 60;
expiration.setTime(expTimeMillis);
// Generate the presigned URL.
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(bucketName, objectKeyUrl)
.withMethod(HttpMethod.GET)
.withExpiration(expiration);
return s3Client.generatePresignedUrl(generatePresignedUrlRequest).toString();
} catch (AmazonServiceException e) {
throw new AssetException(FAILED_TO_GET_METADATA, "The call was transmitted successfully, but Amazon " +
"S3 couldn't process it, so it returned an error response. Error: " + e);
} catch (SdkClientException e) {
throw new AssetException(FAILED_TO_GET_METADATA, "Amazon S3 couldn't be contacted for a response, or " +
"the client couldn't parse the response from Amazon S3. Error: " + e);
}
}
そして、これは私たちがアイテムを処理する部分です:
// Overwrite the url, it's nested deeply in maps of maps.
for (Object anAssetList : assetList) {
String assetId = ((Map) anAssetList).get("asset_id").toString();
if (renditionAssetRecordMap.containsKey(assetId)) {
String s3ObjectKey = renditionAssetRecordMap.get(assetId).getThumbObjectLocation();
((Map) ((Map) ((Map) anAssetList)
.getOrDefault("rendition_content", new HashMap<>()))
.getOrDefault("thumbnail_content", new HashMap<>()))
.put("url", s3SignedUrl(s3ObjectKey));
}
}
どんなガイダンスもいただければ幸いです。シンプルで、うまくいけばAWS側で設定できるソリューションを気に入っていただけると思います。そうでなければ、今私はこれをバッチでURLを生成するためのプロセスを追加することを検討しています。
この問題は、署名付きURLの生成とは無関係です。これらはサービスとの相互作用なしで行われるため、レート制限される可能性のある方法はありません。事前署名付きURLは、HMAC-SHAアルゴリズムを使用して、資格情報を所有しているエンティティが特定の要求を承認したことをサービスに証明します。HMAC-SHAの一方通行(非可逆)の性質により、これらのURLは、サービスの相互作用なしに、コードが実行されているマシン上で完全に生成できます。
ただし、認証情報を繰り返し取得することが例外の実際の原因である可能性が非常に高いようです。そのため、不必要に何度も繰り返しているようです。
これは高価な操作です。
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withRegion(clientRegion)
.withCredentials(new ContainerCredentialsProvider())
.build();
これを再度呼び出すたびに、資格情報を再度フェッチする必要があります。それが実際の限界です。
s3client
一度だけビルドして、s3SignedUrl()
そのオブジェクトが渡されることを期待するようにリファクタリングして、再利用できるようにします。
429
エラーの解決に加えて、顕著なパフォーマンスの向上が見られるはずです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加