前端架构:从基础到微前端
Python代码段逐步指南
我第一次将EC2实例名称记录到PagerDuty和Airbrake的尝试破坏了我们的大多数基础架构。 我无法解释未发布的AWS速率限制,并且当意外数量的错误导致我的代码达到这些速率限制时,错误处理不足会导致在异常记录器中引发错误时发生无限循环。
我希望本教程可以使您免于头痛。 我将向您介绍如何使用boto3 Python客户端从该实例访问正在运行的EC2实例的名称,并一路包括警告和陷阱,以帮助您避免一些错误。
先决条件
- Boto3 。 本教程假定您熟悉使用AWS的boto3 Python客户端,并且已按照AWS的说明配置了AWS凭证。
- Requests ,一个Python HTTP库。
获取实例ID和区域
boto3实例资源可访问有关实例的大多数信息。 要创建该资源,我们首先需要检索实例ID和实例区域。
AWS通过URL http://169.254.169.254提供了实例元数据和用户数据 ,您可以从任何运行的EC2实例中请求。 特别是,我们对实例身份文档感兴趣,该文档可从http://169.254.169.254/latest/dynamic/instance-identity/document访问。
import requests
r = requests.get("http://169.254.169.254/latest/dynamic/instance-identity/document")
response_json = r.json()
region = response_json.get('region')
instance_id = response_json.get('instanceId')
如果您不熟悉requests库,建议您检出“ 响应状态代码” ,尤其是raise_for_status函数,作为错误处理的起点。
获取实例资源
然后,我们可以使用实例ID和区域来检索boto3实例资源 。
import boto3
ec2 = boto3.resource('ec2', region_name=region)
instance = ec2.Instance(instance_id)
在将它们传递给boto3之前验证region和instance_id
boto3错误处理的第一步是捕获同时在botocore.exceptions包中找到的ClientError和BotoCoreError 。
以我的经验, boto3客户端对于无效或“ None区域或实例ID的错误处理非常混乱。 除了上述错误外, None一个字段中的None值都将引发Python内置的ValueError 。 如果region && instance_id为false,我建议您不要尝试使用boto3客户端。
取得名字
实例的“名称”实际上是带有键“名称”的实例标签。 您可以从实例资源中检索标签,并过滤Name标签。
tags = instance.tags or []
names = [tag.get('Value') for tag in tags if tag.get('Key') == 'Name']
name = names[0] if names else None
由于属性是延迟加载的,因此某些无效的实例ID会在此处引发错误
根据boto3文档 ,资源属性是延迟加载的,这意味着在首次访问该属性时会进行第一个API调用。 这意味着,虽然在创建ec2.Instance资源时会验证None或空字符串,但将使用第一个DescribeInstances调用在此处验证类型正确但值错误的非空字符串ID。 为了解决这个问题,您将尝试捕获上一节中的botocore.exceptions异常。
知道了!
从EC2陷阱和限制的 “ AWS的开放指南”部分中:
❗如果EC2 API本身是基础架构的关键依赖项(例如,用于自动服务器更换,自定义扩展算法等)并且您正在大规模运行或进行许多EC2 API调用,请确保您了解它们何时可能失败(对它的调用受到速率的限制,并且不会发布限制,并且可能会更改),并针对这种可能性进行编码和测试。
boto3客户端通过DescribeInstances API调用加载有关实例的信息。 例如,如果您每次登录错误时都进行此API调用以检索实例名称,则可以轻松达到DescribeInstances速率限制。
除了上述错误处理之外,您还需要合并对AWS API的调用,以避免达到未发布的AWS速率限制。 我们的解决方案是在API服务器启动时一次获取实例名称,并将结果缓存在全局数据结构中。 现在,我们无需在每次需要记录错误时都调用EC2 API,而仅在将新代码部署到计算机时才调用一次。
放在一起
这是最终的get_instance_name
函数的外观示例。
前端架构:从基础到微前端