使用断路器模式与 AWS Lambda

利用Circuit Breaker模式与AWS Lambda扩展和Amazon DynamoDB

by 于2024年5月16日发布于、[AWSLambda](https://aws.amazon.com/blogs/compute/category/compute/aws- lambda/"查看所有AWSLambda文章")、
分享

这篇文章由Alan Oberto Jimenez(高级云应用架构师)和Tobias Drees(云应用架构师)撰写。

重点内容

  • 现代软件系统依赖于网络中的远程调用,关键在于避免故障蔓延和服务中断。
  • Circuit Breaker模式可以检测并隔离分布式系统中的故障,从而提高系统稳定性和响应速度。
  • 本文展示了如何通过AWS Lambda扩展与Amazon DynamoDB实现Circuit Breaker模式的示例应用。

现代软件系统常常依赖网络中与其他系统的远程调用。当发生故障时,可能会导致多个服务的连锁故障,从而造成服务中断。而CircuitBreaker模式是缓解这种风险的一种技术,能够检测并隔离分布式系统中的故障。此模式的应用不仅可以防止故障的连锁反应,还能提高整体系统的稳定性。

通过隔离故障的服务,CircuitBreaker模式可以改善系统的响应速度,避免超时等待的长时间延迟。此外,它还提高了系统的容错能力,因为当服务恢复可用时,系统能够重新与其交互。

本文将展示一个示例应用,展示如何利用与结合实现Circuit Breaker模式。

利用Lambda扩展实现Circuit Breaker模式

提供了一种方法,可以将监控、可观察性、安全及管理工具集成到Lambda执行环境中,而无需复杂的安装和配置管理。你可以将扩展作为运行时进程的一部分,或作为执行环境中的独立进程运行。

Lambda扩展可以在不修改核心功能代码的情况下实现CircuitBreaker模式。一种外部扩展会在单独的运行时检查某个服务是否可达。这种方法将Lambda函数中的业务逻辑与故障检测解耦,使该Lambda扩展可以在不同的Lambda函数之间重用。这种将不同目的代码解耦和代码复用的方式符合构建Lambda函数的最佳实践。

每次执行Lambda时,对微服务的ping会增加网络流量和延迟。CircuitBreaker的实现中,利用一个缓存层来存储微服务的状态。Lambda扩展从数据库中获取微服务的状态,并在内存中缓存结果,避免了磁盘写入。Lambda函数在ping微服务之前会检查扩展的缓存,这样可以减少网络流量。Lambda扩展是构建的理想工具,因为其内存缓存比直接调用网络资源更安全、更易于管理且性能更高。

概览

删除)

  1. 主函数进程在每次调用后处理事件。在对外部组件进行任何调用之前,它会监听来自Lambda扩展进程的HTTP POST事件,以获取电路的最新状态。
  2. 扩展进程通过HTTP POST将电路状态提供给主进程。
  3. 扩展检查其内部缓存,如有有效值则返回,否则从DynamoDB表中读取电路状态并更新缓存。
  4. 最后,扩展进程通过API调用向主函数返回电路状态。
  5. 由于Lambda扩展的生命周期,这一过程会定期发生,以保持本地缓存的更新,直到执行环境终止。
  6. 如果电路处于开放(OPEN)状态,主函数进程将对外部微服务进行调用,否则它将返回本地响应。
  7. 事件定期触发一个Lambda函数,用于更新电路状态。
  8. 这个Lambda函数进行必要的验证,以确定不同远程微服务(电路)的状态,使用作为进入点。
  9. Lambda函数将验证过程的结果写入DynamoDB表中。

步骤演示

以下是完成演示所需的条件:

  • 一个有效的AWS账户
  • AWS CLI 2.15.17或更高版本
  • AWS SAM CLI 1.116.0或更高版本
  • Git 2.39.3或更高版本
  • Python 3.12

初始设置

  1. 从GitHub克隆代码到本地机器:

bash git clone https://github.com/aws-samples/implementing-the-circuit- breaker-pattern-with-lambda-extensions-and-dynamodb.git

  1. 使用虚拟环境安装所需包:

bash python -m venv circuit_breaker_venv && sourcecircuit_breaker_venv/bin/activate

  1. 执行以下命令以准备服务进行部署:

bash sam build

  1. 使用以下命令部署服务,同时指定要在其上部署服务的AWS账户的AWS CLI配置文件(在.aws文件夹中的配置文件):

bash sam deploy --guided --profile <AWSProfile>

请根据需要回答问题提示。

  1. 之后可以使用下列命令部署本地代码的后续更改:

bash sam build sam deploy

测试与调整解决方案

更新DynamoDB状态的Lambda函数每分钟运行一次,按照模板的规定。在第一次运行后,DynamoDB中包含状态(“OPEN”或“CLOSED”)的条目就准备好了。因为模拟API是堆栈的一部分,所以状态为“OPEN”。

你可以手动调用_我的微服务_ Lambda函数以查看:

删除)

更新DynamoDB状态的Lambda函数通过EventBridge规则触发,该规则指定要监控的服务的URL和ID。通过创建新的EventBridge规则并指定正确的URL和新的ID,你可以使用AWSSAM模板监控多个服务。

要添加新的EventBridge规则,请在模板中添加以下内容:

触发Lambda函数的事件规则,包含JSON有效负载 ScheduleExpression: rate(1 minute) State: ENABLEDTargets: \- Arn: !GetAtt UpdatingStateLambda.Arn Id: TargetFunction Input: '{
"URL": "https://aws.amazon.com/", "ID": "NewMicroservice"}' # 在此处添加JSON有效负载

MyPermissionForNewEventRule: Type: AWS::Lambda::Permission Properties:
FunctionName: !Ref UpdatingStateLambda Action: lambda:InvokeFunctionPrincipal: events.amazonaws.com SourceArn: !GetAtt NewEventRule.Arn  

在包含业务逻辑的Lambda函数中,添加以下环境变量。对于需要监控多个微服务的复杂情况,建议使用。使用AWSConfig,可以存储Lambda函数的配置,以比环境变量提供更细粒度的控制。

yaml Environment: Variables: service_name: "NewMicroservice"

你可以通过更改my-microservice/lambda-handler.py或者直接在AWS管理控制台的Lambda部分更改此Lambda函数的逻辑。

如果最终使用自己的Lambda函数来使用Circuit Breaker Lambda扩展,请将Circuit Breaker扩展作为层包含在内:

yaml BusinessLogicMicroservice: Type: AWS::Serverless::Function Properties: CodeUri: business-logic-microservice/ Handler: lambda_function.lambda_handlerMemorySize: 128 Policies: - DynamoDBCrudPolicy: TableName: !RefCircuitBreakerStateTable Timeout: 100 Runtime: python3.8 Layers: - !RefCircuitBreakerExtensionLayer

Circuit Breaker在关闭状态

目前,示例应用仅展示了一个开放电路的状态,表示微服务正常运作。本节将模拟无响应的微服务,测试系统在关闭电路(CLOSED)状态下的行为。

  1. 在文件第47行编辑MyMicroservice Lambda函数的环境变量,将更新电路状态的Lambda输入的URL(在第107行)更改为超时的域名,例如"https://aws.amazon.com:81/"。

yaml API_URL: "https://aws.amazon.com:81/" Input: '{ "URL": "https://aws.amazon.com:81/", "ID": "MyMicroservice"}'

  1. 部署这些更改:

bash sam build sam deploy

该事件规则每分钟触发Lambda函数,更新状态。要查看此Lambda函数的输出,可以手动调用它:

删除)

此Lambda函数将该URL的DynamoDB条目更改为:

删除)

MyMicroservice Lambda函数通过Circuit BreakerLambda扩展从DynamoDB接收状态,并在关闭状态下继续执行逻辑。手动调用Lambda的输出为:

删除)

这显示Circuit Breaker模式按预期工作。在更新状态的Lambda中,Lambda函数抛出超时异常所需的时间定义为4秒,可根据用例进行调整。

python requests.get(API_URL, headers=headers, timeout=4)

清理

要删除此堆栈中的所有资源,请运行:

bash sam delete --stack-name new-circuit-breaker-sam-stack

安全

提供的AWSSAM模板未提供可以托管资源的。如果在生产应用中使用,请将资源集成到适当的网络配置中。

该解决方案具备审计特性,Circuit Breaker和微服务的调用记录到日志组中。审计日志使用加密。

要监控解决方案的账户安全,可以使用、、AWS Config以及来保护API Gateway。

结论

CircuitBreaker模式是帮助确保无服务器应用弹性和稳定性的强大工具。正如本示例所示,Lambda扩展非常适合其实现。通过提供的Lambda扩展和代码,你可以将CircuitBreaker模式集成到你的应用中,并根据具体需求进行定制,从而确保系统的健壮性和可靠性。

如需获取更多无服务器学习资源,请访问。

标签: 、

Leave a Reply

Required fields are marked *