Azure Functions #
什么是 Azure Functions? #
Azure Functions 是一种无服务器计算服务,让你无需管理基础设施即可运行事件触发的代码。
text
┌─────────────────────────────────────────────────────────────┐
│ Azure Functions 概览 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 特点 │
│ ├── 无服务器:无需管理服务器 │
│ ├── 事件驱动:按触发器执行 │
│ ├── 按需计费:只为执行时间付费 │
│ ├── 自动扩展:根据负载自动调整 │
│ └── 多语言支持:C#, Java, JavaScript, Python 等 │
│ │
│ 适用场景 │
│ ├── Web API 后端 │
│ ├── 数据处理管道 │
│ ├── 事件处理 │
│ ├── 定时任务 │
│ ├── IoT 处理 │
│ └── 微服务 │
│ │
└─────────────────────────────────────────────────────────────┘
托管计划 #
计划类型 #
text
┌─────────────────────────────────────────────────────────────┐
│ 托管计划 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 消耗计划 (Consumption) │
│ ├── 按执行次数和时间计费 │
│ ├── 自动扩展 │
│ ├── 免费额度:100 万次请求/月 │
│ └── 适合:间歇性、不可预测的工作负载 │
│ │
│ 高级计划 (Premium) │
│ ├── 预热实例 │
│ ├── VNet 集成 │
│ ├── 更高性能 │
│ └── 适合:企业级应用 │
│ │
│ App Service 计划 │
│ ├── 专用资源 │
│ ├── 无冷启动 │
│ ├── 与其他应用共享 │
│ └── 适合:持续高负载 │
│ │
│ 容器计划 (Azure Container Apps) │
│ ├── 容器化函数 │
│ ├── 自定义运行时 │
│ └── 适合:复杂依赖 │
│ │
└─────────────────────────────────────────────────────────────┘
定价对比 #
| 计划 | 免费额度 | 冷启动 | VNet | 预热实例 |
|---|---|---|---|---|
| 消耗 | 100 万请求/月 | 有 | ❌ | ❌ |
| 高级 | 无 | 无 | ✅ | ✅ |
| App Service | 按计划 | 无 | ✅ | ✅ |
触发器和绑定 #
触发器类型 #
text
┌─────────────────────────────────────────────────────────────┐
│ 常用触发器 │
├─────────────────────────────────────────────────────────────┤
│ │
│ HTTP 触发器 │
│ ├── REST API 端点 │
│ ├── Webhook 接收 │
│ └── 最常用的触发器 │
│ │
│ 定时器触发器 │
│ ├── Cron 表达式 │
│ ├── 定时任务 │
│ └── 批处理作业 │
│ │
│ 队列触发器 │
│ ├── Azure Storage Queue │
│ ├── Service Bus Queue │
│ └── 消息处理 │
│ │
│ Blob 触发器 │
│ ├── 文件上传处理 │
│ ├── 图片处理 │
│ └── 数据导入 │
│ │
│ 事件触发器 │
│ ├── Event Grid │
│ ├── Event Hub │
│ └── IoT Hub │
│ │
└─────────────────────────────────────────────────────────────┘
绑定类型 #
| 绑定方向 | 类型 | 用途 |
|---|---|---|
| 输入 | Blob | 读取文件 |
| 输入 | Cosmos DB | 查询数据 |
| 输入 | SQL | 查询数据库 |
| 输出 | Queue | 发送消息 |
| 输出 | Blob | 写入文件 |
| 输出 | SendGrid | 发送邮件 |
创建函数应用 #
使用 Azure CLI #
bash
# 创建资源组
az group create --name myResourceGroup --location eastus
# 创建存储账户
az storage account create \
--name mystorageaccount \
--resource-group myResourceGroup \
--location eastus \
--sku Standard_LRS
# 创建函数应用
az functionapp create \
--name myFunctionApp \
--resource-group myResourceGroup \
--consumption-plan-location eastus \
--runtime node \
--runtime-version 18 \
--functions-version 4 \
--storage-account mystorageaccount
函数应用结构 #
text
myFunctionApp/
├── host.json # 函数应用配置
├── local.settings.json # 本地设置
├── package.json # Node.js 依赖
└── src/
└── functions/
├── HttpTrigger/
│ ├── function.json # 函数绑定配置
│ └── index.js # 函数代码
└── TimerTrigger/
├── function.json
└── index.js
开发函数 #
HTTP 触发器函数 #
javascript
// src/functions/HttpTrigger/index.js
module.exports = async function (context, req) {
context.log('HTTP trigger function processed a request.');
const name = req.query.name || (req.body && req.body.name);
const responseMessage = name
? "Hello, " + name + ". This HTTP triggered function executed successfully."
: "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";
context.res = {
status: 200,
body: responseMessage
};
};
json
// src/functions/HttpTrigger/function.json
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get", "post"]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
定时器触发器函数 #
javascript
// src/functions/TimerTrigger/index.js
module.exports = async function (context, myTimer) {
const timeStamp = new Date().toISOString();
if (myTimer.isPastDue) {
context.log('Timer is running late!');
}
context.log('Timer trigger function ran!', timeStamp);
};
json
// src/functions/TimerTrigger/function.json
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
}
]
}
Blob 触发器函数 #
javascript
// src/functions/BlobTrigger/index.js
module.exports = async function (context, myBlob) {
context.log("JavaScript blob trigger function processed blob \n Blob:", context.bindingData.blobTrigger, "\n Blob Size:", myBlob.length, "Bytes");
// 处理文件内容
const content = myBlob.toString();
// 输出到队列
context.bindings.outputQueueItem = {
blobName: context.bindingData.blobTrigger,
size: myBlob.length,
processedAt: new Date().toISOString()
};
};
json
// src/functions/BlobTrigger/function.json
{
"bindings": [
{
"name": "myBlob",
"type": "blobTrigger",
"direction": "in",
"path": "samples-workitems/{name}",
"connection": "AzureWebJobsStorage"
},
{
"name": "outputQueueItem",
"type": "queue",
"direction": "out",
"queueName": "processed-blobs",
"connection": "AzureWebJobsStorage"
}
]
}
本地开发 #
开发环境设置 #
bash
# 安装 Azure Functions Core Tools
npm install -g azure-functions-core-tools@4
# 安装 Azure CLI 扩展
az extension add --name azure-functions
# 创建新函数应用
func init MyFunctionApp --javascript
# 创建新函数
func new --name HttpTrigger --template "HTTP trigger" --authlevel "function"
# 本地运行
func start
local.settings.json #
json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "node",
"MyDbConnection": "Server=localhost;Database=mydb;User Id=sa;Password=pass;"
},
"Host": {
"LocalHttpPort": 7071,
"CORS": "*"
}
}
部署函数 #
部署方式 #
bash
# 部署到 Azure
func azure functionapp publish myFunctionApp
# 使用 Azure CLI 部署
az functionapp deployment source config-zip \
--name myFunctionApp \
--resource-group myResourceGroup \
--src deployment.zip
# 从 GitHub 部署
az functionapp deployment source config \
--name myFunctionApp \
--resource-group myResourceGroup \
--repo-url https://github.com/user/repo \
--branch main \
--manual-integration
GitHub Actions 部署 #
yaml
# .github/workflows/azure-function.yml
name: Build and deploy to Azure Function App
on:
push:
branches: [ "main" ]
workflow_dispatch:
env:
AZURE_FUNCTIONAPP_NAME: myFunctionApp
AZURE_FUNCTIONAPP_PACKAGE_PATH: '.'
NODE_VERSION: '18.x'
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build --if-present
- name: Deploy to Azure Function App
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}
配置管理 #
应用设置 #
bash
# 设置应用设置
az functionapp config appsettings set \
--name myFunctionApp \
--resource-group myResourceGroup \
--settings KEY1=VALUE1 KEY2=VALUE2
# 从文件导入
az functionapp config appsettings set \
--name myFunctionApp \
--resource-group myResourceGroup \
--settings @settings.json
访问配置 #
javascript
// Node.js
const dbConnection = process.env.MyDbConnection;
const apiKey = process.env.ApiKey;
// Python
import os
db_connection = os.environ['MyDbConnection']
api_key = os.environ['ApiKey']
监控和诊断 #
启用 Application Insights #
bash
# 创建 Application Insights
az monitor app-insights component create \
--app myFunctionApp-ai \
--location eastus \
--resource-group myResourceGroup
# 关联函数应用
az functionapp config appsettings set \
--name myFunctionApp \
--resource-group myResourceGroup \
--settings APPINSIGHTS_INSTRUMENTATIONKEY=<instrumentation-key>
查看日志 #
bash
# 实时日志流
az functionapp log tail \
--name myFunctionApp \
--resource-group myResourceGroup
# 查看执行历史
az functionapp function show \
--name myFunctionApp \
--resource-group myResourceGroup \
--function-name HttpTrigger
最佳实践 #
性能优化 #
text
┌─────────────────────────────────────────────────────────────┐
│ 性能优化建议 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 避免冷启动 │
│ ├── 使用 Premium 计划 │
│ ├── 保持函数精简 │
│ └── 预热实例 │
│ │
│ 2. 连接管理 │
│ ├── 重用连接 │
│ ├── 使用连接池 │
│ └── 静态客户端 │
│ │
│ 3. 异步处理 │
│ ├── 使用队列 │
│ ├── 分解长任务 │
│ └── Durable Functions │
│ │
│ 4. 依赖优化 │
│ ├── 减少依赖数量 │
│ ├── 使用轻量库 │
│ └── 按需加载 │
│ │
└─────────────────────────────────────────────────────────────┘
代码示例 #
javascript
// 重用连接的最佳实践
const cosmosClient = require('@azure/cosmos').CosmosClient;
// 在函数外部创建客户端(重用)
let client = null;
function getClient() {
if (!client) {
client = new cosmosClient(process.env.COSMOS_CONNECTION_STRING);
}
return client;
}
module.exports = async function (context, req) {
const client = getClient();
const container = client.database('mydb').container('mycontainer');
// 使用客户端
const { resource } = await container.item(req.body.id).read();
context.res = { body: resource };
};
下一步 #
现在你已经掌握了 Azure Functions 的使用,接下来学习 容器服务 了解 Azure 容器解决方案!
最后更新:2026-03-29