本文使用本地命令行工具创建响应 HTTP 请求的函数。 在本地验证代码后,将其部署到 Azure Functions 中的无服务器 Flex Consumption 托管计划。
完成本快速入门时会从你的 Azure 帐户中扣取小额费用,大约几美分或者更少。
- 拥有有效订阅的 Azure 帐户。 创建账户。
-
Java 17 开发人员工具包
- 如果使用另一个支持的 Java 版本,则必须更新项目的 pom.xml 文件。
- 环境变量
JAVA_HOME
必须设置为正确版本的 Java 开发工具包(JDK)的安装位置。
- Apache Maven 3.8.x
-
命令行
jq
JSON 处理器,用于分析 JSON 输出,也可以在 Azure Cloud Shell 中使用。
建议的 Core Tools 安装方法取决于本地开发计算机的操作系统。
以下步骤使用 APT 在 Ubuntu/Debian Linux 发行版上安装 Core Tools。 有关其他 Linux 发行版,请参阅 Core Tools 自述文件。
安装 Microsoft 包存储库 GPG 密钥,以验证包完整性:
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
在进行 APT 更新之前,设置 APT 源列表。
Ubuntu
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-$(lsb_release -cs)-prod $(lsb_release -cs) main" > /etc/apt/sources.list.d/dotnetdev.list'
Debian
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/debian/$(lsb_release -rs | cut -d'.' -f 1)/prod $(lsb_release -cs) main" > /etc/apt/sources.list.d/dotnetdev.list'
检查
/etc/apt/sources.list.d/dotnetdev.list
文件以获取下表中相应 Linux 版本字符串之一:Linux 发行版 版本 Debian 11 bullseye
Debian 10 buster
Debian 9 stretch
Ubuntu 22.04 jammy
Ubuntu 20.04 focal
Ubuntu 19.04 disco
Ubuntu 18.10 cosmic
Ubuntu 18.04 bionic
Ubuntu 17.04 zesty
Ubuntu 16.04/Linux Mint 18 xenial
启动 APT 源更新:
sudo apt-get update
安装 Core Tools 包:
sudo apt-get install azure-functions-core-tools-4
在适当的文件夹中,运行以下命令以创建并激活一个名为 .venv
的虚拟环境。 请确保使用 Python 3.8、3.7 或 3.6,这些版本受 Azure Functions 支持。
python -m venv .venv
source .venv/bin/activate
如果 Python 未在 Linux 分发版中安装 venv 包,请运行以下命令:
sudo apt-get install python3-venv
所有后续命令将在这个已激活的虚拟环境中运行。
在 Azure Functions 中,代码项目是一个应用,其中包含一个或多个每个函数响应特定触发器。 项目中的所有函数共享相同的配置,并将其部署为单元到 Azure。 在本部分中,将创建一个包含单个函数的代码项目。
在终端或命令提示符下,运行以下命令
func init
以在当前文件夹中创建函数应用项目:func init --worker-runtime dotnet-isolated
在终端或命令提示符下,运行以下命令
func init
以在当前文件夹中创建函数应用项目:func init --worker-runtime node --language javascript
在终端或命令提示符下,运行以下命令
func init
以在当前文件夹中创建函数应用项目:func init --worker-runtime powershell
在终端或命令提示符下,运行以下命令
func init
以在当前文件夹中创建函数应用项目:func init --worker-runtime python
在终端或命令提示符下,运行以下命令
func init
以在当前文件夹中创建函数应用项目:func init --worker-runtime node --language typescript
在空文件夹中,运行以下命令
mvn
,从 Azure Functions Maven 原型生成代码项目:mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=17
重要
- 如果希望函数在 Java 11 上运行,请使用
-DjavaVersion=11
。 若要了解详细信息,请参阅 Java 版本。 - 要完成本文中的步骤,
JAVA_HOME
环境变量必须设置为正确版本的 JDK 的安装位置。
- 如果希望函数在 Java 11 上运行,请使用
Maven 会请求你提供所需的值,以在部署上完成项目的生成。
系统提示时提供以下值:Prompt 价值 DESCRIPTION groupId com.fabrikam
一个值,用于按照 Java 的包命名规则在所有项目中标识你的项目。 artifactId fabrikam-functions
一个值,该值是 jar 的名称,没有版本号。 版本 1.0-SNAPSHOT
选择默认值。 包 com.fabrikam
一个值,该值是所生成函数代码的 Java 包。 使用默认值。 键入
Y
或按 Enter 进行确认。Maven 在一个名为artifactId的新文件夹中创建项目文件,在本示例中是
fabrikam-functions
。导航到项目文件夹:
cd fabrikam-functions
可以在 \src\main\java\com\fabrikam 项目目录中的 Function.java中查看新 HTTP 触发器函数的模板生成代码。
func new
使用此命令将函数添加到项目:func new --name HttpExample --template "HTTP trigger" --authlevel "anonymous"
新代码文件将添加到项目中。 在这种情况下,该
--name
参数是函数的唯一名称(HttpExample
),参数--template
指定 HTTP 触发器。
项目根文件夹包含项目的各种文件,包括名为 local.settings.json 和 host.json的配置文件。 由于 local.settings.json 可以包含从 Azure 下载的机密,因此该文件在 .gitignore 文件中默认从源代码管理中排除。
在本地运行项目并调用函数终结点来验证新函数。
使用此命令启动项目文件夹根目录中的本地 Azure Functions 运行时主机:
func start
func start
npm install npm start
mvn clean package mvn azure-functions:run
在输出的末尾,应显示以下行:
... Now listening on: http://0.0.0.0:7071 Application started. Press Ctrl+C to shut down. Http Functions: HttpExample: [GET,POST] http://localhost:7071/api/HttpExample ...
备注
如果 HttpExample 终结点未按预期显示,则可能是从项目的根文件夹外部启动主机。 在这种情况下,请使用 Ctrl+C 停止主机,导航到项目的根文件夹,然后再次运行上一个命令。
将此输出中的
HttpExample
函数 URL复制到浏览器中,并访问该URL,你应收到一条包含“hello world”消息的成功响应。完成后,使用 Ctrl+C 并选择
y
停止函数主机。
在将函数代码部署到 Azure 之前,需要创建以下资源:
- 一个资源组:相关资源的逻辑容器。
- 函数宿主使用的默认 存储帐户,用于维护有关函数的状态和其他信息。
- 用户分配的托管标识,Functions 主机使用该标识连接到默认存储帐户。
- 一个函数应用:提供用于执行函数代码的环境。 函数应用映射到本地函数项目,可让你将函数分组为一个逻辑单元,以便更轻松地管理、部署和共享资源。
使用这些步骤中的 Azure CLI 命令创建所需的资源。
请登录到 Azure(如果尚未这样做):
az login
使用
az login
命令登录到 Azure 帐户。 在 Azure Cloud Shell 中运行时跳过此步骤。如果尚未这样做,请使用
az extension add
此命令安装 Application Insights 扩展:az extension add --name application-insights
使用此 az group create 命令创建在所选区域中命名
AzureFunctionsQuickstart-rg
的资源组:az group create --name "AzureFunctionsQuickstart-rg" --location "<REGION>"
在此示例中,将
<REGION>
替换为支持 Flex 消耗计划的附近区域。 使用 az functionapp list-flexconsumption-locations 命令查看当前支持的区域的列表。使用此 az storage account create 命令在资源组和区域中创建常规用途存储帐户:
az storage account create --name <STORAGE_NAME> --location "<REGION>" --resource-group "AzureFunctionsQuickstart-rg" \ --sku "Standard_LRS" --allow-blob-public-access false --allow-shared-key-access false
在此示例中,请将
<STORAGE_NAME>
替换为适合你且在 Azure 存储中唯一的名称。 名称只能包含 3 到 24 个数字和小写字母字符。Standard_LRS
指定 Functions 支持的常规用途帐户。 只能通过使用已向特定资源授予权限的Microsoft Entra 身份验证标识来访问此新帐户。使用此脚本创建一个用户分配的托管标识,解析
jq
对象返回的JSON属性,并在默认存储帐户中授予Storage Blob Data Owner
权限:output=$(az identity create --name "func-host-storage-user" --resource-group "AzureFunctionsQuickstart-rg" --location <REGION> \ --query "{userId:id, principalId: principalId, clientId: clientId}" -o json) userId=$(echo $output | jq -r '.userId') principalId=$(echo $output | jq -r '.principalId') clientId=$(echo $output | jq -r '.clientId') storageId=$(az storage account show --resource-group "AzureFunctionsQuickstart-rg" --name <STORAGE_NAME> --query 'id' -o tsv) az role assignment create --assignee-object-id $principalId --assignee-principal-type ServicePrincipal \ --role "Storage Blob Data Owner" --scope $storageId
如果本地 Bash shell 中没有该
jq
实用工具,则它在 Azure Cloud Shell 中可用。 在此示例中,将<STORAGE_NAME>
替换为您的默认存储帐户名称,将<REGION>
替换为您的默认区域。az identity create 命令创建一个名为
func-host-storage-user
的标识。 返回的权限principalId
用于使用az role assignment create
命令将权限分配给默认存储帐户中的此新标识。 该az storage account show
命令用于获取存储帐户 ID。使用此 az functionapp create 命令在 Azure 中创建函数应用:
az functionapp create --resource-group "AzureFunctionsQuickstart-rg" --name <APP_NAME> --flexconsumption-location <REGION> \ --runtime dotnet-isolated --runtime-version <LANGUAGE_VERSION> --storage-account <STORAGE_NAME> \ --deployment-storage-auth-type UserAssignedIdentity --deployment-storage-auth-value "func-host-storage-user"
az functionapp create --resource-group "AzureFunctionsQuickstart-rg" --name <APP_NAME> --flexconsumption-location <REGION> \ --runtime java --runtime-version <LANGUAGE_VERSION> --storage-account <STORAGE_NAME> \ --deployment-storage-auth-type UserAssignedIdentity --deployment-storage-auth-value "func-host-storage-user"
az functionapp create --resource-group "AzureFunctionsQuickstart-rg" --name <APP_NAME> --flexconsumption-location <REGION> \ --runtime node --runtime-version <LANGUAGE_VERSION> --storage-account <STORAGE_NAME> \ --deployment-storage-auth-type UserAssignedIdentity --deployment-storage-auth-value "func-host-storage-user"
az functionapp create --resource-group "AzureFunctionsQuickstart-rg" --name <APP_NAME> --flexconsumption-location <REGION> \ --runtime python --runtime-version <LANGUAGE_VERSION> --storage-account <STORAGE_NAME> \ --deployment-storage-auth-type UserAssignedIdentity --deployment-storage-auth-value "func-host-storage-user"
az functionapp create --resource-group "AzureFunctionsQuickstart-rg" --name <APP_NAME> --flexconsumption-location <REGION> \ --runtime python --runtime-version <LANGUAGE_VERSION> --storage-account <STORAGE_NAME> \ --deployment-storage-auth-type UserAssignedIdentity --deployment-storage-auth-value "func-host-storage-user"
在此示例中,将这些占位符替换为相应的值:
-
<APP_NAME>
:适合你的全球唯一名称。<APP_NAME>
也是函数应用的默认 DNS 域。 -
<STORAGE_NAME>
:上一步中使用的帐户的名称。 -
<REGION>
:当前区域。 -
<LANGUAGE_VERSION>
:使用你在本地验证的同一支持的语言堆栈版本。
此命令创建一个函数应用,该应用在 Linux 上的 Flex 消耗计划中指定的语言运行时中运行,根据本教程产生的用量,此操作是免费的。 该命令还会在同一资源组中创建关联的 Azure Application Insights 实例,可用于监视函数应用执行和查看日志。 有关详细信息,请参阅监视 Azure Functions。 该实例在激活之前不会产生费用。
-
使用此脚本将用户分配的托管标识添加到 Application Insights 实例中的 “监视指标发布者 ”角色:
appInsights=$(az monitor app-insights component show --resource-group "AzureFunctionsQuickstart-rg" \ --app <APP_NAME> --query "id" --output tsv) principalId=$(az identity show --name "func-host-storage-user" --resource-group "AzureFunctionsQuickstart-rg" \ --query principalId -o tsv) az role assignment create --role "Monitoring Metrics Publisher" --assignee $principalId --scope $appInsights
在本例中,将
<APP_NAME>
替换为函数应用名称。 az role assignment create 命令将用户添加到该角色。 Application Insights 实例的资源 ID 和用户的主体 ID 分别通过 az monitor app-insights component show 和az identity show
命令获取。
若要使 Functions 主机能够使用共享机密连接到默认存储帐户,必须将连接字符串设置替换为 AzureWebJobsStorage
带前缀 AzureWebJobsStorage__
的多个设置。 这些设置定义了一个复杂的设置,你的应用使用该设置通过用户分配的托管标识连接到存储和 Application Insights。
使用此脚本获取用户分配的托管标识的客户端 ID,并使用它定义与存储和 Application Insights 的托管标识连接:
clientId=$(az identity show --name func-host-storage-user \ --resource-group AzureFunctionsQuickstart-rg --query 'clientId' -o tsv) az functionapp config appsettings set --name <APP_NAME> --resource-group "AzureFunctionsQuickstart-rg" \ --settings AzureWebJobsStorage__accountName=<STORAGE_NAME> \ AzureWebJobsStorage__credential=managedidentity AzureWebJobsStorage__clientId=$clientId \ APPLICATIONINSIGHTS_AUTHENTICATION_STRING="ClientId=$clientId;Authorization=AAD"
在此脚本中,将
<APP_NAME>
和<STORAGE_NAME>
分别替换为您的函数应用和存储帐户的名称。运行 az functionapp config appsettings delete 命令以删除包含共享密钥的现有
AzureWebJobsStorage
连接字符串设置:az functionapp config appsettings delete --name <APP_NAME> --resource-group "AzureFunctionsQuickstart-rg" --setting-names AzureWebJobsStorage
在此示例中,将
<APP_NAME>
替换为函数应用的名称。
此时,Functions 主机能够使用托管标识而不是共享机密安全地连接到存储帐户。 现在可以将项目代码部署到 Azure 资源。
在 Azure 中成功创建函数应用后,便可以使用 func azure functionapp publish 命令部署本地函数项目。
在以下示例中,请将 <APP_NAME>
替换为你的应用的名称。
func azure functionapp publish <APP_NAME>
publish 命令显示类似于以下输出的结果(为简洁起见,示例中的结果已截断):
... Getting site publishing info... Creating archive for current directory... Performing remote build for functions project. ... Deployment successful. Remote build succeeded! Syncing triggers... Functions in msdocs-azurefunctions-qs: HttpExample - [httpTrigger] Invoke url: https://msdocs-azurefunctions-qs.chinacloudsites.cn/api/httpexample
在 Azure 中成功创建函数应用后,必须更新 pom.xml 文件,以便 Maven 可以部署到新应用。 否则,它会在部署期间创建新的 Azure 资源集。
在 Azure Cloud Shell 中,使用
az functionapp show
此命令获取新用户分配的托管标识的部署容器 URL 和 ID:az functionapp show --name <APP_NAME> --resource-group AzureFunctionsQuickstart-rg \ --query "{userAssignedIdentityResourceId: properties.functionAppConfig.deployment.storage.authentication.userAssignedIdentityResourceId, \ containerUrl: properties.functionAppConfig.deployment.storage.value}"
在此示例中,将
<APP_NAME>
替换为函数应用的名称。在项目根目录中,在文本编辑器中打开 pom.xml 文件,找到
properties
元素,并更新这些特定的属性值:属性名称 价值 java.version
使用本地验证的相同 支持的语言堆栈版本 ,例如 17
。azure.functions.maven.plugin.version
1.37.1
azure.functions.java.library.version
3.1.0
functionAppName
Azure 中函数应用的名称。 请找到
configuration
部分中的azure-functions-maven-plugin
,并将其替换为以下 XML 片段:<configuration> <appName>${functionAppName}</appName> <resourceGroup>AzureFunctionsQuickstart-rg</resourceGroup> <pricingTier>Flex Consumption</pricingTier> <region>....</region> <runtime> <os>linux</os> <javaVersion>${java.version}</javaVersion> </runtime> <deploymentStorageAccount>...</deploymentStorageAccount> <deploymentStorageResourceGroup>AzureFunctionsQuickstart-rg</deploymentStorageResourceGroup> <deploymentStorageContainer>...</deploymentStorageContainer> <storageAuthenticationMethod>UserAssignedIdentity</storageAuthenticationMethod> <userAssignedIdentityResourceId>...</userAssignedIdentityResourceId> <appSettings> <property> <name>FUNCTIONS_EXTENSION_VERSION</name> <value>~4</value> </property> </appSettings> </configuration>
在新的
configuration
元素中,将这些省略号 (...
) 值进行以下特定替换:配置 价值 region
现有函数应用的区域代码,例如 chinanorth2
。deploymentStorageAccount
存储帐户的名称。 deploymentStorageContainer
部署共享的名称,该共享位于你获得的 \
值中的containerUrl
之后。userAssignedIdentityResourceId
你获取的托管标识的完全限定的资源 ID。 保存对 pom.xml 文件的更改。
现在可以使用 Maven 将代码项目部署到现有应用。
从命令提示符中,运行此命令:
mvn clean package azure-functions:deploy
部署成功后,使用此
az functionapp function show
URL 获取远程HttpExample
函数终结点的 URL:az functionapp function show --name <APP_NAME> --resource-group "AzureFunctionsQuickstart-rg" \ --function-name HttpExample --query invokeUrlTemplate -o tsv
在此示例中,将
<APP_NAME>
替换为函数应用的名称。复制返回的终结点 URL,接下来将使用该 URL 调用函数终结点。
由于函数使用 HTTP 触发器并且支持 GET 请求,因此可以通过向此函数的 URL 发出 HTTP 请求来调用它。 最简单的方法是在浏览器中执行 GET 请求。
将发布命令输出中显示的完整 调用 URL 复制到浏览器地址栏中。
将复制的 URL 粘贴到浏览器地址栏中。
终结点 URL 应类似于以下示例:
https://contoso-app.chinacloudsites.cn/api/httpexample
导航到此 URL 时,浏览器显示的输出应与在本地运行函数时显示的输出类似。
如果继续执行 下一步 并添加 Azure 存储队列输出绑定,请保留所有现有资源,因为您将基于现有的工作进行构建。
否则,请使用以下命令删除资源组及其包含的所有资源,以免产生额外的费用。
az group delete --name AzureFunctionsQuickstart-rg