Azure Functions Java-utvecklarguide
Den här guiden innehåller detaljerad information som hjälper dig att utveckla Azure Functions med Java.
Om du är nybörjare på att skriva Azure Functions Java-utvecklare kan du börja med att läsa någon av följande artiklar:
| Komma igång | Begrepp |
|---|---|
Grundläggande om Java-funktioner
En Java-funktion public är en -metod som är iserad med anteckningen @FunctionName . Den här metoden definierar posten för en Java-funktion och måste vara unik i ett visst paket. Paketet kan ha flera klasser med flera offentliga metoder kommenterade med @FunctionName . Ett enda paket distribueras till en funktionsapp i Azure. När du kör i Azure tillhandahåller funktionsappen distributions-, körnings- och hanteringskontext för dina enskilda Java-funktioner.
Programmeringsmodell
Begreppen utlösare och bindningar är grundläggande för Azure Functions. Utlösare startar körningen av din kod. Bindningar ger dig ett sätt att skicka data till och returnera data från en funktion, utan att behöva skriva anpassad kod för dataåtkomst.
Skapa Java-funktioner
För att göra det enklare att skapa Java-funktioner finns det Maven-baserade verktyg och arketyper som använder fördefinierade Java-mallar för att hjälpa dig att skapa projekt med en specifik funktionsutlösare.
Maven-baserade verktyg
Följande utvecklarmiljöer har ett Azure Functions som gör att du kan skapa Java-funktionsprojekt:
Artikellänkarna ovan visar hur du skapar dina första funktioner med valfri IDE.
Project Byggnadsställningar
Om du föredrar kommandoradsutveckling från terminalen är det enklaste sättet att skapa javabaserade funktionsprojekt att använda Apache Maven arketyper. Java Maven-arketypen för Azure Functions publiceras under följande _groupId:_artifactId: com.microsoft.azure:azure-functions-archetype.
Följande kommando genererar ett nytt Java-funktionsprojekt med hjälp av den här arketypen:
mvn archetype:generate \
-DarchetypeGroupId=com.microsoft.azure \
-DarchetypeArtifactId=azure-functions-archetype
Om du vill komma igång med den här arketypen kan du gå till Java-snabbstarten.
Mappstrukturen
Här är mappstrukturen för ett Azure Functions Java-projekt:
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
Du kan använda en delad host.json-fil för att konfigurera funktionsappen. Varje funktion har en egen kodfil (.java) och en bindningskonfigurationsfil (function.json).
Du kan placera fler än en funktion i ett projekt. Undvik att placera dina funktioner i separata jar-er. i FunctionApp målkatalogen är det som distribueras till funktionsappen i Azure.
Utlösare och anteckningar
Funktioner anropas av en utlösare, till exempel en HTTP-begäran, en timer eller en uppdatering av data. Din funktion måste bearbeta utlösaren och andra indata för att skapa en eller flera utdata.
Använd Java-anteckningarna som ingår i paketet com.microsoft.azure.functions.annotation.* för att binda indata och utdata till dina metoder. Mer information finns i Java-referensdokumenten.
Viktigt
Du måste konfigurera ett Azure Storage-konto i din local.settings.json för att köra Utlösare för Azure Blob Storage, Azure Queue Storage eller Azure Table Storage lokalt.
Exempel:
public class Function {
public String echo(@HttpTrigger(name = "req",
methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS)
String req, ExecutionContext context) {
return String.format(req);
}
}
Här är den genererade function.json som motsvarar azure-functions-maven-plugin:
{
"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"
}
]
}
Java-versioner
Den version av Java som används när du skapar funktionsappen där funktioner körs i Azure anges i pom.xml filen. Maven-arketypen genererar för närvarande en pom.xml för Java 8, som du kan ändra innan du publicerar. Java-versionen i pom.xml matcha den version som du har utvecklat lokalt och testat din app på.
Versioner som stöds
I följande tabell visas aktuella Java-versioner som stöds för varje huvudversion av Functions-körningen, efter operativsystem:
| Functions-version | Java-versioner (Windows) | Java-versioner (Linux) |
|---|---|---|
| 4.x | 11 8 |
11 8 |
| 3.x | 11 8 |
11 8 |
| 2.x | 8 | saknas |
Om du inte anger en Java-version för distributionen får Maven-arketypen som standard Java 8 under distributionen till Azure.
Ange distributionsversionen
Du kan styra vilken version av Java som Maven-arketypen har som mål med hjälp av -DjavaVersion parametern . Värdet för den här parametern kan vara antingen 8 eller 11 .
Maven-arketypen genererar en pom.xml som är inriktad på den angivna Java-versionen. Följande element i pom.xml Java-versionen som ska användas:
| Element | Java 8-värde | Java 11-värde | Description |
|---|---|---|---|
Java.version |
1.8 | 11 | Version av Java som används av maven-compiler-plugin. |
JavaVersion |
8 | 11 | Java-version som finns i funktionsappen i Azure. |
I följande exempel visas inställningarna för Java 8 i de relevanta avsnitten i pom.xml fil:
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>
Viktigt
Du måste ha JAVA_HOME miljövariabeln korrekt inställd på JDK-katalogen som används vid kodkompilera med Maven. Kontrollera att versionen av JDK är minst lika hög som Java.version inställningen.
Ange distributionsoperativsystemet
Med Maven kan du också ange det operativsystem som funktionsappen körs i Azure på. Använd os elementet för att välja operativsystem.
| Element | Windows | Linux | Docker |
|---|---|---|---|
os |
windows |
linux |
docker |
I följande exempel visas operativsysteminställningen i avsnittet runtime i den pom.xml filen:
<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>
Tillgänglighet och stöd för JDK-körning
För lokal utveckling av Java-funktionsappar laddar du ned och använder lämpliga Azul Zulu Enterprise för Azure Java-JDK:er från Azul Systems. Azure Functions använder en Azul Java JDK-körning när du distribuerar funktionsappen till molnet.
Azure-stöd för problem med JDK:er och funktionsappar är tillgängligt med en kvalificerad supportplan.
Anpassa JVM
Med Functions kan du anpassa den virtuella Java-datorn (JVM) som används för att köra Java-funktionerna. Följande JVM-alternativ används som standard:
-XX:+TieredCompilation-XX:TieredStopAtLevel=1-noverify-Djava.net.preferIPv4Stack=true-jar
Du kan ange ytterligare argument i en appinställning med namnet JAVA_OPTS . Du kan lägga till appinställningar i din funktionsapp som distribuerats till Azure i Azure Portal eller Azure CLI.
Viktigt
I förbrukningsplanen måste du också lägga till WEBSITE_USE_PLACEHOLDER med värdet 0 för att anpassningen ska fungera. Den här inställningen ökar kallstarttiderna för Java-funktioner.
Azure Portal
I Azure Portal dufliken Program och Inställningar för att lägga till JAVA_OPTS inställningen.
Azure CLI
Du kan använda kommandot az functionapp config appsettings set för att ange JAVA_OPTS , som i följande exempel:
az functionapp config appsettings set \
--settings "JAVA_OPTS=-Djava.awt.headless=true" \
"WEBSITE_USE_PLACEHOLDER=0" \
--name <APP_NAME> --resource-group <RESOURCE_GROUP>
Det här exemplet aktiverar huvudlöst läge. Ersätt <APP_NAME> med namnet på din funktionsapp och med <RESOURCE_GROUP> resursgruppen.
Bibliotek från tredje part
Azure Functions har stöd för användning av bibliotek från tredje part. Som standard paketeras alla beroenden som anges pom.xml i projektfilen automatiskt under mvn package målet. För bibliotek som inte anges som beroenden pom.xml i filen placerar du dem i en katalog i lib funktionens rotkatalog. Beroenden som placeras i lib katalogen läggs till i systemklassinläsaren vid körning.
Beroendet com.microsoft.azure.functions:azure-functions-java-library anges på klassökvägen som standard och behöver inte inkluderas i lib katalogen. Dessutom lägger azure-functions-java-worker till beroenden som anges här i klassökvägen.
Stöd för datatyper
Du kan använda vanliga gamla Java-objekt (POPO:er), typer som definierats i eller primitiva datatyper som String och Integer för att binda till indata- eller azure-functions-java-library utdatabindningar.
POJOs
För att konvertera indata till POJO använder azure-functions-java-worker gson-biblioteket. POJO-typer som används som indata till funktioner ska vara public .
Binära data
Bind binära indata eller utdata till byte[] genom att ange fältet i dataType function.json till 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");
}
Om du förväntar dig null-värden använder du Optional<T> .
Bindningar
Indata- och utdatabindningar är ett deklarativt sätt att ansluta till data inifrån koden. En funktion kan ha flera indata- och utdatabindningar.
Exempel på indatabindning
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;
}
}
}
Du anropar den här funktionen med en HTTP-begäran.
- NYTTOlast för HTTP-begäran skickas
Stringsom en för argumentetinputReq. - En post hämtas från Table Storage och skickas som
TestInputDatatill argumentetinputData.
Om du vill ta emot en batch med indata kan du binda String[] till , , eller POJO[] List<String> 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;
}
Den här funktionen utlöses när det finns nya data i den konfigurerade händelsehubben. Eftersom cardinality är inställt på MANY tar funktionen emot en batch med meddelanden från händelsehubben. EventData från händelsehubben konverteras till TestEventData för funktionskörningen.
Exempel på utdatabindning
Du kan binda en utdatabindning till returvärdet med hjälp av $return .
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;
}
}
Om det finns flera utdatabindningar använder du returvärdet för endast en av dem.
Om du vill skicka flera utdatavärden använder OutputBinding<T> du som definierats i azure-functions-java-library paketet.
@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;
}
Du anropar den här funktionen på en HttpRequest. Den skriver flera värden till Queue Storage.
HttpRequestMessage och HttpResponseMessage
Dessa definieras i azure-functions-java-library . De är hjälptyper för att arbeta med HttpTrigger-funktioner.
| Specialiserad typ | Mål | Normal användning |
|---|---|---|
HttpRequestMessage<T> |
HTTP-utlösare | Hämtar metod, rubriker eller frågor |
HttpResponseMessage |
HTTP-utdatabindning | Returnerar annan status än 200 |
Metadata
Få utlösare skickar utlösarmetadata tillsammans med indata. Du kan använda anteckningar för att @BindingName binda för att utlösa metadata.
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);
}
}
I föregående exempel är bunden queryValue till frågesträngparametern name i URL:en för HTTP-begäran, http://{example.host}/api/metadata?name=test . Här är ett annat exempel som visar hur du binder till från Id köutlösarmetadata.
@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);
}
Anteckning
Namnet som anges i kommentaren måste matcha metadataegenskapen.
Körningskontext
ExecutionContext, som definieras azure-functions-java-library i , innehåller hjälpmetoder för att kommunicera med functions-körningen. Mer information finns i referensartikeln för ExecutionContext.
Logger
Använd getLogger , som definieras i , för att ExecutionContext skriva loggar från funktionskoden.
Exempel:
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);
}
}
Visa loggar och spårning
Du kan använda Azure CLI för att strömma Java stdout- och stderr-loggning, samt annan programloggning.
Så här konfigurerar du din funktionsapp för att skriva programloggning med hjälp av Azure CLI:
az webapp log config --name functionname --resource-group myResourceGroup --application-logging true
Om du vill strömma loggningsutdata för funktionsappen med hjälp av Azure CLI öppnar du en ny kommandotolk, Bash eller terminalsession och anger följande kommando:
Kommandot az webapp log tail har alternativ för att filtrera utdata med hjälp av alternativet --provider .
Om du vill ladda ned loggfilerna som en zip-fil med hjälp av Azure CLI öppnar du en ny kommandotolk, Bash eller terminalsession och anger följande kommando:
az webapp log download --resource-group resourcegroupname --name functionappname
Du måste ha aktiverat loggning av filsystem i Azure Portal eller Azure CLI innan du kör det här kommandot.
Miljövariabler
I Functions exponeras appinställningar,till exempel tjänstanslutningssträngar, som miljövariabler under körningen. Du kan komma åt de här inställningarna med hjälp av System.getenv("AzureWebJobsStorage") .
I följande exempel hämtar programinställningen, med nyckeln med namnet 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);
}
}
Anteckning
Värdet för AppSetting FUNCTIONS_EXTENSION_VERSION vara ~2 eller ~3 för en optimerad kallstartsupplevelse.
Nästa steg
Mer information om hur Azure Functions Java-utveckling finns i följande resurser:
- Metodtips för Azure Functions
- Azure Functions, info för utvecklare
- Azure Functions utlösare och bindningar
- Lokal utveckling och felsökning med Visual Studio Code, IntelliJoch Eclipse
- Fjärrfelsök Java-funktioner med hjälp Visual Studio Code
- Maven-plugin-program för Azure Functions
- Effektivisera funktionsskapandet genom
azure-functions:addmålet och förbered en mellanlagringskatalog för DISTRIBUTION av ZIP-filer.