Saat memanggil operasi API dari Key Management Service (KMS), terkadang kesalahan dapat terjadi. Topik ini menjelaskan cara menggunakan metode eksponensial backoff untuk mencoba ulang permintaan yang gagal.
Informasi latar belakang
Jika terjadi kesalahan saat memanggil operasi API, Anda dapat mencoba ulang permintaan tersebut di aplikasi.
Beberapa Alibaba Cloud SDK mendukung percobaan ulang otomatis. Sebagai contoh, Anda dapat mengonfigurasi kebijakan percobaan ulang otomatis untuk Alibaba Cloud SDK untuk .NET. Jika SDK Anda tidak mendukung percobaan ulang otomatis, Anda dapat menggunakan metode yang dijelaskan dalam topik ini.
Metode percobaan ulang
Jika terjadi kesalahan server (5xx) atau permintaan ditolak karena pembatasan laju, Anda dapat menggunakan salah satu metode berikut:
Percobaan Ulang Sederhana
Cobalah ulang permintaan pada interval tetap dalam periode waktu tertentu.
Eksponensial Backoff
Untuk kesalahan berturut-turut, tingkatkan waktu tunggu antara percobaan secara eksponensial berdasarkan waktu maksimum backoff dan jumlah maksimum percobaan ulang. Metode ini membantu mencegah kesalahan konstan selama proses percobaan ulang. Sebagai contoh, Anda dapat menggunakan metode ini untuk mencoba ulang permintaan yang ditolak karena pembatasan laju, sehingga mengurangi jumlah kesalahan pembatasan laju dalam waktu singkat.
PentingGateway spesifikasi khusus tidak memberlakukan batas atas pada jumlah panggilan API dan menggunakan sumber daya komputasi serta penyimpanan instance untuk memproses sebanyak mungkin panggilan API. Dengan demikian, tidak ada kesalahan pembatasan laju yang terjadi.
Pseudocode untuk eksponensial backoff
Pseudocode berikut menunjukkan cara mencapai peningkatan eksponensial waktu tunggu antara percobaan ulang:
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 pembatasan laju atau server sibuk, coba lagi.
ELSE
retry = false // Beberapa kesalahan lain terjadi, hentikan pemanggilan API lagi.
END IF
retries = retries + 1
WHILE (retry AND (retries < MAX_RETRIES))Gunakan metode eksponensial backoff untuk memproses kesalahan pembatasan laju di KMS
Kode Java berikut menunjukkan cara menggunakan metode eksponensial backoff untuk memproses kesalahan pembatasan laju yang dikembalikan saat operasi Decrypt dipanggil.
Anda dapat membuat modifikasi sederhana pada kode untuk memproses beberapa kesalahan server tertentu, seperti kesalahan HTTP 503.
Anda dapat memperkirakan jumlah permintaan yang akan dimulai oleh klien dalam periode waktu tertentu. Kemudian, sesuaikan penundaan awal (
initialDelay) dan jumlah maksimum percobaan ulang (maxRetries) dalam kode berdasarkan hasil estimasi.
Pasangan AccessKey dari akun Alibaba Cloud memiliki izin untuk semua operasi API. Menggunakan pasangan AccessKey untuk melakukan operasi adalah operasi berisiko tinggi. Selain itu, gunakan pengguna RAM untuk memanggil operasi API atau melakukan O&M rutin. Kami menyarankan agar Anda tidak menyimpan ID AccessKey dan Rahasia AccessKey di kode proyek Anda. Jika Anda melakukannya, pasangan AccessKey mungkin bocor dan keamanan semua sumber daya yang dimiliki oleh akun Anda mungkin terganggu.
Dalam contoh ini, pasangan AccessKey disimpan dalam variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET untuk mengimplementasikan autentikasi identitas.
Untuk informasi lebih lanjut tentang cara mengonfigurasi informasi autentikasi, lihat Kelola Kredensial Akses.
Metode yang digunakan untuk mengonfigurasi variabel lingkungan bervariasi berdasarkan sistem operasi. Untuk informasi lebih lanjut, lihat Konfigurasikan Variabel Lingkungan di Linux, macOS, dan Windows.
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpClientConfig;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.kms.model.v20160120.DecryptRequest;
import com.aliyuncs.kms.model.v20160120.DecryptResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
public class CmkDecrypt {
private static DefaultAcsClient kmsClient;
private static DefaultAcsClient kmsClient(String regionId, String accessKeyId, String accessKeySecret) {
IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
HttpClientConfig clientConfig = HttpClientConfig.getDefault();
profile.setHttpClientConfig(clientConfig);
return new DefaultAcsClient(profile);
}
private static String kmsDecrypt(String cipherTextBlob) throws ClientException {
final DecryptRequest request = new DecryptRequest();
request.setSysProtocol(ProtocolType.HTTPS);
request.setAcceptFormat(FormatType.JSON);
request.setSysMethod(MethodType.POST);
request.setCiphertextBlob(cipherTextBlob);
DecryptResponse response = kmsClient.getAcsResponse(request);
return response.getPlaintext();
}
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) {
String regionId = "xxxxx"; //"cn-shanghai"
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
String cipherTextBlob = "xxxxxx";
int maxRetries = 5;
kmsClient = kmsClient(regionId, accessKeyId, accessKeySecret);
for (int i = 0; i < maxRetries; i++) {
try {
String plainText = kmsDecrypt(cipherTextBlob);
return;
} catch (ClientException e) {
if (e.getErrCode().contains("Rejected.Throttling")) {//perlu mencoba ulang
try {
Thread.sleep(getWaitTimeExponential(i + 1));
} catch (InterruptedException ignore) {
}
}
}
}
}
}