Azure İşlevleri Java geliştirici kılavuzu

Bu kılavuz, Java kullanarak uygulama geliştirmeyi başarılı bir şekilde Azure İşlevleri ayrıntılı bilgiler içerir.

Java geliştiricisi olarak, yeni bir Azure İşlevleri önce aşağıdaki makalelerden birini okumayı düşünün:

Başlarken Kavramlar

Java işlevinin temelleri

Java işlevi, ek public açıklamasıyla dekore edilmiş bir @FunctionName yöntemdir. Bu yöntem, bir Java işlevinin girişini tanımlar ve belirli bir pakette benzersiz olmalıdır. Paketin, ile açıklama ek açıklamalı birden çok genel yöntemi olan birden çok sınıfı @FunctionName olabilir. Azure'da bir işlev uygulamasına tek bir paket dağıtılır. Azure'da çalıştırsanız, işlev uygulaması tek tek Java işlevleriniz için dağıtım, yürütme ve yönetim bağlamı sağlar.

Programlama modeli

Tetikleyiciler ve bağlama kavramları, tetikleyiciler ve Azure İşlevleri. Tetikleyiciler kodunuzun yürütülmesini başlatıyor. Bağlamalar, özel veri erişim kodu yazmak zorunda kalmadan bir işleve veri ileten ve işlevden veri iade etmek için size bir yol sağlar.

Java işlevleri oluşturma

Java işlevleri oluşturmanızı kolaylaştırmak için, belirli bir işlev tetikleyicisi ile projeler oluşturmanıza yardımcı olmak üzere önceden tanımlanmış Java şablonları kullanan Maven tabanlı araç ve arketipler vardır.

Maven tabanlı araç

Aşağıdaki geliştirici ortamlarının Java Azure İşlevleri oluşturmanızı sağlayan farklı araçları vardır:

Yukarıdaki makale bağlantıları, tercihi IDE'nizi kullanarak ilk işlevlerinizi nasıl oluşturabilirsiniz?

Project Iskele

Terminalden komut satırı geliştirmeyi tercih ediyorsanız, Java tabanlı işlev projelerini iskeleye yüklemenin en basit yolu Apache Maven arketipleri kullanmaktır. Azure İşlevleri için Java Maven archetype şu groupId:artifactId: com.microsoft.azure:azure-functions-archetype altında yayımlanır.

Aşağıdaki komut, bu arketipi kullanarak yeni bir Java işlev projesi üretir:

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

Bu arketipi kullanmaya başlama için bkz. Java hızlı başlangıç.

Klasör yapısı

Java projesinin klasör yapısı Azure İşlevleri:

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

İşlev uygulamasını yapılandırmak için paylaşılan bir host.json dosyası kullanabilirsiniz. Her işlevin kendi kod dosyası (.java) ve bağlama yapılandırma dosyası (function.json) vardır.

Bir projeye birden fazla işlev koyarak. İşlevlerinizi ayrı jar'lara koymaktan kaçının. Hedef FunctionApp dizinde, Azure'daki işlev uygulamanıza dağıtılan dizindir.

Tetikleyiciler ve ek açıklamalar

İşlevler HTTP isteği, zamanlayıcı veya veri güncelleştirmesi gibi bir tetikleyici tarafından çağrılır. İşlevin bir veya daha fazla çıkış üretmek için bu tetikleyiciyi ve diğer girişleri işlemesi gerekir.

Giriş ve çıkışları yöntemlerinize bağlamak için com.microsoft.azure.functions.annotation.* paketine dahil edilen Java ek açıklamalarını kullanın. Daha fazla bilgi için Java başvuru belgelerine bakın.

Önemli

Azure Blob depolama, Azure Kuyruk Depolama veya Azure Tablo depolama tetikleyicilerini yerel olarak çalıştırmak için local.settings.json içinde bir Azure Depolama hesabı yapılandırmanız gerekir.

Örnek:

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

function.json azure-functions-maven-plugin tarafından oluşturulan şu şekildedir:

{
  "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 sürümleri

azure'da işlevlerin çalıştır olduğu işlev uygulamasını oluştururken kullanılan Java sürümü, pom.xml belirtilir. Maven arketipi şu anda Java 8 pom.xml yayımlamadan önce değiştirip değiştiremeden önce bir uygulama oluştur. pom.xml'daki Java sürümü, yerel olarak geliştirmiş ve test edilmiş olan sürümle eşleşmeli.

Desteklenen sürümler

Aşağıdaki tabloda, işletim sistemine göre İşlevler çalışma zamanının her ana sürümü için desteklenen geçerli Java sürümleri yer alır:

İşlevler sürümü Java sürümleri (Windows) Java sürümleri (Linux)
4.x 11
8
11
8
3.x 11
8
11
8
2.x 8 yok

Dağıtımınız için bir Java sürümü belirtmedikçe Maven arketipi, Azure'a dağıtım sırasında varsayılan olarak Java 8'i kullanır.

Dağıtım sürümünü belirtme

parametresini kullanarak Maven arketipi tarafından hedeflenen Java sürümünü kontrol -DjavaVersion edin. Bu parametrenin değeri veya 8 11 olabilir.

Maven arketipi, pom.xml Java sürümünü hedef alan bir komut türü üretir. aşağıdaki öğeler pom.xml Java sürümünü gösteriyor:

Öğe Java 8 değeri Java 11 değeri Description
Java.version 1.8 11 maven-compiler-plugin tarafından kullanılan Java sürümü.
JavaVersion 8 11 Azure'da işlev uygulaması tarafından barındırılan Java sürümü.

Aşağıdaki örneklerde, Java 8'in ayarları, dosyanın ilgili pom.xml gösterir:

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>

Önemli

Ortam değişken JAVA_HOME Maven kullanarak kod derleme sırasında kullanılan JDK dizinine doğru ayarlanmış olmalıdır. JDK sürümünün en azından ayar kadar yüksek olduğundan emin Java.version olun.

Dağıtım işletim sistemi belirtme

Maven ayrıca işlev uygulamanın Azure'da çalıştır olduğu işletim sistemini belirtmenize de olanak sağlar. İşletim os sistemini seçmek için öğesini kullanın.

Öğe Windows Linux Docker
os windows linux docker

Aşağıdaki örnekte, pom.xml dosyasının runtime bölümünde yer alan işletim pom.xml gösterir:

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

JDK çalışma zamanı kullanılabilirliği ve desteği

Java işlev uygulamalarının yerel olarak geliştirilmesi için, Azul Systems'danAzure Java JDK'leri için uygun Azul Zulu Enterprise'leri indirip kullanın. Azure İşlevleri buluta dağıtırken azul Java JDK çalışma zamanı kullanır.

Azure desteği JDK'lerle ve işlev uygulamalarıyla ilgili sorunlar için uygun bir destek planı ile birlikte kullanılabilir.

JVM'yi özelleştirme

İşlevler, Java işlevlerinizi çalıştırmak için kullanılan Java sanal makinesini (JVM) özelleştirmenize olanak sağlar. Aşağıdaki JVM seçenekleri varsayılan olarak kullanılır:

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

adlı bir uygulama ayarında ek bağımsız değişkenler JAVA_OPTS sebilirsiniz. Uygulama ayarlarını Azure'a dağıtılan işlev uygulamanıza uygulama ayarlarını Azure portal Azure CLI'sinde ebilirsiniz.

Önemli

Tüketim planında, özelleştirmenin çalışması için WEBSITE_USE_PLACEHOLDER 0 değerine sahip bir değerle birlikte varsayılan değer ayarını da eklemeniz gerekir. Bu ayar, Java işlevleri için soğuk başlangıç sürelerini artırmaz.

Azure portal

uygulama Azure portal,ayarı eklemek Ayarlar Uygulama Uygulama Sekmesi'ne JAVA_OPTS tıklayın.

Azure CLI

Aşağıdaki örnekte olduğu gibi ayarlamak için az functionapp config appsettings set komutunu JAVA_OPTS kullanabilirsiniz:

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

Bu örnek, başsız modu sağlar. yerine <APP_NAME> işlev uygulamanın adını, yerine <RESOURCE_GROUP> de kaynak grubunu yazın.

Üçüncü taraf kitaplıklar

Azure İşlevleri üçüncü taraf kitaplıkların kullanımını destekler. Varsayılan olarak, proje dosyanız içinde belirtilen tüm pom.xml bağımlılıklar hedef sırasında otomatik olarak mvn package paketlenir. Dosyada bağımlılık olarak belirtilmemiş pom.xml kitaplıklar için, bunları işlevin kök lib dizininde bir dizine yer açın. dizinine yerleştirilen lib bağımlılıklar çalışma zamanında sistem sınıfı yükleyicisine eklenir.

Bağımlılık com.microsoft.azure.functions:azure-functions-java-library varsayılan olarak sınıf yolu üzerinde sağlanır ve dizinine dahil olması gerek lib değildir. Ayrıca, azure-functions-java-worker burada listelenen bağımlılıkları sınıf yoluna ekler.

Veri türü desteği

Giriş veya çıkış bağlamalarına bağlamak için Düz eski Java nesneleri (POJOs), içinde tanımlanan türleri veya Dize ve Tamsayı gibi ilkel veri azure-functions-java-library türlerini kullanabilirsiniz.

POJO'lar

Giriş verilerini POJO'ya dönüştürmek için azure-functions-java-worker gson kitaplığını kullanır. İşlevlere giriş olarak kullanılan POJO türleri olması public gerekir.

İkili veriler

function.json dosyanız içinde alanını olarak ayarerek ikili byte[] girişleri veya dataType çıkışları olarak binary bağlayın:

   @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 değerler bekliyorsanız Optional<T> kullanın.

Bağlamalar

Giriş ve çıkış bağlamaları, kodunuz içindeki verilere bağlanmak için bildirime bağlı bir yol sağlar. Bir işlevin birden çok giriş ve çıkış bağlaması olabilir.

Giriş bağlama örneği

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

Bu işlevi bir HTTP isteğiyle çağırırsiniz.

  • HTTP isteği yükü, bağımsız değişkeni için String olarak inputReq geçirildi.
  • Bir giriş Tablo depolama alanından alınır ve bağımsız TestInputData değişkenine olarak inputData geçirildi.

Bir giriş toplu işi almak için , String[] , veya POJO[] 'ye List<String> List<POJO> bağlanebilirsiniz.

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

Yapılandırılan olay hub'larında yeni veriler olduğunda bu işlev tetiklenir. olarak cardinality ayarlanmış olduğundan MANY işlev, olay hub'larından toplu ileti alır. EventData olay hub'ını işlevin TestEventData yürütülmesi için olarak dönüştürülür.

Çıkış bağlama örneği

kullanarak dönüş değerine bir çıkış bağlaması b $return bağlanarak.

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

Birden çok çıkış bağlaması varsa, bunlardan yalnızca biri için dönüş değerini kullanın.

Birden çok çıkış değeri göndermek için OutputBinding<T> pakette tanımlanan değeri azure-functions-java-library kullanın.

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

Bu işlevi bir HttpRequest üzerinde çağırırsiniz. Kuyruk depolamaya birden çok değer yazar.

HttpRequestMessage ve HttpResponseMessage

Bunlar içinde azure-functions-java-library tanımlanır. Bunlar HttpTrigger işlevleriyle çalışmak için yardımcı türlerdir.

Özelleştirilmiş tür Hedef Tipik kullanım
HttpRequestMessage<T> HTTP Tetikleyicisi Yöntemi, üst bilgileri veya sorguları alır
HttpResponseMessage HTTP Çıkış Bağlaması 200 dışında bir durum döndürür

Meta veri

Birkaç tetikleyici, giriş verileriyle birlikte tetikleyici meta verilerini gönderir. Meta verileri tetiklemek üzere @BindingName bağlamak için ek açıklama kullanabilirsiniz.

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

Yukarıdaki örnekte , queryValue HTTP istek URL'sinde sorgu dizesi name parametresine http://{example.host}/api/metadata?name=test bağlıdır. Kuyruk tetikleyici meta verilerinden nasıl bağlanacağını gösteren Id başka bir örnek daha ve burada ve daha sonra yer alan bir örnektir.

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

Not

Ek açıklamada sağlanan adın meta veri özelliğiyle eşleşmesi gerekir.

Yürütme bağlamı

ExecutionContextiçinde tanımlanan azure-functions-java-library , işlev çalışma zamanıyla iletişim kurmak için yardımcı yöntemleri içerir. Daha fazla bilgi için ExecutionContext başvuru makalesine bakın.

Günlükçü

İşlev getLogger kodundan günlük ExecutionContext yazmak için içinde tanımlanan kullanın.

Örnek:


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

Günlükleri ve izlemeyi görüntüleme

Azure CLI'sini kullanarak Java stdout ve stderr günlük kaydı akışının yanı sıra diğer uygulama günlüklerini de kullanabilirsiniz.

İşlev uygulamanızı Azure CLI kullanarak uygulama günlüğü yazacak şekilde yapılandırma:

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

Azure CLI kullanarak işlev uygulamanıza yönelik günlük çıkışının akışını yapmak için yeni bir komut istemi, Bash veya Terminal oturumu açın ve aşağıdaki komutu girin:

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

az webapp log tail komutu, seçeneğini kullanarak çıkışı filtreleme --provider seçeneklerine sahiptir.

Azure CLI kullanarak günlük dosyalarını tek bir ZIP dosyası olarak indirmek için yeni bir komut istemi, Bash veya Terminal oturumu açın ve aşağıdaki komutu girin:

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

Bu komutu çalıştırmadan önce dosya sistemi günlüğünü Azure portal Azure CLI'da etkinleştirmiş olması gerekir.

Ortam değişkenleri

İşlevler'de,hizmet bağlantı dizeleri gibi uygulama ayarları yürütme sırasında ortam değişkenleri olarak ortaya çıkar. Bu ayarlara, kullanarak System.getenv("AzureWebJobsStorage") erişebilirsiniz.

Aşağıdaki örnek, adlı anahtarlauygulama ayarını myAppSetting alır:


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

Not

İyileştirilmiş bir soğuk FUNCTIONS_EXTENSION_VERSION için AppSetting FUNCTIONS_EXTENSION_VERSION değerinin ~2 veya ~3 olması gerekir.

Sonraki adımlar

Java geliştirme hakkında daha Azure İşlevleri için aşağıdaki kaynaklara bakın: