在此阶段,完成将工作负荷从 AWS Lambda 迁移到 Azure Functions。 目标是调整函数代码以实现兼容性和最佳做法、迁移工作负载、测试性能、优化作,以及实现对可靠性和效率的监视。
将函数代码、配置文件和基础结构调整为代码文件
需要调整函数代码、配置文件和基础结构即代码(IaC)文件,以遵循 Azure Functions 编程模型和最佳做法。 此步骤有助于确保工作负荷与 Azure Functions 兼容。
更新 Azure Functions 运行时要求的代码:
修改代码以遵守 Azure Functions 编程模型。 例如,调整函数签名以匹配 Azure Functions 所需的格式。 有关函数定义和执行上下文的详细信息,请参阅 Azure Functions 开发人员指南。
使用 Azure Functions 扩展捆绑包 来处理类似于 AWS 服务的各种绑定和触发器。 对于 .NET 应用程序,应使用相应的 NuGet 包,而不是扩展捆绑包。
使用扩展捆绑包与其他 Azure 服务(例如 Azure 存储、Azure 服务总线和 Azure Cosmos DB)集成,而无需通过 SDK 手动配置每个绑定。 有关详细信息,请参阅 使用绑定将函数连接到 Azure 服务 和 Azure Functions 绑定表达式模式。
以下代码片段是常见 SDK 代码的示例。 AWS Lambda 代码映射到 Azure Functions 中的相应触发器、绑定或 SDK 代码片段。
从 Amazon S3 与 Azure Blob 存储读取数据
AWS Lambda 代码 (SDK)
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
exports.handler = async (event) => {
const params = {
Bucket: 'my-bucket',
Key: 'my-object.txt',
};
const data = await
s3.getObject(params).promise();
console.log('File content:',
data.Body.toString());
};
Azure Functions 代码(触发器)
import { app } from '@azure/functions';
app.storageblob('blobTrigger', {
path: 'my-container/{blobName}',
connection: 'AzureWebJobsStorage',
}, async (context, myBlob) => {
context.log(`Blob content:
${myBlob.toString()}`);
});
写入 Amazon Simple Queue Service (SQS) 与 Azure 队列存储
AWS Lambda 代码 (SDK)
const AWS = require('aws-sdk');
const sqs = new AWS.SQS();
exports.handler = async (event) => {
const params = {
QueueUrl:
'https://sqs.amazonaws.com/123456789012/MyQueue',
MessageBody: 'Hello, world!',
};
await
sqs.sendMessage(params).promise();
};
Azure Functions 代码(触发器)
import { app } from '@azure/functions';
app.queue('queueTrigger', {
queueName: 'myqueue-items',
connection: 'AzureWebJobsStorage',
}, async (context, queueMessage) => {
context.log(`Queue message:
${queueMessage}`);
});
将数据写入 DynamoDB 与 Azure Cosmos DB 的比较
AWS Lambda 代码 (SDK)
const AWS = require('aws-sdk');
const dynamoDb = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event) => {
const params = {
TableName: 'my-table',
Key: { id: '123' },
};
const data = await dynamoDb.get(params).promise();
console.log('DynamoDB record:', data.Item);
};
Azure Functions 代码(触发器)
import { app } from '@azure/functions';
app.cosmosDB('cosmosTrigger', {
connectionStringSetting: 'CosmosDBConnection',
databaseName: 'my-database',
containerName: 'my-container',
leaseContainerName: 'leases',
}, async (context, documents) => {
documents.forEach(doc => {
context.log(`Cosmos DB document: ${JSON.stringify(doc)}`);
});
});
Amazon CloudWatch 事件与 Azure 计时器触发器
AWS Lambda 代码 (SDK)
exports.handler = async (event) => {
console.log('Scheduled event:', event);
};
Azure Functions 代码(触发器)
import { app } from '@azure/functions';
app.timer('timerTrigger', { schedule: '0 */5 * * * *', // Runs every 5 minutes }, async (context, myTimer) => { if (myTimer.isPastDue) { context.log('Timer is running late!'); } context.log(Timer function executed at: ${new Date().toISOString()}); });
Amazon Simple Notification Service (SNS) 与 Azure 事件网格触发器
AWS Lambda 代码 (SDK)
const AWS = require('aws-sdk');
const sns = new AWS.SNS();
exports.handler = async (event) => {
const params = {
Message: 'Hello, Event Grid!',
TopicArn: 'arn:aws:sns:us-east-1:123456789012:MyTopic',
};
await sns.publish(params).promise();
};
Azure Functions 代码(触发器)
import { app } from '@azure/functions';
app.eventGrid('eventGridTrigger', {},
async (context, eventGridEvent) => {
context.log(`Event Grid event:
${JSON.stringify(eventGridEvent)}`);
});
Amazon Kinesis 与 Azure 事件中心触发器
AWS Lambda 代码 (SDK)
const AWS = require('aws-sdk');
const kinesis = new AWS.Kinesis();
exports.handler = async (event) => {
const records =
event.Records.map(record =>
Buffer.from(record.kinesis.data,
'base64').toString());
console.log('Kinesis records:', records);
};
Azure Functions 代码(触发器)
import { app } from '@azure/functions';
app.eventHub('eventHubTrigger', {
connection: 'EventHubConnection',
eventHubName: 'my-event-hub',
}, async (context, eventHubMessages) =>
{
eventHubMessages.forEach(message =>
{
context.log(`Event Hub message:
${message}`);
});
});
请参阅以下 GitHub 存储库来比较 AWS Lambda 代码和 Azure Functions 代码:
-
- 此存储库还包括适用于 Azure Functions 的初学者示例、IaC 和端到端示例。
调整配置设置
确保函数的超时和 内存 设置与 Azure Functions 兼容。 有关可配置设置的详细信息,请参阅 Azure Functionshost.json 参考。
遵循有关权限、访问、网络和部署配置的建议最佳做法。
配置权限
在为函数应用设置权限时,请遵循最佳做法。 有关详细信息,请参阅 使用托管身份验证配置存储帐户和函数应用。
main.bicep
// User-assigned managed identity that the function app uses to reach Storage and Service Bus
module processorUserAssignedIdentity './core/identity/userAssignedIdentity.bicep' = {
name: 'processorUserAssignedIdentity'
scope: rg
params: {
location: location
tags: tags
identityName: !empty(processorUserAssignedIdentityName) ? processorUserAssignedIdentityName : '${abbrs.managedIdentityUserAssignedIdentities}processor-${resourceToken}'
}
}
有关详细信息,请参阅 userAssignedIdentity.bicep。
配置网络访问
Azure Functions 支持 虚拟网络集成,使函数应用能够访问虚拟网络中的资源。 集成后,应用通过虚拟网络路由出站流量。 然后,应用可以使用仅允许来自特定子网的流量的规则访问专用终结点或资源。 如果目标是虚拟网络外部的 IP 地址,则源 IP 地址是应用属性中列出的地址之一,除非配置 NAT 网关。
为函数应用启用 虚拟网络集成 时,请遵循 TSG 中的最佳做法,实现 Web 应用和函数应用的虚拟网络集成。
main.bicep
// Virtual network and private endpoint
module serviceVirtualNetwork 'app/vnet.bicep' = {
name: 'serviceVirtualNetwork'
scope: rg
params: {
location: location
tags: tags
vNetName: !empty(vNetName) ? vNetName : '${abbrs.networkVirtualNetworks}${resourceToken}'
}
}
module servicePrivateEndpoint 'app/storage-PrivateEndpoint.bicep' = {
name: 'servicePrivateEndpoint'
scope: rg
params: {
location: location
tags: tags
virtualNetworkName: !empty(vNetName) ? vNetName : '${abbrs.networkVirtualNetworks}${resourceToken}'
subnetName: serviceVirtualNetwork.outputs.peSubnetName
resourceName: storage.outputs.name
}
}
有关详细信息,请参阅 VNet.bicep 和 storage-PrivateEndpoint.bicep。
配置部署设置
部署遵循单个路径。 生成项目代码并将其压缩到应用程序包后,将其部署到 Blob 存储容器。 启动后,应用会获取包,并从中运行函数代码。 默认情况下,存储内部主机元数据的同一存储帐户(例如 AzureWebJobsStorage
)也用作部署容器。 但是,可以使用备用存储帐户,也可以通过配置应用的部署设置来选择首选的身份验证方法。 有关详细信息,请参阅 部署技术详细信息 和 配置部署设置。
生成 IaC 文件
使用 Bicep、Azure 资源管理器模板或 Terraform 等工具创建 IaC 文件来部署 Azure 资源。
在 IaC 文件中定义 Azure Functions、存储帐户和网络组件等资源。
请使用此 IaC 示例存储库获取有关 Azure Functions 建议和最佳实践的示例。
使用重构工具
使用 Visual Studio Code 中的 GitHub Copilot 等工具来帮助进行代码重构、手动重构特定更改或其他迁移帮助。
有关每个步骤的详细信息,请参阅:
这些资源提供特定的示例和详细步骤,以帮助迁移过程。
部署并测试应用程序
执行工作负荷到 Azure Functions 的引导迁移,并测试部署的函数以验证其性能和正确性。
部署到 Azure 云
使用 VS Code 发布功能部署工作负载。 还可以使用 Azure Functions Core Tools 或 Azure CLI 从命令行部署工作负荷。 GitHub Actions 也使用 One Deploy。
- Azure Functions Core Tools:使用 Azure Functions Core Tools 通过 命令
func azure functionapp publish <FunctionAppName>
。
执行端到端测试
验证功能
彻底测试每个函数,以确保其按预期工作。 这些测试应包括输入/输出、事件触发器和绑定验证。
使用 VS Code 上的 curl 或 REST 客户端 扩展等工具发送 HTTP 触发的函数的 HTTP 请求。
对于其他触发器(如计时器或队列),请确保触发器正确触发,并且函数按预期运行。
验证性能
执行性能测试,将新的 Azure Functions 部署与以前的 AWS Lambda 部署进行比较。
监视响应时间、运行时和资源消耗等指标。
在测试阶段使用 Application Insights 进行 监视、日志分析和故障排除 。
优化和监视应用程序的性能
按照以下步骤有效地监视、排除故障并优化函数应用的性能和成本。
使用 Application Insights 进行监视和故障排除
为函数应用启用 Application Insights 以收集详细的遥测数据,以便进行监视和故障排除。 可以通过 Azure 门户或在函数应用的 host.json 配置文件中启用 Application Insights。 启用 Application Insights 后,可以:
收集遥测数据。 Application Insights 提供各种遥测数据,例如请求日志、性能指标、异常和依赖项。
分析日志和指标。 从 Azure 门户访问 Application Insights 仪表板,以可视化和分析日志、指标和其他遥测数据。 使用内置工具创建自定义查询并可视化数据,以便深入了解函数应用的性能和行为。
设置警报。 在 Application Insights 中配置警报,以通知严重问题、性能下降或特定事件。 这些警报可帮助你主动监视并快速响应问题。
针对成本和性能进行优化
缩放和性能优化:
使用自动缩放功能高效处理不同的工作负荷。
通过减少运行时、优化依赖项和使用高效的编码做法来优化函数代码以提高性能。
实现缓存策略,以减少频繁访问数据的重复处理和延迟。
成本管理:
使用 Microsoft成本管理工具 监视和分析 Azure Functions 成本。
设置预算和成本警报,以有效管理和预测费用。
开始吧
使用 MigrationGetStarted 存储库 作为模板开始概念验证。 此存储库包括一个现成部署的 Azure Functions 项目,其中包含基础结构和源代码文件,可帮助你入门。
如果希望使用 Terraform,请改用 MigrationGetStarted-Terraform 。