Saat memanggil API KMS, Anda mungkin menerima error. Topik ini menjelaskan cara menggunakan exponential backoff untuk melakukan retry permintaan yang mengalami error.
Latar Belakang
Saat memanggil API layanan, error dapat terjadi sewaktu-waktu. Dalam kasus seperti ini, Anda dapat melakukan retry permintaan tersebut dari dalam aplikasi Anda.
Beberapa SDK Alibaba Cloud mendukung retry otomatis melalui konfigurasi. Sebagai contoh, Alibaba Cloud SDK untuk .NET memungkinkan Anda mengonfigurasi kebijakan retry. Jika retry otomatis tidak tersedia, Anda dapat menerapkan metode retry yang dijelaskan dalam topik ini.
Strategi retry
Jika permintaan gagal karena error server (5xx) atau error throttling, lakukan retry dengan menerapkan strategi berikut:
-
Retry sederhana.
Misalnya, lakukan retry sekali per detik selama 10 detik.
-
Exponential backoff.
Pada setiap respons error berturut-turut, interval tunggu antar retry diperpanjang secara eksponensial. Anda harus menetapkan batas maksimum untuk interval tunda dan jumlah maksimum retry. Pendekatan ini membantu mencegah konflik berkelanjutan selama proses retry. Sebagai contoh, ketika permintaan melebihi kuota throttling dalam periode waktu singkat, exponential backoff secara efektif dapat menghindari pengulangan error throttling.
Gerbang KMS Dedicated tidak menerapkan batas atas pada jumlah pemanggilan API. Sebaliknya, gerbang tersebut menggunakan pendekatan best-effort untuk memaksimalkan pemanfaatan sumber daya komputasi dan penyimpanan instans dalam memproses permintaan API. Oleh karena itu, error throttling tidak terjadi.
Pseudocode untuk exponential backoff
Pseudocode berikut menunjukkan cara melakukan retry operasi dengan penundaan bertahap.
initialDelay = 200
retries = 0
DO
wait for (2^retries * initialDelay) milliseconds
status = CallSomeAPI()
IF status == SUCCESS
retry = false // Berhasil, hentikan pemanggilan API lagi.
ELSE IF status = THROTTLED || status == SERVER_NOT_READY
retry = true // Gagal karena throttling atau server sibuk, coba lagi.
ELSE
retry = false // Terjadi error lain, hentikan pemanggilan API lagi.
END IF
retries = retries + 1
WHILE (retry AND (retries < MAX_RETRIES))
Gunakan exponential backoff untuk menangani throttling KMS
Contoh Java berikut menunjukkan cara menggunakan exponential backoff untuk menangani error throttling saat memanggil operasi Decrypt pada KMS.
-
Anda dapat melakukan modifikasi sederhana untuk melakukan retry terhadap jenis error server tertentu, seperti HTTP 503.
-
Anda dapat memperkirakan jumlah permintaan yang dikirim klien dalam periode waktu tertentu dan menyesuaikan delay awal (
initialDelay) serta jumlah retry maksimum (maxRetries).
Pasangan AccessKey untuk Akun Alibaba Cloud memiliki izin untuk semua operasi API. Kami menyarankan agar Anda menggunakan RAM user untuk memanggil operasi API atau melakukan O&M rutin. Untuk mencegah risiko keamanan, jangan hardcode ID AccessKey dan AccessKey Secret Anda di kode proyek. Hardcoding kredensial dapat menyebabkan kebocoran yang membahayakan seluruh sumber daya dalam akun Anda.
Topik ini memberikan contoh cara mengonfigurasi variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET untuk otentikasi identitas.
Untuk informasi lebih lanjut tentang cara mengonfigurasi kredensial akses, lihat Kelola kredensial akses.
Cara mengonfigurasi variabel lingkungan berbeda-beda tergantung sistem operasinya. Untuk informasi selengkapnya, lihat Konfigurasi variabel lingkungan di Linux, macOS, dan Windows.
import com.aliyun.kms20160120.Client;
import com.aliyun.kms20160120.models.DecryptRequest;
import com.aliyun.kms20160120.models.DecryptResponse;
import com.aliyun.tea.*;
import com.aliyun.teautil.models.RuntimeOptions;
import java.nio.charset.StandardCharsets;
public class Main {
private static Client kmsClient;
private static Client kmsClient(String regionId, String accessKeyId, String accessKeySecret) throws Exception {
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(accessKeySecret);
config.setRegionId(regionId) ;
return new Client(config);
}
private static String kmsDecrypt(String cipherTextBlob) throws Exception {
DecryptRequest decryptRequest = new DecryptRequest()
// Tentukan ciphertext yang ingin Anda dekripsi.
.setCiphertextBlob(cipherTextBlob);
DecryptResponse response = kmsClient.decryptWithOptions(decryptRequest, new RuntimeOptions());
// Dapatkan teks biasa hasil dekripsi dari respons.
String plaintext = response.getBody().getPlaintext();
System.out.println("Ciphertext (Base64): " + cipherTextBlob);
System.out.println("Teks Biasa Hasil Dekripsi: " + plaintext);
return plaintext;
}
public static long getWaitTimeExponential(int retryCount) {
final long initialDelay = 200L;
long waitTime = ((long) Math.pow(2, retryCount) * initialDelay);
return waitTime;
}
public static void main(String[] args) throws Exception {
String regionId = "<region ID>"; // Contoh: "cn-shanghai"
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
String cipherTextBlob ="a2V5LXNoaDY4M**********w=";
int maxRetries = 5;
kmsClient = kmsClient(regionId, accessKeyId, accessKeySecret);
for (int i = 0; i < maxRetries; i++) {
try {
String plainText = kmsDecrypt(cipherTextBlob);
return;
} catch (Exception e) {
e.printStackTrace();
if (e.getMessage().contains("Rejected.Throttling")) { // Mengalami throttling. Lakukan retry permintaan.
try {
Thread.sleep(getWaitTimeExponential(i + 1));
} catch (InterruptedException ignore) {
}
} else {
break; // Bukan error throttling. Hentikan retry.
}
}
}
}
}