Руководство разработчика Java по Функциям AzureAzure Functions Java developer guide

Среда выполнения функций Azure поддерживает Java SE 8 LTS (Zulu 8.31.0.2-JRE 8.0.181-win_x64).The Azure Functions runtime supports Java SE 8 LTS (zulu8.31.0.2-jre8.0.181-win_x64). В этом руководства содержатся сведения об тонкостях написания функций Azure с помощью Java.This guide contains information about the intricacies of writing Azure Functions with Java.

Как и в случае с другими языками, приложение-функция может иметь одну или несколько функций.As it happens to other languages, a Function App may have one or more functions. Функция Java — это public метод, дополненный @FunctionNameзаметкой.A Java function is a public method, decorated with the annotation @FunctionName. Этот метод определяет запись для функции Java и должен быть уникальным в определенном пакете.This method defines the entry for a Java function, and must be unique in a particular package. Один приложение-функция, написанный на языке Java, может иметь несколько классов с несколькими открытыми методами, помеченными @FunctionName.One Function App written in Java may have multiple classes with multiple public methods annotated with @FunctionName.

В этой статье предполагается, что вы уже прочли руководство для разработчиков по Функциям Azure.This article assumes that you have already read the Azure Functions developer reference. Кроме того, вы должны заполнить краткое руководство по функциям, чтобы создать свою первую функцию с помощью Visual Studio Code или Maven.You should also complete the Functions quickstart to create your first function, by using Visual Studio Code or Maven.

Модель программированияProgramming model

Понятия триггеров и привязок играют решающую роль в Функциях Azure.The concepts of triggers and bindings are fundamental to Azure Functions. Триггеры запускают выполнение вашего кода.Triggers start the execution of your code. Привязки предоставляют возможность передавать данные, а также возвращать их из функции без необходимости написания кода доступа к ним.Bindings give you a way to pass data to and return data from a function, without having to write custom data access code.

Создание функций JavaCreate Java functions

Чтобы упростить создание функций Java, существуют средства на основе Maven и архетипов, использующие стандартные шаблоны Java для создания проектов с определенным триггером функции.To make it easier to create Java functions, there are Maven-based tooling and archetypes that use predefined Java templates to help you create projects with a specific function trigger.

Инструментарий на основе MavenMaven-based tooling

В следующих средах разработки есть Инструментарий функций Azure, позволяющий создавать проекты функций Java:The following developer environments have Azure Functions tooling that lets you create Java function projects:

В статье выше показано, как создать первые функции с помощью вашей интегрированной среды разработки.The article links above show you how to create your first functions using your IDE of choice.

Формирование шаблонов проектовProject Scaffolding

Если вы предпочитаете выполнять разработку из командной строки с помощью терминала, самый простой способ формирования шаблонов проектов функций на основе Java — использовать Apache Maven архетипов.If you prefer command line development from the Terminal, the simplest way to scaffold Java-based function projects is to use Apache Maven archetypes. В настоящее время существует две функции, архетипов для Maven:There are currently two Functions archetypes for Maven:

Исходный код этих архетипов можно найти в репозитории Azure Maven архетипов GitHub.The source code of these archetypes can be found on the Azure Maven Archetypes GitHub repository.

Структура папокFolder structure

Ниже приведена структура папок проекта Java для функций Azure.Here is the folder structure of an Azure Functions Java project:

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

* Проект Котлин выглядит очень похожим, так как он все еще Maven* The Kotlin project looks very similar since it is still Maven

Для настройки приложения-функции можно использовать общий файл Host. JSON .You can use a shared host.json file to configure the function app. У каждой функции есть собственный файл кода (.java) и файл конфигурации привязки (function.json).Each function has its own code file (.java) and binding configuration file (function.json).

Вы можете добавить несколько функций в проект.You can put more than one function in a project. Не добавляйте функции в отдельные JAR-файлы.Avoid putting your functions into separate jars. FunctionApp в целевом каталоге, который развертывается в приложении-функции в Azure.The FunctionApp in the target directory is what gets deployed to your function app in Azure.

Триггеры и заметкиTriggers and annotations

Функции вызываются триггером, например HTTP-запросом, таймером или обновлением данных.Functions are invoked by a trigger, such as an HTTP request, a timer, or an update to data. Функция должна обработать этот триггер, а также любые другие входные данные, чтобы получить один или несколько выходов.Your function needs to process that trigger, and any other inputs, to produce one or more outputs.

Используйте заметки Java, включенные в пакет com.microsoft.azure.functions.annotation.*, чтобы привязать входные и выходные данные к своим методам.Use the Java annotations included in the com.microsoft.azure.functions.annotation.* package to bind input and outputs to your methods. Дополнительные сведения см. в справочных документах по Java.For more information, see the Java reference docs.

Важно!

Учетную запись хранения Azure необходимо настроить в локальном. Settings. JSON для запуска хранилища BLOB-объектов Azure, хранилища очередей Azure или для локальных триггеров хранилища таблиц Azure.You must configure an Azure Storage account in your local.settings.json to run Azure Blob storage, Azure Queue storage, or Azure Table storage triggers locally.

Пример:Example:

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

Ниже приведена созданная соответствующая function.json в Azure-functions-maven-plugin:Here is the generated corresponding function.json by the azure-functions-maven-plugin:

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

Обеспечения доступности и предоставления поддержки времени выполнения пакета JDKJDK runtime availability and support

Для локальной разработки приложений с функциями Java Скачайте и используйте Azul Zulu Enterprise для Azure Java 8 JDK от Azul Systems.For local development of Java function apps, download and use the Azul Zulu Enterprise for Azure Java 8 JDKs from Azul Systems. Функции Azure используют среду выполнения Azul Java 8 JDK, если вы развертываете приложения-функции в облако.Azure Functions uses the Azul Java 8 JDK runtime when you deploy your function apps to the cloud.

Поддержка Azure для проблем, связанных с JDK и приложениями-функциями, доступна в полном плане поддержки.Azure support for issues with the JDKs and function apps is available with a qualified support plan.

Настройка ВИРТУАЛЬНОЙ машины JavaCustomize JVM

Функции позволяют настроить виртуальную машину Java (ВИРТУАЛЬНОЙ машины Java), используемую для выполнения функций Java.Functions lets you customize the Java virtual machine (JVM) used to run your Java functions. По умолчанию используются следующие параметры виртуальной машины Java :The following JVM options are used by default:

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

Дополнительные аргументы можно указать в параметре приложения с именем JAVA_OPTS.You can provide additional arguments in an app setting named JAVA_OPTS. Вы можете добавить параметры приложения в приложение функции, развернутое в Azure, в портал Azure или Azure CLI.You can add app settings to your function app deployed to Azure in the Azure portal or the Azure CLI.

Портал AzureAzure portal

В портал Azureиспользуйте вкладку Параметры приложения , чтобы добавить параметр JAVA_OPTS.In the Azure portal, use the Application Settings tab to add the JAVA_OPTS setting.

Интерфейс командной строки AzureAzure CLI

Для установки JAVA_OPTSможно использовать команду AZ functionapp config appSettings Set , как показано в следующем примере:You can use the az functionapp config appsettings set command to set JAVA_OPTS, as in the following example:

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

Этот пример включает режим без монитора.This example enables headless mode. Замените <APP_NAME> именем приложения функции и <RESOURCE_GROUP> с группой ресурсов.Replace <APP_NAME> with the name of your function app, and <RESOURCE_GROUP> with the resource group.

Предупреждение

В плане потреблениянеобходимо добавить параметр WEBSITE_USE_PLACEHOLDER со значением 0.In the Consumption plan, you must add the WEBSITE_USE_PLACEHOLDER setting with a value of 0.
Этот параметр увеличивает время холодного запуска для функций Java.This setting does increase the cold start times for Java functions.

Сторонние библиотекиThird-party libraries

Служба "Функции Azure" поддерживает использование сторонних библиотек.Azure Functions supports the use of third-party libraries. По умолчанию все зависимости, указанные в файле проекта pom.xml, автоматически объединяются во время mvn package цели.By default, all dependencies specified in your project pom.xml file are automatically bundled during the mvn package goal. Зависимости библиотек, не указанных как зависимости в файле pom.xml, поместите в каталог lib в корневой папке функции.For libraries not specified as dependencies in the pom.xml file, place them in a lib directory in the function's root directory. Зависимости, помещенные в каталог lib, добавляются в загрузчик системных классов во время выполнения.Dependencies placed in the lib directory are added to the system class loader at runtime.

Зависимость com.microsoft.azure.functions:azure-functions-java-library предоставляется в подкаталогах классов по умолчанию и не требуется включать в каталог lib.The com.microsoft.azure.functions:azure-functions-java-library dependency is provided on the classpath by default, and doesn't need to be included in the lib directory. Кроме того, Azure-functions-Java-Worker добавляет зависимости, перечисленные здесь , в подкаталог классов.Also, azure-functions-java-worker adds dependencies listed here to the classpath.

Поддержка типов данныхData type support

Для привязки к входным или выходным привязкам можно использовать обычные старые объекты Java (POJO), типы, определенные в azure-functions-java-library, или примитивные типы данных, такие как String и Integer.You can use Plain old Java objects (POJOs), types defined in azure-functions-java-library, or primitive data types such as String and Integer to bind to input or output bindings.

POJOPOJOs

Для преобразования входных данных в POJO Azure-functions-Java-Worker использует библиотеку gson .For converting input data to POJO, azure-functions-java-worker uses the gson library. Типам POJO, используемые как входные данные для функций, необходим такой же модификатор доступа public.POJO types used as inputs to functions should be public.

Двоичные данныеBinary data

Привязка входных двоичных данных или выходов к byte[]путем установки поля dataType в файле Function. JSON для binary:Bind binary inputs or outputs to byte[], by setting the dataType field in your function.json to 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");
    }

Если предполагается наличие значений NULL, используйте Optional<T>.If you expect null values, use Optional<T>.

ПривязкиBindings

Входные и выходные привязки реализуют декларативный способ подключения к данным из кода.Input and output bindings provide a declarative way to connect to data from within your code. У функции может быть несколько входных и выходных привязок.A function can have multiple input and output bindings.

Пример входной привязкиInput binding example

package com.example;

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

public class Function {
    @FunctionName("echo")
    public static String echo(
        @HttpTrigger(name = "req", methods = { "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;
        }
    }
}

Эта функция вызывается с HTTP-запросом.You invoke this function with an HTTP request.

  • Полезные данные HTTP-запроса передаются в качестве String аргумента inputReq.HTTP request payload is passed as a String for the argument inputReq.
  • Одна запись извлекается из хранилища таблиц и передается как TestInputData аргументу inputData.One entry is retrieved from Table storage, and is passed as TestInputData to the argument inputData.

Чтобы получить пакет входных данных, можно выполнить привязку к String[], POJO[], List<String>или List<POJO>.To receive a batch of inputs, you can bind to String[], POJO[], List<String>, or 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;
}

Эта функция запускается всякий раз, когда в настроенном концентраторе событий появляются новые данные.This function gets triggered whenever there is new data in the configured event hub. Так как cardinality имеет значение MANY, функция получает пакет сообщений из концентратора событий.Because the cardinality is set to MANY, the function receives a batch of messages from the event hub. EventData из концентратора событий преобразуется в TestEventData для выполнения функции.EventData from event hub gets converted to TestEventData for the function execution.

Пример выходной привязкиOutput binding example

Выходную привязку можно привязать к возвращаемому значению с помощью $return.You can bind an output binding to the return value by using $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;
    }
}

При наличии нескольких выходных привязок используйте возвращаемое значение только для одной из них.If there are multiple output bindings, use the return value for only one of them.

Чтобы отправить несколько выходных значений, используйте тип OutputBinding<T>, который определен в пакете azure-functions-java-library.To send multiple output values, use OutputBinding<T> defined in the azure-functions-java-library package.

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

Эта функция вызывается для HttpRequest.You invoke this function on an HttpRequest. Он записывает несколько значений в хранилище очередей.It writes multiple values to Queue storage.

HttpRequestMessage и HttpResponseMessageHttpRequestMessage and HttpResponseMessage

Они определяются в azure-functions-java-library.These are defined in azure-functions-java-library. Они являются вспомогательными типами для работы с HttpTrigger функциями.They are helper types to work with HttpTrigger functions.

Специализированный типSpecialized type Выбор пути миграцииTarget Типичное использованиеTypical usage
HttpRequestMessage<T> Триггер HTTPHTTP Trigger Возвращает метод, заголовки или запросыGets method, headers, or queries
HttpResponseMessage Привязка к выходным данным HTTPHTTP Output Binding Возвращает состояние, отличное от 200Returns status other than 200

МетаданныеMetadata

Несколько триггеров отправляют метаданные триггеров вместе с входными данными.Few triggers send trigger metadata along with input data. Для привязки к метаданным триггера можно использовать @BindingName аннотации.You can use annotation @BindingName to bind to trigger 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 = { "get", "post" }, authLevel = AuthorizationLevel.ANONYMOUS) Optional<String> body,
        @BindingName("name") String queryValue
    ) {
        return body.orElse(queryValue);
    }
}

В предыдущем примере queryValue привязан к параметру строки запроса, name в URL-адресе запроса HTTP http://{example.host}/api/metadata?name=test.In the preceding example, the queryValue is bound to the query string parameter name in the HTTP request URL, http://{example.host}/api/metadata?name=test. Вот еще один пример, показывающий, как выполнить привязку к Id из метаданных триггера очереди.Here's another example, showing how to bind to Id from queue trigger metadata.

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

Примечание

Имя, указанное в заметке, должно соответствовать свойству метаданных.The name provided in the annotation needs to match the metadata property.

Контекст выполненияExecution context

ExecutionContext, определенные в azure-functions-java-library, содержит вспомогательные методы для взаимодействия со средой выполнения функций.ExecutionContext, defined in the azure-functions-java-library, contains helper methods to communicate with the functions runtime.

Средство ведения журналаLogger

Используйте getLogger, определенные в ExecutionContext, для записи журналов из кода функции.Use getLogger, defined in ExecutionContext, to write logs from function code.

Пример:Example:


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

public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {"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);
    }
}

Просмотр журналов и трассировкиView logs and trace

Вы можете использовать Azure CLI для потокового ведения журнала Java stdout и stderr, а также для других событий ведения журнала приложений.You can use the Azure CLI to stream Java stdout and stderr logging, as well as other application logging.

Вот как можно настроить приложение функции для записи журнала приложений с помощью Azure CLI:Here's how to configure your function app to write application logging by using the Azure CLI:

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

Чтобы передать выходные данные журнала для приложения-функции с помощью Azure CLI, откройте новую командную строку, bash или сеанс терминала и введите следующую команду:To stream logging output for your function app by using the Azure CLI, open a new command prompt, Bash, or Terminal session, and enter the following command:

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

Команда AZ webapp log хвоста имеет параметры для фильтрации выходных данных с помощью параметра --provider.The az webapp log tail command has options to filter output by using the --provider option.

Чтобы загрузить файлы журнала в виде одного ZIP-файла с помощью Azure CLI, откройте новую командную строку, bash или сеанс терминала и введите следующую команду:To download the log files as a single ZIP file by using the Azure CLI, open a new command prompt, Bash, or Terminal session, and enter the following command:

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

Перед выполнением этой команды необходимо включить ведение журнала файловой системы в портал Azure или Azure CLI.You must have enabled file system logging in the Azure portal or the Azure CLI before running this command.

Переменные средыEnvironment variables

В Функциях параметры приложения, такие как строки подключения службы, доступны в виде переменных среды во время выполнения.In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. Доступ к этим параметрам можно получить с помощью, System.getenv("AzureWebJobsStorage").You can access these settings by using, System.getenv("AzureWebJobsStorage").

В следующем примере возвращается параметр приложенияс ключом с именем myAppSetting:The following example gets the application setting, with the key named myAppSetting:


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

Дальнейшие действияNext steps

Дополнительные сведения о разработке приложений Java с помощью функций Azure см. в следующих ресурсах:For more information about Azure Functions Java development, see the following resources: