基于 Swift 的无服务器函数:高级 AWS Lambda

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

基于 Swift 的无服务器函数:高级 AWS Lambda



使用 Swift 开发无服务器应用程序正变得越来越受欢迎。在本指南中,我们将探讨使用 AWS Lambda 的高级技术:异步处理器、与 VPC 的集成、创建自定义层 (Layers) 以及配置监控。本材料面向已经熟悉 Swift 和 AWS Lambda 基础的开发人员。



1. 异步处理器 (async/await)



现代 Swift 通过 async/await 支持异步。AWS Lambda SDK 允许使用此模型,这大大简化了与输入/输出和外部服务的交互。



基本异步处理器:



import AWSLambdaRuntimeimport AWSLambdaEvents

struct AsyncHandler: LambdaHandler { typealias Event = APIGatewayV2Request typealias Output = APIGatewayV2Response

func handle(_ event: APIGatewayV2Request, context: LambdaContext) async throws -> APIGatewayV2Response { let result = await fetchData(from: "https://api.example.com/data") return APIGatewayV2Response(statusCode: .ok, body: result) }

private func fetchData(from url: String) async -> String { // 模拟异步请求 try? await Task.sleep(nanoseconds: 100_000_000) return "{\\"status\\": \\"ok\\", \\"data\\": \\"\\(url)\\"}" }}


并行处理:



func handle(_ event: APIGatewayV2Request, context: LambdaContext) async throws -> APIGatewayV2Response {    async let user = fetchUser(id: event.queryParameters?["userId"] ?? "")    async let orders = fetchOrders(userId: event.queryParameters?["userId"] ?? "")

let (userData, ordersData) = try await (user, orders) let combined = """ { "user": \\(userData), "orders": \\(ordersData) } """ return APIGatewayV2Response(statusCode: .ok, body: combined)}


使用 Task 可以精细控制优先级和操作取消。这在处理缓慢的外部 API 时至关重要。



2. 与 VPC 集成及安全性



基于 Swift 的 Lambda 函数可以在 VPC 内运行,以访问私有资源(RDS、ElastiCache)。然而,由于需要创建 ENI,这会使冷启动时间增加 5-10 秒。



高级 VPC 配置:



  • 最小化子网: 仅在不同可用区中使用 2-3 个子网。
  • NAT 网关: 如果需要访问互联网,请务必在公有子网中配置 NAT 网关。
  • VPC 终端节点: 对于 AWS 服务(S3、DynamoDB、SQS),请使用 VPC 终端节点而不是 NAT。
  • 安全组: 配置最小必要的规则(仅针对特定端口的入站/出站规则)。


通过 VPC 连接到 RDS 的示例:



import Vaporimport MySQLNIO

struct DatabaseHandler: LambdaHandler { typealias Event = APIGatewayV2Request typealias Output = APIGatewayV2Response

private let db: MySQLConnection

init(context: LambdaInitializationContext) async throws { let eventLoop = context.eventLoop self.db = try await MySQLConnection.connect( to: .init(hostname: "private-rds-endpoint", port: 3306), username: "admin", password: "secret", database: "mydb", on: eventLoop ).get() }

func handle(_ event: APIGatewayV2Request, context: LambdaContext) async throws -> APIGatewayV2Response { let rows = try await db.simpleQuery("SELECT * FROM users LIMIT 10") let jsonData = try JSONEncoder().encode(rows) return APIGatewayV2Response(statusCode: .ok, body: String(data: jsonData, encoding: .utf8) ?? "[]")

博客

书籍推荐