تمرين - إنشاء وظيفة Azure لمحاكاة البيانات عن بعد

مكتمل

على سبيل المثال، نستخدم مصادر الأحداث. دعونا ننشئ وظيفة تحاكي قياس البيانات عن بعد ونرسلها إلى مركز الحدث. في وقت لاحق، يمكن لوظيفة أخرى الاستماع إلى هذا الحدث ومعالجته وتخزينه في قاعدة بيانات تم إنشاؤها باستخدام Azure Cosmos DB.

Visualization of event sourcing for buying coffee at a coffee shop.

إعداد البيئة الخاصة بك

دعونا نعرّف بعض متغيرات البيئة للحفاظ على الأوامر التالية قصيرة ومفهومة قدر الإمكان. عرّف <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.

عندما يقوم الأمر 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 Function الخاص بك، قم بتشغيل الأمر التالي في المحطة الطرفية الخاصة بك:

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:

  • ملف إنشاء pom.xml مع تبعيات Azure المعرفة مسبقًا.
  • ملف local.settings.json الذي يحفظ إعدادات التطبيق للنشر المحلي والاختبار اليدوي.
  • ملف host.json الذي يمكّن Azure Functions Extension Bundle.
  • ملف Function.java الذي يتضمن وظيفة مشغل HTTP الافتراضية.
  • بعض ملفات الاختبار التي لا تستخدمها وحدة التعلم هذه.

لا نلمس ملفات الاختبار في وحدة 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، والتي تحتاج إلى تنفيذها. أنشئ ملفًا جديدًا يسمى TelemetryItem.java في نفس الموقع كـ Function.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 محليًا، تكون قد تدفقت مسبقًا في جميع أنحاء العالم! كما يمكنك مراجعتها في بوابة 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

قم بتشغيل النشر على Azure بتشغيل الأمر mvn azure-functions:deploy والمتابعة.

mvn azure-functions:deploy