Azure Functions Příručka pro vývojáře v Javě

Tato příručka obsahuje podrobné informace, které vám pomůžou úspěšně vyvíjet Azure Functions pomocí Javy.

Pokud s Azure Functions jako vývojář v Javě teprve začínáte, zvažte první přečtení některého z následujících článků:

Začínáme Koncepty Scénáře a ukázky

Základy funkcí v Javě

Funkce Java je metoda, která je public zdobená poznámkou @FunctionName. Tato metoda definuje položku pro funkci Jazyka Java a musí být v konkrétním balíčku jedinečná. Balíček může mít více tříd s několika veřejnými metodami anotovanými @FunctionNamepomocí . Do aplikace funkcí v Azure se nasadí jeden balíček. Aplikace funkcí v Azure poskytuje kontext nasazení, spouštění a správy pro jednotlivé funkce Javy.

Programovací model

Koncepty triggerů a vazeb jsou pro Azure Functions zásadní. Triggery spustí provádění kódu. Vazby umožňují předávat a vracet data z funkce, aniž byste museli psát vlastní kód pro přístup k datům.

Vytváření funkcí v Javě

Pro usnadnění vytváření funkcí Jazyka Java existují nástroje a archetypy založené na Mavenu, které používají předdefinované šablony Java, které vám pomůžou vytvářet projekty s konkrétním triggerem funkce.

Nástroje založené na Mavenu

Následující vývojářská prostředí mají Azure Functions nástroje, které umožňují vytvářet projekty funkcí Java:

Tyto články ukazují, jak vytvořit první funkce pomocí integrovaného vývojového prostředí (IDE) podle vašeho výběru.

Generování uživatelského rozhraní projektu

Pokud dáváte přednost vývoji z příkazového řádku z terminálu, nejjednodušší způsob, jak vygenerovat projekty funkcí založené na jazyce Java, je použít Apache Maven archetypy. Archetyp Java Maven pro Azure Functions je publikovaný pod následující groupId:artifactId: com.microsoft.azure:azure-functions-archetype.

Následující příkaz vygeneruje nový projekt funkcí Javy pomocí tohoto archetypu:

mvn archetype:generate \
    -DarchetypeGroupId=com.microsoft.azure \
    -DarchetypeArtifactId=azure-functions-archetype

Pokud chcete začít používat tento archetyp, projděte si rychlý start pro Javu.

Struktura složek

Tady je struktura složek projektu Azure Functions Javě:

FunctionsProject
 | - src
 | | - main
 | | | - java
 | | | | - FunctionApp
 | | | | | - MyFirstFunction.java
 | | | | | - MySecondFunction.java
 | - target
 | | - azure-functions
 | | | - FunctionApp
 | | | | - FunctionApp.jar
 | | | | - host.json
 | | | | - MyFirstFunction
 | | | | | - function.json
 | | | | - MySecondFunction
 | | | | | - function.json
 | | | | - bin
 | | | | - lib
 | - pom.xml

Ke konfiguraci aplikace funkcí můžete použít sdílený soubor host.json . Každá funkce má vlastní soubor kódu (.java) a konfigurační soubor vazby (function.json).

Do projektu můžete vložit více než jednu funkci. Vyhněte se vkládání funkcí do samostatných souborů JAR. Hodnota FunctionApp v cílovém adresáři je to, co se nasadí do vaší aplikace funkcí v Azure.

Triggery a poznámky

Funkce jsou vyvolány triggerem, jako je požadavek HTTP, časovač nebo aktualizace dat. Vaše funkce musí zpracovat aktivační událost a všechny další vstupy, aby se vytvořil jeden nebo více výstupů.

Pomocí poznámek v Javě, které jsou součástí balíčku com.microsoft.azure.functions.annotation.*, svážete vstupy a výstupy s vašimi metodami. Další informace najdete v referenční dokumentaci k Javě.

Důležité

V souboru local.settings.json musíte nakonfigurovat účet služby Azure Storage tak, aby se triggery Azure Blob Storage, Azure Queue Storage nebo Azure Table Storage spouštěly místně.

Příklad:

public class Function {
    public String echo(@HttpTrigger(name = "req", 
      methods = {HttpMethod.POST},  authLevel = AuthorizationLevel.ANONYMOUS) 
        String req, ExecutionContext context) {
        return String.format(req);
    }
}

Tady je vygenerovaný odpovídající function.json modul plug-in azure-functions-maven:

{
  "scriptFile": "azure-functions-example.jar",
  "entryPoint": "com.example.Function.echo",
  "bindings": [
    {
      "type": "httpTrigger",
      "name": "req",
      "direction": "in",
      "authLevel": "anonymous",
      "methods": [ "GET","POST" ]
    },
    {
      "type": "http",
      "name": "$return",
      "direction": "out"
    }
  ]
}

Verze Javy

Verze Javy, ve které vaše aplikace běží v Azure, je uvedená v souboru pom.xml. Archetyp Maven v současné době generuje pom.xml pro Javu 8, který můžete před publikováním změnit. Verze Javy v pom.xml by se měla shodovat s verzí, na které jste aplikaci místně vyvinuli a otestovali.

Podporované verze

Následující tabulka uvádí aktuálně podporované verze Javy pro každou hlavní verzi modulu runtime functions podle operačního systému:

Verze služby Functions Verze Java (Windows) Verze Java (Linux)
4.x 17
11
8
17
11
8
3.x 11
8
11
8
2.x 8 Není k dispozici

Pokud pro své nasazení nezadáte verzi Javy, archetyp Maven se během nasazování do Azure jako výchozí nastaví na Java 8.

Určení verze nasazení

Verzi Javy, na kterou cílí archetyp Maven, můžete řídit pomocí parametru -DjavaVersion . Hodnota tohoto parametru může být nebo 811.

Archetyp Maven vygeneruje pom.xml, který cílí na zadanou verzi Javy. Následující prvky v pom.xml označují verzi Javy, která se má použít:

Prvek Hodnota Java 8 Hodnota Java 11 Hodnota Java 17 Description
Java.version 1.8 11 17 Verze Javy používaná modulem maven-compiler-plugin.
JavaVersion 8 11 17 Verze Javy hostovaná aplikací funkcí v Azure.

Následující příklady ukazují nastavení pro Javu 8 v příslušných částech souboru pom.xml:

Java.version

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    <azure.functions.maven.plugin.version>1.6.0</azure.functions.maven.plugin.version>
    <azure.functions.java.library.version>1.3.1</azure.functions.java.library.version>
    <functionAppName>fabrikam-functions-20200718015742191</functionAppName>
    <stagingDirectory>${project.build.directory}/azure-functions/${functionAppName}</stagingDirectory>
</properties>

JavaVersion

<runtime>
    <!-- runtime os, could be windows, linux or docker-->
    <os>windows</os>
    <javaVersion>8</javaVersion>
    <!-- for docker function, please set the following parameters -->
    <!-- <image>[hub-user/]repo-name[:tag]</image> -->
    <!-- <serverId></serverId> -->
    <!-- <registryUrl></registryUrl>  -->
</runtime>

Důležité

Musíte mít JAVA_HOME proměnnou prostředí správně nastavenou na adresář sady JDK, který se používá při kompilaci kódu pomocí Mavenu. Ujistěte se, že je verze sady JDK alespoň stejně vysoká jako nastavení Java.version .

Určení operačního systému nasazení

Maven také umožňuje určit operační systém, na kterém vaše aplikace funkcí běží v Azure. Pomocí elementu os zvolte operační systém.

Prvek Windows Linux Docker
os windows linux docker

Následující příklad ukazuje nastavení operačního systému v runtime části souboru pom.xml:

<runtime>
    <!-- runtime os, could be windows, linux or docker-->
    <os>windows</os>
    <javaVersion>8</javaVersion>
    <!-- for docker function, please set the following parameters -->
    <!-- <image>[hub-user/]repo-name[:tag]</image> -->
    <!-- <serverId></serverId> -->
    <!-- <registryUrl></registryUrl>  -->
</runtime>

Dostupnost a podpora modulu runtime JDK

Buildy OpenJDK od Microsoftu a Adoptium se poskytují a podporují ve Functions pro Javu 8 (Adoptium), 11 (MSFT) a 17 (MSFT). Tyto binární soubory jsou poskytovány jako beznákladová distribuce sady OpenJDK pro Azure pro více platforem připravená pro produkční prostředí. Obsahuje všechny komponenty pro vytváření a spouštění aplikací Java SE.

Pro účely místního vývoje nebo testování si můžete zdarma stáhnout binární soubory OpenJDK nebo Adoptium Temurin od Microsoftu. podpora Azure pro problémy se sadami JDK a aplikacemi funkcí je k dispozici s kvalifikovaným plánem podpory.

Pokud chcete v aplikaci funkcí dál používat binární soubory Zulu pro Azure, nakonfigurujte aplikaci odpovídajícím způsobem. Pro svůj web můžete dál používat binární soubory Azul. Všechny opravy zabezpečení nebo vylepšení jsou však k dispozici pouze v nových verzích sady OpenJDK. Z tohoto důvodu byste nakonec měli tuto konfiguraci odebrat, aby vaše aplikace používaly nejnovější dostupnou verzi Javy.

Přizpůsobení prostředí JVM

Funkce umožňují přizpůsobit prostředí Java Virtual Machine (JVM) používané ke spouštění funkcí Javy. Ve výchozím nastavení se používají následující možnosti prostředí JVM :

  • -XX:+TieredCompilation
  • -XX:TieredStopAtLevel=1
  • -noverify
  • -Djava.net.preferIPv4Stack=true
  • -jar

V závislosti na typu plánu můžete prostředí JVM zadat další argumenty pomocí jednoho z následujících nastavení aplikace:

Typ plánu Název nastavení Komentář
Plán Consumption languageWorkers__java__arguments Toto nastavení prodlužuje dobu studeného spuštění funkcí Javy spuštěných v plánu Consumption.
Plán Premium
Plán Dedicated
JAVA_OPTS

V následujících částech se dozvíte, jak tato nastavení přidat. Další informace o práci s nastavením aplikace najdete v části Práce s nastavením aplikace .

portál Azure

V Azure Portal pomocí karty Nastavení aplikace přidejte nastavení nebo languageWorkers__java__argumentsJAVA_OPTS .

Azure CLI

K přidání těchto nastavení můžete použít příkaz az functionapp config appsettings set , jak je znázorněno v následujícím příkladu -Djava.awt.headless=true pro možnost :

az functionapp config appsettings set \
    --settings "languageWorkers__java__arguments=-Djava.awt.headless=true" \
    --name <APP_NAME> --resource-group <RESOURCE_GROUP>

Tento příklad povolí režim bez hlavy. Nahraďte <APP_NAME> názvem vaší aplikace funkcí a <RESOURCE_GROUP> skupinou prostředků.

Knihovny třetích stran

Azure Functions podporuje použití knihoven třetích stran. Ve výchozím nastavení se všechny závislosti zadané v souboru projektu pom.xml automaticky seskupí během mvn package cíle. U knihoven, které nejsou v souboru zadané jako závislosti pom.xml , je umístěte do lib adresáře v kořenovém adresáři funkce. Závislosti umístěné v adresáři lib se přidají do zavaděče systémové třídy za běhu.

Závislost com.microsoft.azure.functions:azure-functions-java-library je ve výchozím nastavení k dispozici v cestě ke třídě a nemusí být zahrnuta lib do adresáře . Azure-functions-java-worker také přidá závislosti uvedené tady do cesty ke třídě.

Podpora datových typů

K vytvoření vazby se vstupními nebo výstupními vazbami můžete použít jednoduché staré objekty Java (POJO), typy definované v azure-functions-java-librarynebo primitivní datové typy, jako je String a Integer.

POJO

K převodu vstupních dat na POJO používá azure-functions-java-worker knihovnu gson . Typy POJO používané jako vstupy funkcí by měly být public.

Binární data

Vytvořte vazbu binárních vstupů nebo výstupů na byte[], a to nastavením dataType pole v souboru function.json na hodnotu binary:

   @FunctionName("BlobTrigger")
    @StorageAccount("AzureWebJobsStorage")
     public void blobTrigger(
        @BlobTrigger(name = "content", path = "myblob/{fileName}", dataType = "binary") byte[] content,
        @BindingName("fileName") String fileName,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Blob trigger function processed a blob.\n Name: " + fileName + "\n Size: " + content.length + " Bytes");
    }

Pokud očekáváte hodnoty null, použijte Optional<T>.

Vazby

Vstupní a výstupní vazby poskytují deklarativní způsob připojení k datům v rámci kódu. Funkce může mít několik vstupních a výstupních vazeb.

Příklad vstupní vazby

package com.example;

import com.microsoft.azure.functions.annotation.*;

public class Function {
    @FunctionName("echo")
    public static String echo(
        @HttpTrigger(name = "req", methods = { HttpMethod.PUT }, authLevel = AuthorizationLevel.ANONYMOUS, route = "items/{id}") String inputReq,
        @TableInput(name = "item", tableName = "items", partitionKey = "Example", rowKey = "{id}", connection = "AzureWebJobsStorage") TestInputData inputData,
        @TableOutput(name = "myOutputTable", tableName = "Person", connection = "AzureWebJobsStorage") OutputBinding<Person> testOutputData
    ) {
        testOutputData.setValue(new Person(httpbody + "Partition", httpbody + "Row", httpbody + "Name"));
        return "Hello, " + inputReq + " and " + inputData.getKey() + ".";
    }

    public static class TestInputData {
        public String getKey() { return this.rowKey; }
        private String rowKey;
    }
    public static class Person {
        public String partitionKey;
        public String rowKey;
        public String name;

        public Person(String p, String r, String n) {
            this.partitionKey = p;
            this.rowKey = r;
            this.name = n;
        }
    }
}

Tuto funkci vyvoláte pomocí požadavku HTTP.

  • Datová část požadavku HTTP se předává jako String argument inputReq.
  • Jedna položka se načte z table storage a předá se jako TestInputData argument inputData.

Pokud chcete přijmout dávku vstupů, můžete vytvořit vazbu na String[], POJO[], List<String>nebo List<POJO>.

@FunctionName("ProcessIotMessages")
    public void processIotMessages(
        @EventHubTrigger(name = "message", eventHubName = "%AzureWebJobsEventHubPath%", connection = "AzureWebJobsEventHubSender", cardinality = Cardinality.MANY) List<TestEventData> messages,
        final ExecutionContext context)
    {
        context.getLogger().info("Java Event Hub trigger received messages. Batch size: " + messages.size());
    }
    
    public class TestEventData {
    public String id;
}

Tato funkce se aktivuje vždy, když jsou v nakonfigurovaném centru událostí nová data. cardinality Protože je nastavená na MANY, přijímá funkce dávku zpráv z centra událostí. EventData z centra událostí se pro provádění funkce převede na TestEventData .

Příklad výstupní vazby

Výstupní vazbu na vrácenou hodnotu můžete vytvořit pomocí $returnpříkazu .

package com.example;

import com.microsoft.azure.functions.annotation.*;

public class Function {
    @FunctionName("copy")
    @StorageAccount("AzureWebJobsStorage")
    @BlobOutput(name = "$return", path = "samples-output-java/{name}")
    public static String copy(@BlobTrigger(name = "blob", path = "samples-input-java/{name}") String content) {
        return content;
    }
}

Pokud existuje více výstupních vazeb, použijte návratové hodnoty pouze pro jednu z nich.

Pokud chcete odeslat více výstupních hodnot, použijte příkaz OutputBinding<T> definovaný v azure-functions-java-library balíčku.

@FunctionName("QueueOutputPOJOList")
    public HttpResponseMessage QueueOutputPOJOList(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
            HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            @QueueOutput(name = "itemsOut", queueName = "test-output-java-pojo", connection = "AzureWebJobsStorage") OutputBinding<List<TestData>> itemsOut, 
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");
       
        String query = request.getQueryParameters().get("queueMessageId");
        String queueMessageId = request.getBody().orElse(query);
        itemsOut.setValue(new ArrayList<TestData>());
        if (queueMessageId != null) {
            TestData testData1 = new TestData();
            testData1.id = "msg1"+queueMessageId;
            TestData testData2 = new TestData();
            testData2.id = "msg2"+queueMessageId;

            itemsOut.getValue().add(testData1);
            itemsOut.getValue().add(testData2);

            return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + queueMessageId).build();
        } else {
            return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Did not find expected items in CosmosDB input list").build();
        }
    }

     public static class TestData {
        public String id;
    }

Tuto funkci vyvoláte u objektu HttpRequest . Zapisuje do služby Queue Storage několik hodnot.

HttpRequestMessage a HttpResponseMessage

Jsou definovány v azure-functions-java-librarysouboru . Jedná se o pomocné typy pro práci s funkcemi HttpTrigger.

Specializovaný typ Cíl Typické využití
HttpRequestMessage<T> Trigger HTTP Získá metodu, hlavičky nebo dotazy.
HttpResponseMessage Výstupní vazba HTTP Vrátí jiný stav než 200.

Metadata

Několik triggerů odesílá metadata triggeru spolu se vstupními daty. Pomocí poznámky @BindingName můžete vytvořit vazbu k aktivaci metadat.

package com.example;

import java.util.Optional;
import com.microsoft.azure.functions.annotation.*;


public class Function {
    @FunctionName("metadata")
    public static String metadata(
        @HttpTrigger(name = "req", methods = { HttpMethod.GET, HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) Optional<String> body,
        @BindingName("name") String queryValue
    ) {
        return body.orElse(queryValue);
    }
}

V předchozím příkladu je vázaný queryValue na parametr name řetězce dotazu v adrese URL požadavku HTTP . http://{example.host}/api/metadata?name=test Tady je další příklad, který ukazuje, jak vytvořit vazbu Id k metadatům triggeru fronty.

 @FunctionName("QueueTriggerMetadata")
    public void QueueTriggerMetadata(
        @QueueTrigger(name = "message", queueName = "test-input-java-metadata", connection = "AzureWebJobsStorage") String message,@BindingName("Id") String metadataId,
        @QueueOutput(name = "output", queueName = "test-output-java-metadata", connection = "AzureWebJobsStorage") OutputBinding<TestData> output,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Queue trigger function processed a message: " + message + " with metadaId:" + metadataId );
        TestData testData = new TestData();
        testData.id = metadataId;
        output.setValue(testData);
    }

Poznámka

Název zadaný v poznámce musí odpovídat vlastnosti metadat.

Kontext spuštění

ExecutionContext, definované v azure-functions-java-library, obsahuje pomocné metody pro komunikaci s modulem runtime funkcí. Další informace najdete v referenčním článku ExecutionContext.

Logger

K zápisu protokolů z kódu funkce použijte getLoggernástroj , definovaný v ExecutionContext.

Příklad:


import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;

public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) {
        if (req.isEmpty()) {
            context.getLogger().warning("Empty request body received by function " + context.getFunctionName() + " with invocation " + context.getInvocationId());
        }
        return String.format(req);
    }
}

Zobrazení protokolů a trasování

Pomocí Azure CLI můžete streamovat protokolování stdout a stderr v Javě a další protokolování aplikací.

Tady je postup konfigurace aplikace funkcí pro zápis protokolování aplikace pomocí Azure CLI:

az webapp log config --name functionname --resource-group myResourceGroup --application-logging true

Pokud chcete streamovat výstup protokolování pro aplikaci funkcí pomocí Azure CLI, otevřete nový příkazový řádek, Bash nebo relaci terminálu a zadejte následující příkaz:

az webapp log tail --name webappname --resource-group myResourceGroup

Příkaz az webapp log tail má možnosti filtrování výstupu pomocí možnosti .--provider

Pokud chcete soubory protokolu stáhnout jako jeden soubor ZIP pomocí Azure CLI, otevřete nový příkazový řádek, Bash nebo relaci terminálu a zadejte následující příkaz:

az webapp log download --resource-group resourcegroupname --name functionappname

Před spuštěním tohoto příkazu musíte povolit protokolování systému souborů v Azure Portal nebo v Azure CLI.

Proměnné prostředí

Ve Funkcích se nastavení aplikace, například připojovací řetězce služby, během provádění zveřejňují jako proměnné prostředí. K těmto nastavením můžete přistupovat pomocí příkazu System.getenv("AzureWebJobsStorage").

Následující příklad získá nastavení aplikace s klíčem s názvem myAppSetting:


public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) {
        context.getLogger().info("My app setting value: "+ System.getenv("myAppSetting"));
        return String.format(req);
    }
}

Použití injektáže závislostí ve funkcích Java

Azure Functions Java podporuje vzor návrhu softwaru pro injektáž závislostí (DI), což je technika k dosažení inverze řízení (IoC) mezi třídami a jejich závislostmi. Java Azure Functions poskytuje háček pro integraci s oblíbenými architekturami vkládání závislostí ve vašich aplikacích Functions. Azure Functions Java SPI obsahuje rozhraní FunctionInstanceInjector. Implementací tohoto rozhraní můžete vrátit instanci třídy funkce a funkce budou vyvolány v této instanci. Tím získáte architektury jako Spring, Quarkus, Google Guice, Dagger atd. možnost vytvořit instanci funkce a zaregistrovat ji do kontejneru IOC. To znamená, že tyto architektury vkládání závislostí můžete použít ke správě funkcí přirozeně.

Poznámka

Microsoft Azure Functions Java SPI Types (azure-function-java-spi) je balíček, který obsahuje všechna rozhraní SPI určená třetím stranám pro interakci s modulem runtime funkcí Microsoft Azure.

Injektor instance funkce pro injektáž závislostí

azure-function-java-spi obsahuje rozhraní FunctionInstanceInjector.

package com.microsoft.azure.functions.spi.inject; 

/** 

 * The instance factory used by DI framework to initialize function instance. 

 * 

 * @since 1.0.0 

 */ 

public interface FunctionInstanceInjector { 

    /** 

     * This method is used by DI framework to initialize the function instance. This method takes in the customer class and returns 

     * an instance create by the DI framework, later customer functions will be invoked on this instance. 

     * @param functionClass the class that contains customer functions 

     * @param <T> customer functions class type 

     * @return the instance that will be invoked on by azure functions java worker 

     * @throws Exception any exception that is thrown by the DI framework during instance creation 

     */ 

    <T> T getInstance(Class<T> functionClass) throws Exception; 

} 

Další příklady, které používají FunctionInstanceInjector k integraci s rozhraními injektáže závislostí, najdete v tomto úložišti.

Další kroky

Další informace o vývoji Azure Functions Javě najdete v následujících zdrojích informací: