Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Mencoba lagi di AWS SDK untuk Kotlin
Panggilan untuk Layanan AWS sesekali mengembalikan pengecualian yang tidak terduga. Jenis kesalahan tertentu, seperti kesalahan pelambatan atau transien, mungkin berhasil jika panggilan dicoba ulang.
Halaman ini menjelaskan cara AWS SDK untuk Kotlin penanganan mencoba ulang secara otomatis dan cara menyesuaikan perilaku coba ulang untuk aplikasi Anda.
Memahami perilaku coba lagi
Bagian berikut menjelaskan bagaimana SDK menentukan kapan harus mencoba ulang permintaan dan pengecualian apa yang dianggap dapat dicoba ulang.
Konfigurasi coba lagi default
Secara default, setiap klien layanan secara otomatis dikonfigurasi dengan strategi coba ulang standar. Konfigurasi default mencoba panggilan yang gagal hingga tiga kali (upaya awal ditambah dua percobaan ulang). Penundaan intervensi antara setiap panggilan dikonfigurasi dengan backoff eksponensial dan jitter acak untuk menghindari badai coba lagi. Konfigurasi ini berfungsi untuk sebagian besar kasus penggunaan tetapi mungkin tidak cocok dalam beberapa keadaan, seperti sistem throughput tinggi.
SDK mencoba mencoba ulang hanya pada kesalahan yang dapat dicoba ulang. Contoh kesalahan yang dapat dicoba ulang adalah batas waktu soket, pelambatan sisi layanan, kegagalan kunci konkurensi atau optimis, dan kesalahan layanan sementara. Parameter, authentication/security kesalahan, dan pengecualian salah konfigurasi yang hilang atau tidak valid tidak dianggap dapat dicoba ulang.
Anda dapat menyesuaikan strategi coba ulang standar dengan menyetel upaya maksimum, penundaan dan backoff, dan konfigurasi bucket token.
Pengecualian mana yang bisa dicoba kembali?
AWS SDK untuk Kotlin Menggunakan kebijakan coba ulang yang telah dikonfigurasi sebelumnya yang menentukan pengecualian mana yang dapat dicoba ulang. Konfigurasi klien layanan memiliki retryPolicy
properti yang menentukan kebijakan yang diterapkan pada percobaan ulang. Jika tidak ada nilai kustom yang ditentukan, nilai defaultnya adalah AwsRetryPolicy.
Pengecualian berikut ditentukan untuk dapat dicoba kembali oleh: AwsRetryPolicy
Dicoba ulang dengan kode kesalahan
Apa saja ServiceException
dengan sdkErrorMetadata.errorCode
dari:
BandwidthLimitExceeded
EC2ThrottledException
IDPCommunicationError
LimitExceededException
PriorRequestNotComplete
ProvisionedThroughputExceededException
RequestLimitExceeded
RequestThrottled
RequestThrottledException
RequestTimeout
RequestTimeoutException
SlowDown
ThrottledException
Throttling
ThrottlingException
TooManyRequestsException
TransactionInProgressException
Dicoba ulang dengan kode status HTTP
Apa saja ServiceException
dengan sdkErrorMetadata.statusCode
dari:
500 (Kesalahan Layanan Internal)
502 (Gerbang Buruk)
503 (Layanan Tidak Tersedia)
504 (Batas Waktu Gerbang)
Dicoba ulang dengan jenis kesalahan
Apa saja ServiceException
dengan sdkErrorMetadata.errorType
dari:
ErrorType.Server
(seperti kesalahan layanan internal)ErrorType.Client
(seperti permintaan yang tidak valid, sumber daya tidak ditemukan, akses ditolak, dll.)
Dicoba ulang dengan metadata SDK
SdkBaseException
Dimana saja:
sdkErrorMetadata.isRetryable
adalahtrue
(seperti batas waktu sisi klien, networking/socket kesalahan, dll.)sdkErrorMetadata.isThrottling
adalahtrue
(seperti membuat terlalu banyak permintaan dalam waktu singkat)
Untuk daftar lengkap pengecualian yang mungkin dilemparkan oleh setiap klien layanan, lihat dokumentasi referensi API khusus layanan.
Periksa apakah pengecualian dapat dicoba ulang
Untuk menentukan apakah SDK menganggap pengecualian dapat dicoba ulang, periksa isRetryable
properti pada pengecualian yang tertangkap:
try { dynamoDbClient.putItem { tableName = "MyTable" item = mapOf("id" to AttributeValue.S("123")) } } catch (e: SdkBaseException) { println("Exception occurred: ${e.message}") if (e.sdkErrorMetadata.isRetryable) { println("This exception is retryable - SDK will automatically retry") println("If you're seeing this, retries may have been exhausted") } else { println("This exception is not retryable - fix the underlying issue") // Common non-retryable scenarios. when { e.message?.contains("ValidationException") == true -> println("Check your request parameters") e.message?.contains("AccessDenied") == true -> println("Check your IAM permissions") e.message?.contains("ResourceNotFound") == true -> println("Verify the resource exists") } } }
Pengecualian apa yang mencapai kode Anda saat percobaan ulang gagal
Ketika mekanisme percobaan ulang SDK tidak dapat menyelesaikan masalah, pengecualian akan dilemparkan ke kode aplikasi Anda. Memahami jenis pengecualian ini membantu Anda menerapkan penanganan kesalahan yang sesuai. Ini bukan pengecualian yang memicu pengambilan — yang ditangani secara internal oleh SDK.
Kode Anda akan menangkap jenis pengecualian berikut ketika percobaan ulang habis atau dinonaktifkan:
- Pengecualian layanan setelah mencoba lagi kelelahan
-
Ketika semua upaya coba lagi gagal, kode Anda menangkap pengecualian layanan akhir (subkelas
AwsServiceException
) yang menyebabkan upaya percobaan ulang terakhir gagal. Ini bisa berupa kesalahan pelambatan, kesalahan server, atau pengecualian khusus layanan lainnya yang tidak dapat diselesaikan oleh SDK melalui percobaan ulang. - Pengecualian jaringan setelah coba lagi kelelahan
-
Ketika masalah jaringan berlanjut melalui semua upaya coba lagi, kode Anda menangkap
ClientException
instance untuk masalah seperti batas waktu koneksi, kegagalan resolusi DNS, dan masalah konektivitas lainnya yang tidak dapat diselesaikan oleh SDK.
Gunakan pola berikut untuk menangani pengecualian ini dalam aplikasi Anda:
try { s3Client.getObject { bucket = "amzn-s3-demo-bucket" key = "my-key" } } catch (e: AwsServiceException) { // Service-side errors that persisted through all retries. println("Service error after retries: ${e.errorDetails?.errorCode} - ${e.message}") // Handle specific service errors that couldn't be resolved. if (e.errorDetails?.errorCode == "ServiceQuotaExceededException" || e.errorDetails?.errorCode == "ThrottlingException") { println("Rate limiting persisted - consider longer delays or quota increase") } } catch (e: ClientException) { // Client-side errors (persistent network issues, DNS resolution failures, etc.) println("Client error after retries: ${e.message}") }
Menyesuaikan perilaku coba lagi
Bagian berikut menunjukkan cara menyesuaikan perilaku coba ulang SDK untuk kasus penggunaan spesifik Anda.
Konfigurasikan upaya maksimum
Anda dapat menyesuaikan upaya maksimum default (3) di blok retryStrategy
DSL selama konstruksi klien.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { maxAttempts = 5 } }
Dengan klien layanan DynamoDB yang ditampilkan dalam cuplikan sebelumnya, SDK mencoba panggilan API yang gagal hingga lima kali (upaya awal ditambah empat percobaan ulang).
Anda dapat menonaktifkan percobaan ulang otomatis sepenuhnya dengan mengatur upaya maksimum ke satu seperti yang ditunjukkan pada cuplikan berikut.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { maxAttempts = 1 // The SDK makes no retries. } }
Konfigurasikan penundaan dan backoff
Jika percobaan ulang diperlukan, strategi coba lagi default menunggu sebelum melakukan upaya berikutnya. Penundaan untuk percobaan ulang pertama kecil tetapi tumbuh secara eksponensial untuk percobaan ulang nanti. Jumlah penundaan maksimum dibatasi sehingga tidak tumbuh terlalu besar.
Akhirnya, jitter acak diterapkan pada penundaan di antara semua upaya. Jitter membantu mengurangi efek armada besar yang dapat menyebabkan badai coba lagi. (Lihat posting Blog AWS Arsitektur
Parameter penundaan dapat dikonfigurasi di blok delayProvider
DSL.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { delayProvider { initialDelay = 100.milliseconds maxBackoff = 5.seconds } } }
Dengan konfigurasi yang ditunjukkan pada cuplikan sebelumnya, klien menunda upaya percobaan ulang pertama hingga 100 milidetik. Jumlah waktu maksimum antara setiap upaya coba lagi adalah 5 detik.
Parameter berikut tersedia untuk tuning delay dan backoff.
Parameter | Nilai default | Deskripsi |
---|---|---|
initialDelay |
10 milidetik | Jumlah maksimum keterlambatan untuk percobaan ulang pertama. Ketika jitter diterapkan, jumlah penundaan yang sebenarnya mungkin lebih sedikit. |
jitter |
1.0 (jitter penuh) |
Amplitudo maksimum yang digunakan untuk secara acak mengurangi penundaan yang dihitung. Nilai default 1.0 berarti bahwa penundaan yang dihitung dapat dikurangi menjadi jumlah berapa pun hingga 100% (misalnya, turun ke 0). Nilai 0,5 berarti bahwa penundaan yang dihitung dapat dikurangi hingga setengahnya. Dengan demikian, penundaan maksimal 10 ms dapat dikurangi menjadi antara 5 ms dan 10 ms. Nilai 0,0 berarti tidak ada jitter yang diterapkan. penting️ Konfigurasi Jitter adalah fitur lanjutan. Menyesuaikan perilaku ini biasanya tidak disarankan. |
maxBackoff |
20 detik | Jumlah maksimum keterlambatan untuk diterapkan pada upaya apa pun. Menetapkan nilai ini membatasi pertumbuhan eksponensial yang terjadi antara upaya berikutnya dan mencegah maksimum yang dihitung menjadi terlalu besar. Parameter ini membatasi penundaan yang dihitung sebelum jitter diterapkan. Jika diterapkan, jitter dapat mengurangi penundaan lebih jauh. |
scaleFactor |
1.5 | Basis eksponensial dimana penundaan maksimum berikutnya akan ditingkatkan. Misalnya, diberikan 10 ms dan 1,5,
|
Konfigurasikan ember token coba lagi
Anda dapat memodifikasi perilaku strategi coba ulang standar lebih lanjut dengan menyesuaikan konfigurasi bucket token default. Bucket token coba lagi membantu mengurangi percobaan ulang yang cenderung tidak berhasil atau yang mungkin membutuhkan lebih banyak waktu untuk diselesaikan, seperti kegagalan batas waktu dan pembatasan.
penting
Konfigurasi token bucket adalah fitur lanjutan. Menyesuaikan perilaku ini biasanya tidak disarankan.
Setiap upaya coba lagi (opsional termasuk upaya awal) mengurangi beberapa kapasitas dari ember token. Jumlah yang dikurangi tergantung pada jenis upaya. Misalnya, mencoba ulang kesalahan sementara mungkin murah, tetapi mencoba kembali kesalahan batas waktu atau pelambatan mungkin lebih mahal.
Upaya yang berhasil mengembalikan kapasitas ke ember. Bucket mungkin tidak bertambah melebihi kapasitas maksimumnya atau dikurangi di bawah nol.
Bergantung pada nilai useCircuitBreakerMode
pengaturan, upaya untuk mengurangi kapasitas di bawah nol menghasilkan salah satu hasil berikut:
-
Jika pengaturannya BENAR, pengecualian dilemparkan— Misalnya, jika terlalu banyak percobaan ulang telah terjadi dan lebih banyak percobaan ulang tidak mungkin berhasil.
-
Jika pengaturannya SALAH, ada penundaan — Misalnya, penundaan hingga bucket memiliki kapasitas yang cukup lagi.
catatan
Saat pemutus sirkuit aktif (ember token mencapai kapasitas nol), SDK melempar a ClientException
dengan pesan “Coba lagi kapasitas terlampaui”. Ini adalah pengecualian sisi klien, bukanAwsServiceException
, karena berasal dari logika coba lagi SDK daripada layanan. AWS Pengecualian dilemparkan segera tanpa mencoba operasi, membantu mencegah badai coba lagi selama pemadaman layanan.
Parameter bucket token dapat dikonfigurasi di blok tokenBucket
DSL:
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { tokenBucket { maxCapacity = 100 refillUnitsPerSecond = 2 } } }
Parameter berikut tersedia untuk menyetel ember token coba lagi:
Parameter | Nilai default | Deskripsi |
---|---|---|
initialTryCost |
0 | Jumlah yang akan dikurangi dari ember untuk upaya awal. Nilai default 0 berarti tidak ada kapasitas yang akan dikurangi dan dengan demikian upaya awal tidak dihentikan atau ditunda. |
initialTrySuccessIncrement |
1 | Jumlah untuk meningkatkan kapasitas ketika upaya awal berhasil. |
maxCapacity |
500 | Kapasitas maksimum ember token. Jumlah token yang tersedia tidak dapat melebihi jumlah ini. |
refillUnitsPerSecond |
0 | Jumlah kapasitas ditambahkan kembali ke ember setiap detik. Nilai 0 berarti tidak ada kapasitas yang ditambahkan kembali secara otomatis. (Misalnya, hanya upaya yang berhasil yang menghasilkan peningkatan kapasitas). Nilai 0 useCircuitBreakerMode harus BENAR. |
retryCost |
5 | Jumlah yang akan dikurangi dari ember untuk upaya setelah kegagalan sementara. Jumlah yang sama ditambahkan kembali ke ember jika upaya berhasil. |
timeoutRetryCost |
10 | Jumlah yang akan dikurangi dari bucket untuk upaya setelah batas waktu atau kegagalan pelambatan. Jumlah yang sama ditambahkan kembali ke ember jika upaya berhasil. |
useCircuitBreakerMode |
BETUL | Menentukan perilaku ketika upaya untuk mengurangi kapasitas akan mengakibatkan kapasitas bucket turun di bawah nol. Ketika TRUE, bucket token akan mengeluarkan pengecualian yang menunjukkan bahwa tidak ada lagi kapasitas coba lagi. Ketika FALSE, token bucket akan menunda upaya sampai kapasitas yang cukup telah diisi ulang. |
Untuk informasi rinci tentang jenis pengecualian yang dilemparkan selama skenario coba lagi, termasuk pengecualian pemutus sirkuit, lihat. Pengecualian apa yang mencapai kode Anda saat percobaan ulang gagal
Konfigurasikan percobaan ulang adaptif
Sebagai alternatif dari strategi coba ulang standar, strategi coba lagi adaptif adalah pendekatan lanjutan yang mencari tingkat permintaan yang ideal untuk meminimalkan kesalahan pelambatan.
penting
Coba ulang adaptif adalah mode coba lagi lanjutan. Menggunakan strategi coba lagi ini biasanya tidak disarankan.
Percobaan ulang adaptif mencakup semua fitur percobaan ulang standar. Ini menambahkan pembatas tingkat sisi klien yang mengukur tingkat permintaan yang dibatasi dibandingkan dengan permintaan non-throttled. Ini juga membatasi lalu lintas untuk mencoba tetap berada dalam bandwidth yang aman, idealnya menyebabkan kesalahan pelambatan nol.
Tarif beradaptasi secara real time untuk mengubah kondisi layanan dan pola lalu lintas dan dapat meningkatkan atau menurunkan tingkat lalu lintas yang sesuai. Secara kritis, pembatas tarif mungkin menunda upaya awal dalam skenario lalu lintas tinggi.
Anda memilih strategi coba ulang adaptif dengan memberikan parameter tambahan pada retryStrategy
metode ini. Parameter pembatas laju dapat dikonfigurasi di blok rateLimiter
DSL.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy(AdaptiveRetryStrategy) { maxAttempts = 10 rateLimiter { minFillRate = 1.0 smoothing = 0.75 } } }
catatan
Strategi coba ulang adaptif mengasumsikan bahwa klien bekerja melawan satu sumber daya (misalnya, satu tabel DynamoDB atau satu bucket Amazon S3).
Jika Anda menggunakan satu klien untuk beberapa sumber daya, pembatasan atau pemadaman yang terkait dengan satu sumber daya menghasilkan peningkatan latensi dan kegagalan saat klien mengakses semua sumber daya lainnya. Saat Anda menggunakan strategi coba ulang adaptif, kami sarankan Anda menggunakan satu klien untuk setiap sumber daya.