练习 - 构建 Azure 函数以模拟遥测数据
在我们的示例中,我们使用事件溯源。 让我们构建一个函数,该函数将模拟遥测数据并将其发送到事件中心。 稍后,另一个函数可以侦听此事件,对其进行处理,然后将其存储到使用 Azure Cosmos DB 创建的数据库中。
准备环境
让我们定义一些环境变量,使下面的所有命令尽可能简短易懂。 定义 <value>
占位符,然后在终端或命令行工具中粘贴并运行以下命令:
RESOURCE_GROUP=<value>
EVENT_HUB_NAMESPACE=<value>
EVENT_HUB_NAME=<value>
EVENT_HUB_AUTHORIZATION_RULE=<value>
COSMOS_DB_ACCOUNT=<value>
STORAGE_ACCOUNT=<value>
FUNCTION_APP=<value>
LOCATION=<value>
注意
若要设置 LOCATION 变量,可以查看 az functionapp list-consumption-locations
命令并取最接近的值。
创建所需的组件
在 Azure 上预配资源需要一些时间。 让我们尽早开始创建组件,以避免在以后长时间等待。
创建资源组
最好将训练、概念证明或原型的所有资源绑定到一个资源组中。 这样,你就可以用一个命令方便地清理所有使用过的服务。 若要在指定位置创建资源组,请在终端中运行以下命令:
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION
创建和配置事件中心
对于事件中心,需要指定其应侦听的命名空间。 此外,你需要将授权规则配置为 Listen
和 Send
。
az eventhubs namespace create \
--resource-group $RESOURCE_GROUP \
--name $EVENT_HUB_NAMESPACE
az eventhubs eventhub create \
--resource-group $RESOURCE_GROUP \
--name $EVENT_HUB_NAME \
--namespace-name $EVENT_HUB_NAMESPACE \
az eventhubs eventhub authorization-rule create \
--resource-group $RESOURCE_GROUP \
--name $EVENT_HUB_AUTHORIZATION_RULE \
--eventhub-name $EVENT_HUB_NAME \
--namespace-name $EVENT_HUB_NAMESPACE \
--rights Listen Send
构建、配置和部署 Azure 函数
为使此示例尽可能真实,请创建一个 Azure 函数并模拟遥测数据。 你也可以将 IoT 设备绑定到 Azure 函数,这样就可以获得真实的数据。 由于此函数是生成事件的函数,因此让我们添加一个 p 或 -p 标志。
az storage account create \
--resource-group $RESOURCE_GROUP \
--name $STORAGE_ACCOUNT"p" \
--sku Standard_LRS
az functionapp create \
--resource-group $RESOURCE_GROUP \
--name $FUNCTION_APP"-p"\
--storage-account $STORAGE_ACCOUNT"p" \
--consumption-plan-location $LOCATION \
--runtime java \
--functions-version 4
注意
请使用 functions-version 4,因为 2 和 3 已于 2022 年 12 月停用。
当 az functionapp create
命令创建函数应用程序时,它还会创建一个具有相同名称的 Application Insights 资源。 我们稍后将使用该资源进行监视。
若要检索存储帐户和事件中心的连接字符串,请使用以下命令将其保存在环境变量中,然后使用 echo
命令显示它们。
AZURE_WEB_JOBS_STORAGE=$( \
az storage account show-connection-string \
--resource-group $RESOURCE_GROUP \
--name $STORAGE_ACCOUNT"p" \
--query connectionString \
--output tsv)
echo $AZURE_WEB_JOBS_STORAGE
EVENT_HUB_CONNECTION_STRING=$( \
az eventhubs eventhub authorization-rule keys list \
--resource-group $RESOURCE_GROUP \
--name $EVENT_HUB_AUTHORIZATION_RULE \
--eventhub-name $EVENT_HUB_NAME \
--namespace-name $EVENT_HUB_NAMESPACE \
--query primaryConnectionString \
--output tsv)
echo $EVENT_HUB_CONNECTION_STRING
若要将这些连接字符串存储在 Azure 函数帐户的应用程序设置中,请在终端运行以下命令:
az functionapp config appsettings set \
--resource-group $RESOURCE_GROUP \
--name $FUNCTION_APP"-p" \
--settings \
AzureWebJobsStorage=$AZURE_WEB_JOBS_STORAGE \
EventHubConnectionString=$EVENT_HUB_CONNECTION_STRING
现在,你的 Azure 资源事件中心和 Azure 函数已创建并配置为一起有序工作。
接下来,利用 Maven 创建一个本地函数项目。
mvn archetype:generate --batch-mode \
-DarchetypeGroupId=com.microsoft.azure \
-DarchetypeArtifactId=azure-functions-archetype \
-DappName=$FUNCTION_APP"-p" \
-DresourceGroup=$RESOURCE_GROUP \
-DappRegion=$LOCATION \
-DappServicePlanName=$LOCATION"plan" \
-DgroupId=com.learn \
-DartifactId=telemetry-functions-producer
此命令在 telemetry-functions-producer
文件夹内生成多个文件:
- 具有预定义 Azure 依赖项的
pom.xml
生成文件。 - 用于保存本地部署和手动测试的应用程序设置的
local.settings.json
文件。 - 支持 Azure Functions 扩展捆绑包的
host.json
文件。 - 包含默认 HTTP 触发器函数的
Function.java
文件。 - 此 Learn 模块不使用的一些测试文件。
我们不会用到此学习模块中的测试文件,因此可随意将其删除。
cd telemetry-functions-producer
rm -r src/test
对于本地执行,需检索应用程序设置并将其存储在 local.settings.json
文件中。 可以通过运行 fetch-app-settings
命令自动执行此操作。
func azure functionapp fetch-app-settings $FUNCTION_APP"-p"
接下来,打开 Function.java
文件并将其中的内容替换为以下代码:
package com.learn;
import com.microsoft.azure.functions.annotation.EventHubOutput;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.TimerTrigger;
import com.microsoft.azure.functions.ExecutionContext;
public class Function {
@FunctionName("generateSensorData")
@EventHubOutput(
name = "event",
eventHubName = "", // blank because the value is included in the connection string
connection = "EventHubConnectionString")
public TelemetryItem generateSensorData(
@TimerTrigger(
name = "timerInfo",
schedule = "*/10 * * * * *") // every 10 seconds
String timerInfo,
final ExecutionContext context) {
context.getLogger().info("Java Timer trigger function executed at: " + java.time.LocalDateTime.now());
double temperature = Math.random() * 100;
double pressure = Math.random() * 50;
return new TelemetryItem(temperature, pressure);
}
}
generateSensorData
函数模拟向事件中心发送温度和压力读数的传感器。 计时器触发器每 10 秒运行一次该函数,事件中心输出绑定将返回值发送到事件中心。
当事件中心收到消息时,它会生成一个事件。
此函数使用的数据是使用名为 TelemetryItem 的类存储的,你需要实现此类。 在与 Function.java 相同的位置创建名为 TelemetryItem.java 的新文件,并添加以下代码:
package com.learn;
public class TelemetryItem {
private String id;
private double temperature;
private double pressure;
private boolean isNormalPressure;
private status temperatureStatus;
static enum status {
COOL,
WARM,
HOT
}
public TelemetryItem(double temperature, double pressure) {
this.temperature = temperature;
this.pressure = pressure;
}
public String getId() {
return id;
}
public double getTemperature() {
return temperature;
}
public double getPressure() {
return pressure;
}
@Override
public String toString() {
return "TelemetryItem={id=" + id + ",temperature="
+ temperature + ",pressure=" + pressure + "}";
}
public boolean isNormalPressure() {
return isNormalPressure;
}
public void setNormalPressure(boolean isNormal) {
this.isNormalPressure = isNormal;
}
public status getTemperatureStatus() {
return temperatureStatus;
}
public void setTemperatureStatus(status temperatureStatus) {
this.temperatureStatus = temperatureStatus;
}
}
在本地运行
在本地运行 Azure Functions 时,它们已传输到世界各地! 此外,还可以在 Azure 门户中查看它们。
mvn clean package
mvn azure-functions:run
在某些生成和启动消息后,每次运行函数时,将看到类似于以下示例的输出:
[2021-01-19T16:25:40.005Z] Executing 'Functions.generateSensorData' (Reason='Timer fired at 2021-01-19T17:25:40.0044630+01:00', Id=fcf567a3-03ec-4159-9714-aa4449861b30)
[2021-01-19T16:25:40.011Z] Java Timer trigger function executed at: 2021-01-19T17:25:40.009405
[2021-01-19T16:25:40.013Z] Function "generateSensorData" (Id: fcf567a3-03ec-4159-9714-aa4449861b30) invoked by Java Worker
[2021-01-19T16:25:40.048Z] Executed 'Functions.generateSensorData' (Succeeded, Id=fcf567a3-03ec-4159-9714-aa4449861b30, Duration=43ms)
注意
在 Azure 云中部署和运行函数之前,可以通过本地计算机将事件发送到世界各地! 这对于开发、调试和本地测试非常有用。
部署到 Azure
请运行 mvn azure-functions:deploy
命令,在 Azure 上触发部署,然后继续。
mvn azure-functions:deploy