Samouczek: tworzenie funkcji w języku Java za pomocą wyzwalacza centrum zdarzeń i powiązania wyjściowego usługi Azure Cosmos DB

W tym samouczku pokazano, jak za pomocą usługi Azure Functions utworzyć funkcję Języka Java, która analizuje ciągły strumień danych temperatury i ciśnienia. Zdarzenia centrum zdarzeń reprezentujące odczyty czujników wyzwalają funkcję. Funkcja przetwarza dane zdarzenia, a następnie dodaje wpisy stanu do wystąpienia usługi Azure Cosmos DB.

W tym samouczku wykonasz następujące elementy:

  • Tworzenie i konfigurowanie zasobów platformy Azure przy użyciu interfejsu wiersza polecenia platformy Azure.
  • Tworzenie i testowanie funkcji języka Java, które współdziałają z tymi zasobami.
  • Wdróż swoje funkcje na platformie Azure i monitoruj je przy użyciu Szczegółowe informacje aplikacji.

Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto platformy Azure.

Wymagania wstępne

Aby ukończyć ten samouczek, musisz mieć zainstalowane następujące elementy:

Ważne

Aby JAVA_HOME ukończyć ten samouczek, należy ustawić zmienną środowiskową na lokalizację instalacji zestawu JDK.

Jeśli wolisz bezpośrednio używać kodu na potrzeby tego samouczka, zobacz przykładowe repozytorium java-functions-eventhub-cosmosdb .

Tworzenie zasobów platformy Azure

W tym samouczku potrzebne są następujące zasoby:

  • Grupa zasobów zawierająca inne zasoby
  • Przestrzeń nazw usługi Event Hubs, centrum zdarzeń i reguła autoryzacji
  • Konto, baza danych i kolekcja usługi Azure Cosmos DB
  • Aplikacja funkcji i konto magazynu do hostowania

W poniższych sekcjach pokazano, jak utworzyć te zasoby przy użyciu interfejsu wiersza polecenia platformy Azure.

Ustawianie zmiennych środowiskowych

Następnie utwórz zmienne środowiskowe dla nazw i lokalizacji zasobów, które utworzysz. Użyj następujących poleceń, zastępując <value> symbole zastępcze wybranymi wartościami. Wartości powinny być zgodne z regułami i ograniczeniami nazewnictwa dla zasobów platformy Azure. W przypadku zmiennej LOCATION użyj jednej z wartości wygenerowanych przez az functionapp list-consumption-locations polecenie .

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>

W pozostałej części tego samouczka są używane te zmienne. Należy pamiętać, że te zmienne są utrwalane tylko przez czas trwania bieżącej sesji interfejsu wiersza polecenia platformy Azure lub usługi Cloud Shell. Te polecenia należy uruchomić ponownie, jeśli używasz innego lokalnego okna terminalu lub limitu czasu sesji usługi Cloud Shell.

Tworzenie grupy zasobów

Platforma Azure używa grup zasobów do zbierania wszystkich powiązanych zasobów na twoim koncie. W ten sposób można je wyświetlać jako jednostkę i usuwać za pomocą jednego polecenia po zakończeniu pracy z nimi.

Użyj następującego polecenia, aby utworzyć grupę zasobów:

az group create \
    --name $RESOURCE_GROUP \
    --location $LOCATION

Tworzenie centrum zdarzeń

Następnie utwórz przestrzeń nazw usługi Azure Event Hubs, centrum zdarzeń i regułę autoryzacji przy użyciu następujących poleceń:

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 \
    --message-retention 1
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

Przestrzeń nazw usługi Event Hubs zawiera rzeczywiste centrum zdarzeń i regułę autoryzacji. Reguła autoryzacji umożliwia funkcjom wysyłanie komunikatów do centrum i nasłuchiwanie odpowiednich zdarzeń. Jedna funkcja wysyła komunikaty reprezentujące dane telemetryczne. Inna funkcja nasłuchuje zdarzeń, analizuje dane zdarzeń i przechowuje wyniki w usłudze Azure Cosmos DB.

Tworzenie usługi Azure Cosmos DB

Następnie utwórz konto, bazę danych i kolekcję usługi Azure Cosmos DB przy użyciu następujących poleceń:

az cosmosdb create \
    --resource-group $RESOURCE_GROUP \
    --name $COSMOS_DB_ACCOUNT
az cosmosdb sql database create \
    --resource-group $RESOURCE_GROUP \
    --account-name $COSMOS_DB_ACCOUNT \
    --name TelemetryDb
az cosmosdb sql container create \
    --resource-group $RESOURCE_GROUP \
    --account-name $COSMOS_DB_ACCOUNT \
    --database-name TelemetryDb \
    --name TelemetryInfo \
    --partition-key-path '/temperatureStatus'

Wartość partition-key-path dzieli dane na partycje na temperatureStatus podstawie wartości każdego elementu. Klucz partycji umożliwia usłudze Azure Cosmos DB zwiększenie wydajności przez podzielenie danych na odrębne podzestawy, do których może uzyskiwać dostęp niezależnie.

Tworzenie konta magazynu i aplikacji funkcji

Następnie utwórz konto usługi Azure Storage, które jest wymagane przez usługę Azure Functions, a następnie utwórz aplikację funkcji. Użyj następujących poleceń:

az storage account create \
    --resource-group $RESOURCE_GROUP \
    --name $STORAGE_ACCOUNT \
    --sku Standard_LRS
az functionapp create \
    --resource-group $RESOURCE_GROUP \
    --name $FUNCTION_APP \
    --storage-account $STORAGE_ACCOUNT \
    --consumption-plan-location $LOCATION \
    --runtime java \
    --functions-version 3

Gdy az functionapp create polecenie tworzy aplikację funkcji, tworzy również zasób aplikacji Szczegółowe informacje o tej samej nazwie. Aplikacja funkcji jest automatycznie konfigurowana przy użyciu ustawienia o nazwie APPINSIGHTS_INSTRUMENTATIONKEY , które łączy ją z aplikacją Szczegółowe informacje. Dane telemetryczne aplikacji można wyświetlić po wdrożeniu funkcji na platformie Azure zgodnie z opisem w dalszej części tego samouczka.

Konfigurowanie aplikacji funkcji

Aby aplikacja funkcji działała prawidłowo, będzie musiała uzyskać dostęp do innych zasobów. W poniższych sekcjach pokazano, jak skonfigurować aplikację funkcji, aby mogła działać na komputerze lokalnym.

Pobieranie parametry połączenia zasobów

Użyj następujących poleceń, aby pobrać magazyn, centrum zdarzeń i usługę Azure Cosmos DB parametry połączenia i zapisać je w zmiennych środowiskowych:

AZURE_WEB_JOBS_STORAGE=$( \
    az storage account show-connection-string \
        --name $STORAGE_ACCOUNT \
        --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
COSMOS_DB_CONNECTION_STRING=$( \
    az cosmosdb keys list \
        --resource-group $RESOURCE_GROUP \
        --name $COSMOS_DB_ACCOUNT \
        --type connection-strings \
        --query 'connectionStrings[0].connectionString' \
        --output tsv)
echo $COSMOS_DB_CONNECTION_STRING

Te zmienne są ustawiane na wartości pobierane z poleceń interfejsu wiersza polecenia platformy Azure. Każde polecenie używa zapytania JMESPath do wyodrębnienia parametry połączenia z zwróconego ładunku JSON. Wyświetlane są również parametry połączenia, echo dzięki czemu można potwierdzić, że zostały one pomyślnie pobrane.

Aktualizowanie ustawień aplikacji funkcji

Następnie użyj następującego polecenia, aby przenieść wartości parametry połączenia do ustawień aplikacji na koncie usługi Azure Functions:

az functionapp config appsettings set \
    --resource-group $RESOURCE_GROUP \
    --name $FUNCTION_APP \
    --settings \
        AzureWebJobsStorage=$AZURE_WEB_JOBS_STORAGE \
        EventHubConnectionString=$EVENT_HUB_CONNECTION_STRING \
        CosmosDBConnectionSetting=$COSMOS_DB_CONNECTION_STRING

Zasoby platformy Azure zostały utworzone i skonfigurowane do prawidłowej współpracy.

Tworzenie i testowanie funkcji

Następnie utworzysz projekt na komputerze lokalnym, dodasz kod Java i przetestujesz go. Użyjesz poleceń, które współpracują z wtyczką usługi Azure Functions dla narzędzia Maven i narzędzi Azure Functions Core Tools. Funkcje będą uruchamiane lokalnie, ale będą korzystać z utworzonych zasobów w chmurze. Po korzystaniu z funkcji działających lokalnie możesz użyć narzędzia Maven, aby wdrożyć je w chmurze i obserwować gromadzenie danych i analiz.

Jeśli użyto usługi Cloud Shell do utworzenia zasobów, nie będzie można nawiązać połączenia z platformą Azure lokalnie. W takim przypadku użyj az login polecenia , aby uruchomić proces logowania opartego na przeglądarce. W razie potrzeby ustaw domyślną subskrypcję, az account set --subscription a następnie identyfikator subskrypcji. Na koniec uruchom następujące polecenia, aby ponownie utworzyć zmienne środowiskowe na komputerze lokalnym. <value> Zastąp symbole zastępcze tymi samymi wartościami, które były wcześniej używane.

RESOURCE_GROUP=<value>
FUNCTION_APP=<value>

Tworzenie projektu funkcji lokalnych

Użyj następującego polecenia narzędzia Maven, aby utworzyć projekt funkcji i dodać wymagane zależności.

mvn archetype:generate --batch-mode \
    -DarchetypeGroupId=com.microsoft.azure \
    -DarchetypeArtifactId=azure-functions-archetype \
    -DappName=$FUNCTION_APP \
    -DresourceGroup=$RESOURCE_GROUP \
    -DappRegion=$LOCATION \
    -DgroupId=com.example \
    -DartifactId=telemetry-functions

To polecenie generuje kilka plików wewnątrz telemetry-functions folderu:

  • pom.xml Plik do użycia z narzędziem Maven
  • local.settings.json Plik do przechowywania ustawień aplikacji na potrzeby testowania lokalnego
  • host.json Plik, który umożliwia pakiet rozszerzeń usługi Azure Functions wymagany dla powiązania wyjściowego usługi Azure Cosmos DB w funkcji analizy danych
  • Function.java Plik zawierający domyślną implementację funkcji
  • Kilka plików testowych, których ten samouczek nie wymaga

Aby uniknąć błędów kompilacji, należy usunąć pliki testowe. Uruchom następujące polecenia, aby przejść do nowego folderu projektu i usunąć folder testowy:

cd telemetry-functions
rm -r src/test

Pobieranie ustawień aplikacji funkcji do użytku lokalnego

W przypadku testowania lokalnego projekt funkcji będzie potrzebować parametry połączenia dodanych do aplikacji funkcji na platformie Azure wcześniej w tym samouczku. Użyj następującego polecenia Azure Functions Core Tools, które pobiera wszystkie ustawienia aplikacji funkcji przechowywane w chmurze i dodaje je do pliku local.settings.json :

func azure functionapp fetch-app-settings $FUNCTION_APP

Dodawanie kodu Java

Następnie otwórz Function.java plik i zastąp zawartość następującym kodem.

package com.example;

import com.example.TelemetryItem.status;
import com.microsoft.azure.functions.annotation.Cardinality;
import com.microsoft.azure.functions.annotation.CosmosDBOutput;
import com.microsoft.azure.functions.annotation.EventHubOutput;
import com.microsoft.azure.functions.annotation.EventHubTrigger;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.TimerTrigger;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.OutputBinding;

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);
    }

    @FunctionName("processSensorData")
    public void processSensorData(
        @EventHubTrigger(
            name = "msg",
            eventHubName = "", // blank because the value is included in the connection string
            cardinality = Cardinality.ONE,
            connection = "EventHubConnectionString")
            TelemetryItem item,
        @CosmosDBOutput(
            name = "databaseOutput",
            databaseName = "TelemetryDb",
            containerName = "TelemetryInfo",
            connection = "CosmosDBConnectionSetting")
            OutputBinding<TelemetryItem> document,
        final ExecutionContext context) {

        context.getLogger().info("Event hub message received: " + item.toString());

        if (item.getPressure() > 30) {
            item.setNormalPressure(false);
        } else {
            item.setNormalPressure(true);
        }

        if (item.getTemperature() < 40) {
            item.setTemperatureStatus(status.COOL);
        } else if (item.getTemperature() > 90) {
            item.setTemperatureStatus(status.HOT);
        } else {
            item.setTemperatureStatus(status.WARM);
        }

        document.setValue(item);
    }
}

Jak widać, ten plik zawiera dwie funkcje i generateSensorDataprocessSensorData. Funkcja generateSensorData symuluje czujnik, który wysyła odczyty temperatury i ciśnienia do centrum zdarzeń. Wyzwalacz czasomierza uruchamia funkcję co 10 sekund, a powiązanie wyjściowe centrum zdarzeń wysyła wartość zwracaną do centrum zdarzeń.

Gdy centrum zdarzeń odbiera komunikat, generuje zdarzenie. Funkcja processSensorData jest uruchamiana po odebraniu zdarzenia. Następnie przetwarza dane zdarzenia i używa powiązania wyjściowego usługi Azure Cosmos DB do wysyłania wyników do usługi Azure Cosmos DB.

Dane używane przez te funkcje są przechowywane przy użyciu klasy o nazwie TelemetryItem, którą należy zaimplementować. Utwórz nowy plik o nazwie TelemetryItem.java w tej samej lokalizacji co Function.java i dodaj następujący kod:

package com.example;

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;
    }
}

Uruchamianie polecenia w środowisku lokalnym

Teraz możesz kompilować i uruchamiać funkcje lokalnie i wyświetlać dane w usłudze Azure Cosmos DB.

Użyj następujących poleceń narzędzia Maven, aby skompilować i uruchomić funkcje:

mvn clean package
mvn azure-functions:run

Po wykonaniu niektórych komunikatów kompilacji i uruchamiania zobaczysz dane wyjściowe podobne do następujących przykładów po każdym uruchomieniu funkcji:

[10/22/19 4:01:30 AM] Executing 'Functions.generateSensorData' (Reason='Timer fired at 2019-10-21T21:01:30.0016769-07:00', Id=c1927c7f-4f70-4a78-83eb-bc077d838410)
[10/22/19 4:01:30 AM] Java Timer trigger function executed at: 2019-10-21T21:01:30.015
[10/22/19 4:01:30 AM] Function "generateSensorData" (Id: c1927c7f-4f70-4a78-83eb-bc077d838410) invoked by Java Worker
[10/22/19 4:01:30 AM] Executed 'Functions.generateSensorData' (Succeeded, Id=c1927c7f-4f70-4a78-83eb-bc077d838410)
[10/22/19 4:01:30 AM] Executing 'Functions.processSensorData' (Reason='', Id=f4c3b4d7-9576-45d0-9c6e-85646bb52122)
[10/22/19 4:01:30 AM] Event hub message received: TelemetryItem={id=null,temperature=32.728691307527015,pressure=10.122563042388165}
[10/22/19 4:01:30 AM] Function "processSensorData" (Id: f4c3b4d7-9576-45d0-9c6e-85646bb52122) invoked by Java Worker
[10/22/19 4:01:38 AM] Executed 'Functions.processSensorData' (Succeeded, Id=1cf0382b-0c98-4cc8-9240-ee2a2f71800d)

Następnie możesz przejść do witryny Azure Portal i przejść do konta usługi Azure Cosmos DB. Wybierz pozycję Eksplorator danych, rozwiń pozycję TelemetryInfo, a następnie wybierz pozycję Elementy , aby wyświetlić dane po ich nadejściu.

Azure Cosmos DB Data Explorer

Wdrażanie na platformie Azure i wyświetlanie danych telemetrycznych aplikacji

Na koniec możesz wdrożyć aplikację na platformie Azure i sprawdzić, czy nadal działa tak samo jak lokalnie.

Wdróż projekt na platformie Azure przy użyciu następującego polecenia:

mvn azure-functions:deploy

Funkcje są teraz uruchamiane na platformie Azure i nadal gromadzić dane w usłudze Azure Cosmos DB. Wdrożoną aplikację funkcji można wyświetlić w witrynie Azure Portal i wyświetlić dane telemetryczne aplikacji za pomocą połączonego zasobu aplikacji Szczegółowe informacje, jak pokazano na poniższych zrzutach ekranu:

Transmisja strumieniowa metryk na żywo:

Application Insights Live Metrics Stream

Wydajność:

Application Insights Performance blade

Czyszczenie zasobów

Po zakończeniu pracy z zasobami platformy Azure, które zostały utworzone w tym samouczku, można je usunąć za pomocą następującego polecenia:

az group delete --name $RESOURCE_GROUP

Następne kroki

W tym samouczku przedstawiono sposób tworzenia funkcji platformy Azure obsługującej zdarzenia centrum zdarzeń i aktualizacji wystąpienia usługi Azure Cosmos DB. Aby uzyskać więcej informacji, zobacz Przewodnik dla deweloperów języka Java usługi Azure Functions. Aby uzyskać informacje na temat użytych adnotacji, zobacz dokumentację com.microsoft.azure.functions.annotation .

W tym samouczku użyto zmiennych środowiskowych i ustawień aplikacji do przechowywania wpisów tajnych, takich jak parametry połączenia. Aby uzyskać informacje na temat przechowywania tych wpisów tajnych w usłudze Azure Key Vault, zobacz Use Key Vault references for App Service and Azure Functions (Używanie odwołań usługi Key Vault dla usług App Service i Azure Functions).

Następnie dowiesz się, jak używać ciągłej integracji/ciągłego wdrażania usługi Azure Pipelines do automatycznego wdrażania:

Kompilowanie i wdrażanie języka Java w Azure Functions