亚马逊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表达式在这些语言支持闭包中处理,但是表达了基本的意图:假设失败的可能,并且放慢失败直到系统停止抱怨。