亞馬遜Web服務讓企業相信他們擁有了自己的私有資源,但是有時候共享云系統反咬一口虔誠的企業。在亞馬遜Web服務EC2實例中會看到一個錯誤RequestLimitExceeded,這也是反咬企業的錯誤之一。
通常,虛擬機上運行的工作負載對于亞馬遜Web服務(AWS)彈性計算云(EC2)實例被遺忘的事實是,這是一個使用基礎物理計算機資源的hypervisor的子系統。換句話說,可能存在數十個或者數百個微實例運行在亞馬遜硬件的每一個實際部分上。
如果你操作你自己的實例,你并不能實際影響其他的AWS EC2實例,直到你開始進行請求或者調用AWS EC2應用程序接口(API)。不管什么時候你進行了AWS調用,你都在對所有實例共享的系統放置一個小的需求。如果你創建了一個無限循環的運行實例列表請求,相對其他用戶嘗試進行AWS調用,你可以創建一個拒絕服務環境。
因此,如果你進行了過多的AWS調用,你的調用就會出現RequestLimitExceeded錯誤。然而,AWS并沒有明確多少調用算“過多”,很可能是因為這是一個復雜的且未公開的算法,AWS也有待進一步開發。但是這意味著沒辦法預測什么時候這個錯誤會發生。
圍繞AWS EC2錯誤編碼 這里有一個可以用來避免運行出這個錯誤的方法。 首先將AWS作為有約束的資源考慮,而且往返周期昂貴。正如你無法一次按字節閱讀一個文件,不要在一個小的組塊中詢問AWS。
如果你希望了解正在運行的每一個實例,可以對每一個實例運行一個單獨的AWS調用,或者使用靈活的API來針對AWS EC2實例列表的信息進行單獨請求。第一種方法更有可能導致問題。
第二種選擇是考慮你多久需要更新一下請求的AWS數據。假定你正在收集實例數據來進行手動擴展決定。頻繁更新數據增加了精準度,知道你收到了請求拒絕提示,而且不得不以指數方式退下。要平衡你所請求的數據頻率。
然而,在做了這些時候,所有的AWS調用需要防止請求限制異常,你必須決定如何處理。一些調用可以失敗,而且你可以基于邏輯嘗試一次;其他的調用需要局部再次嘗試直到成功為止。
對于第二種情況,很多管理員會編寫類似的代碼:
int backOffFactor = 0;
while(true) {
try {
amazonClient.someCall();
break;
} catch(AmazonServiceException e) {
if(e.getErrorCode().equalsIgnoreCase("RequestLimitExceeded")) {
quietSleepSeconds(++backOffFactor); } }
這個代碼是一種改進的強制性重傳延遲,通過使用重試之間的更長周期的休眠實現,使用一個實用功能來完成,即所有的管理員編寫休眠和捕捉/忽略“InterruptedException”,直到“過多”情況消失。你可以調整多快增加休眠時間,而且也可以創建最高上限限制休眠時間。
這并不是完美的代碼,而且可以作為一個lambda表達式在這些語言支持閉包中處理,但是表達了基本的意圖:假設失敗的可能,并且放慢失敗直到系統停止抱怨。