Azure İşlevleri özel işleyicileri

Her İşlev uygulaması dile özgü bir işleyici tarafından yürütülür. Azure İşlevleri varsayılan olarak birçok dil işleyicisine sahip olsa da, diğer dilleri veya çalışma zamanlarını kullanmak isteyebileceğiniz durumlar vardır.

Özel işleyiciler, İşlevler ana bilgisayarından olay alan basit web sunucularıdır. HTTP temel öğelerini destekleyen tüm diller özel bir işleyici uygulayabilir.

Özel işleyiciler, şu durumlarda en uygun olanlardır:

  • Go veya Rust gibi kullanıma hazır olarak sunulmayan bir dilde işlev uygulaması uygulayın.
  • Deno gibi varsayılan olarak öne çıkarılmayan bir çalışma zamanında işlev uygulaması uygulayın.

Özel işleyicilerle, uzantı paketleri aracılığıyla tetikleyicileri ve giriş ve çıkış bağlamalarını kullanabilirsiniz.

Go ve Rust'ta hızlı başlangıçlarla Azure İşlevleri özel işleyicileri kullanmaya başlayın.

Genel Bakış

Aşağıdaki diyagramda İşlevler konağı ile özel işleyici olarak uygulanan bir web sunucusu arasındaki ilişki gösterilmektedir.

Azure İşlevleri özel işleyiciye genel bakış

  1. Her olay İşlevler konağına gönderilen bir isteği tetikler. Olay, Azure İşlevleri tarafından desteklenen herhangi bir tetikleyicidir.
  2. ardından İşlevler ana bilgisayarı web sunucusuna bir istek yükü verir. Yük, tetikleyici ve giriş bağlama verilerini ve işlevin diğer meta verilerini tutar.
  3. Web sunucusu tek tek işlevi yürütür ve İşlevler konağına bir yanıt yükü döndürür.
  4. İşlevler konağı, yanıttan verileri işleme için işlevin çıkış bağlamalarına geçirir.

Özel işleyici olarak uygulanan bir Azure İşlevleri uygulamasının host.json, local.settings.json ve function.json dosyalarını birkaç kurala göre yapılandırması gerekir.

Uygulama yapısı

Özel işleyici uygulamak için uygulamanız için aşağıdaki yönlere ihtiyacınız vardır:

  • Uygulamanızın kökünde bir host.json dosyası
  • Uygulamanızın kökünde local.settings.json dosyası
  • Her işlev için bir function.json dosyası (işlev adıyla eşleşen bir klasörün içinde)
  • Web sunucusu çalıştıran komut, betik veya yürütülebilir dosya

Aşağıdaki diyagramda, "MyQueueFunction" adlı bir işlev ve handler.exeadlı özel işleyici yürütülebilir dosyası için bu dosyaların dosya sisteminde nasıl göründüğü gösterilmektedir.

| /MyQueueFunction
|   function.json
|
| host.json
| local.settings.json
| handler.exe

Yapılandırma

Uygulama host.json ve local.settings.json dosyaları aracılığıyla yapılandırılır.

host.json

host.json , HTTP olaylarını işleyebilen bir web sunucusuna işaret ederek İşlevler konağına istekleri nereye göndereceklerini söyler.

Özel işleyici, host.json dosyasının bölümü aracılığıyla customHandler web sunucusunun nasıl çalıştırılması gerektiğiyle ilgili ayrıntılarla yapılandırılarak tanımlanır.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "handler.exe"
    }
  }
}

customHandler bölümü tarafından tanımlanan bir hedefe işaret ettidefaultExecutablePath. Yürütme hedefi, web sunucusunun uygulandığı bir komut, yürütülebilir dosya veya dosya olabilir.

arguments Herhangi bir bağımsız değişkeni yürütülebilir dosyaya geçirmek için diziyi kullanın. Bağımsız değişkenler, gösterimi kullanarak %% ortam değişkenlerinin (uygulama ayarları) genişletilmesine destek olur.

ile yürütülebilir dosya workingDirectorytarafından kullanılan çalışma dizinini de değiştirebilirsiniz.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "app/handler.exe",
      "arguments": [
        "--database-connection-string",
        "%DATABASE_CONNECTION_STRING%"
      ],
      "workingDirectory": "app"
    }
  }
}
Bağlama desteği

Giriş ve çıkış bağlamalarıyla birlikte standart tetikleyiciler, host.json dosyanızdaki uzantı paketlerine başvurarak kullanılabilir.

local.settings.json

local.settings.json , işlev uygulamasını yerel olarak çalıştırırken kullanılan uygulama ayarlarını tanımlar. Gizli diziler içerebileceği için local.settings.json kaynak denetiminin dışında tutulmalıdır. Bunun yerine Azure'da uygulama ayarlarını kullanın.

Özel işleyiciler için local.settings.json dosyasında olarak ayarlayın FUNCTIONS_WORKER_RUNTIMECustom.

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "Custom"
  }
}

İşlev meta verileri

Özel işleyiciyle kullanıldığında function.json içeriği, başka bir bağlam altında işlev tanımlama yönteminizden farklı değildir. Tek gereksinim , function.json dosyalarının işlev adıyla eşleşmesi için adlı bir klasörde bulunması gerektiğidir.

Aşağıdaki function.json , kuyruk tetikleyicisi ve kuyruk çıkış bağlaması olan bir işlev yapılandırır. MyQueueFunction adlı bir klasörde olduğundan MyQueueFunction adlı bir işlev tanımlar.

MyQueueFunction/function.json

{
  "bindings": [
    {
      "name": "myQueueItem",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "messages-incoming",
      "connection": "AzureWebJobsStorage"
    },
    {
      "name": "$return",
      "type": "queue",
      "direction": "out",
      "queueName": "messages-outgoing",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

İstek yükü

Kuyruk iletisi alındığında İşlevler ana bilgisayarı, gövdesinde bir yük bulunan özel işleyiciye bir HTTP gönderi isteği gönderir.

Aşağıdaki kod örnek istek yükünü temsil eder. Yük, iki üyeye sahip bir JSON yapısı içerir: Data ve Metadata.

Üye, Datafunction.json dosyasındaki bağlamalar dizisinde tanımlandığı gibi giriş ve tetikleyici adlarıyla eşleşen anahtarlar içerir.

Üye, Metadataolay kaynağından oluşturulan meta verileri içerir.

{
  "Data": {
    "myQueueItem": "{ message: \"Message sent\" }"
  },
  "Metadata": {
    "DequeueCount": 1,
    "ExpirationTime": "2019-10-16T17:58:31+00:00",
    "Id": "800ae4b3-bdd2-4c08-badd-f08e5a34b865",
    "InsertionTime": "2019-10-09T17:58:31+00:00",
    "NextVisibleTime": "2019-10-09T18:08:32+00:00",
    "PopReceipt": "AgAAAAMAAAAAAAAAAgtnj8x+1QE=",
    "sys": {
      "MethodName": "QueueTrigger",
      "UtcNow": "2019-10-09T17:58:32.2205399Z",
      "RandGuid": "24ad4c06-24ad-4e5b-8294-3da9714877e9"
    }
  }
}

Yanıt yükü

Kural gereği, işlev yanıtları anahtar/değer çiftleri olarak biçimlendirilir. Desteklenen anahtarlar şunlardır:

Yük anahtarı Veri türü Açıklamalar
Outputs object function.json dosyasında dizi bindings tarafından tanımlanan yanıt değerlerini tutar.

Örneğin, bir işlev "myQueueOutput" adlı bir kuyruk çıkış bağlamasıyla yapılandırıldıysa, Outputs özel işleyici tarafından kuyruğa gönderilen iletilere ayarlanan adlı myQueueOutputbir anahtar içerir.
Logs array İletiler İşlev çağırma günlüklerinde görünür.

Azure'da çalışırken iletiler Application Insights'ta görünür.
ReturnValue string Bir çıkış function.json dosyasında olduğu gibi $return yapılandırıldığında yanıt sağlamak için kullanılır.

Bu bir yanıt yükü örneğidir.

{
  "Outputs": {
    "res": {
      "body": "Message enqueued"
    },
    "myQueueOutput": [
      "queue message 1",
      "queue message 2"
    ]
  },
  "Logs": [
    "Log message 1",
    "Log message 2"
  ],
  "ReturnValue": "{\"hello\":\"world\"}"
}

Örnekler

Özel işleyiciler, HTTP olaylarını almayı destekleyen herhangi bir dilde uygulanabilir. Aşağıdaki örneklerde, Go programlama dilini kullanarak özel işleyicinin nasıl uygulandığı gösterilmektedir.

Bağlamaları olan işlev

Bu örnekte uygulanan senaryo, bir ürün siparişini temsil eden bir yük ile kabul POST eden adlı order bir işlev içerir. İşleve bir sipariş gönderildiğinde bir Kuyruk Depolama iletisi oluşturulur ve bir HTTP yanıtı döndürülür.

Uygulama

order adlı bir klasörde function.json dosyası HTTP ile tetiklenen işlevi yapılandırıyor.

order/function.json

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "name": "message",
      "direction": "out",
      "queueName": "orders",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Bu işlev, HTTP yanıtı döndüren ve Kuyruk depolama iletisi veren HTTPile tetiklenen bir işlev olarak tanımlanır.

Uygulamanın kökünde, host.json dosyası (handler Linux veya macOS'ta) adlı handler.exe yürütülebilir bir dosyayı çalıştıracak şekilde yapılandırılır.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "handler.exe"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  }
}

Bu, İşlevler çalışma zamanına gönderilen HTTP isteğidir.

POST http://127.0.0.1:7071/api/order HTTP/1.1
Content-Type: application/json

{
  "id": 1005,
  "quantity": 2,
  "color": "black"
}

İşlevler çalışma zamanı daha sonra özel işleyiciye aşağıdaki HTTP isteğini gönderir:

POST http://127.0.0.1:<FUNCTIONS_CUSTOMHANDLER_PORT>/order HTTP/1.1
Content-Type: application/json

{
  "Data": {
    "req": {
      "Url": "http://localhost:7071/api/order",
      "Method": "POST",
      "Query": "{}",
      "Headers": {
        "Content-Type": [
          "application/json"
        ]
      },
      "Params": {},
      "Body": "{\"id\":1005,\"quantity\":2,\"color\":\"black\"}"
    }
  },
  "Metadata": {
  }
}

Not

Yükün bazı bölümleri kısa bir süre için kaldırıldı.

handler.exe , bir web sunucusu çalıştıran ve İşlevler konağından gelen işlev çağırma isteklerine yanıt veren derlenmiş Go özel işleyici programıdır.

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
)

type InvokeRequest struct {
	Data     map[string]json.RawMessage
	Metadata map[string]interface{}
}

type InvokeResponse struct {
	Outputs     map[string]interface{}
	Logs        []string
	ReturnValue interface{}
}

func orderHandler(w http.ResponseWriter, r *http.Request) {
	var invokeRequest InvokeRequest

	d := json.NewDecoder(r.Body)
	d.Decode(&invokeRequest)

	var reqData map[string]interface{}
	json.Unmarshal(invokeRequest.Data["req"], &reqData)

	outputs := make(map[string]interface{})
	outputs["message"] = reqData["Body"]

	resData := make(map[string]interface{})
	resData["body"] = "Order enqueued"
	outputs["res"] = resData
	invokeResponse := InvokeResponse{outputs, nil, nil}

	responseJson, _ := json.Marshal(invokeResponse)

	w.Header().Set("Content-Type", "application/json")
	w.Write(responseJson)
}

func main() {
	customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
	if !exists {
		customHandlerPort = "8080"
	}
	mux := http.NewServeMux()
	mux.HandleFunc("/order", orderHandler)
	fmt.Println("Go server Listening on: ", customHandlerPort)
	log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux))
}

Bu örnekte, özel işleyici HTTP olaylarını işlemek için bir web sunucusu çalıştırır ve aracılığıyla FUNCTIONS_CUSTOMHANDLER_PORTistekleri dinleyecek şekilde ayarlanır.

İşlevler konağı konumunda /api/orderözgün HTTP isteği almış olsa da, işlev adını (klasör adı) kullanarak özel işleyiciyi çağırır. Bu örnekte işlevi yolunda /ordertanımlanmıştır. Konak, özel işleyiciye yolunda /orderbir HTTP isteği gönderir.

İstekler bu işleve gönderildikçe POST tetikleyici verileri ve işlev meta verileri HTTP isteği gövdesi aracılığıyla kullanılabilir. Özgün HTTP isteği gövdesine yükün Data.req.Bodyiçinde erişilebilir.

İşlevin yanıtı, üyenin Outputs bir JSON değeri tuttuğu ve anahtarların function.json dosyasında tanımlandığı şekilde çıkışlarla eşleştiği anahtar/değer çiftleri halinde biçimlendirilir.

Bu, bu işleyicinin İşlevler konağına döndürdüğü örnek bir yükdür.

{
  "Outputs": {
    "message": "{\"id\":1005,\"quantity\":2,\"color\":\"black\"}",
    "res": {
      "body": "Order enqueued"
    }
  },
  "Logs": null,
  "ReturnValue": null
}

Çıkış, message istekten gelen sipariş verilerine eşit olarak ayarlanarak, işlev verileri yapılandırılan kuyruğa sıralayan çıkışlar oluşturur. İşlevler konağı, içinde yapılandırılan res HTTP yanıtını da çağırana döndürür.

Yalnızca HTTP işlevi

Ek bağlamaları veya çıkışları olmayan HTTP ile tetiklenen işlevler için, işleyicinizin özel işleyici isteği ve yanıt yükleri yerine doğrudan HTTP isteği ve yanıtıyla çalışmasını isteyebilirsiniz. Bu davranış, ayarı kullanılarak enableForwardingHttpRequesthost.json dosyasında yapılandırılabilir.

Önemli

Özel işleyiciler özelliğinin birincil amacı, şu anda Azure İşlevleri birinci sınıf desteği olmayan dilleri ve çalışma zamanlarını etkinleştirmektir. Web uygulamalarını özel işleyiciler kullanarak çalıştırmak mümkün olsa da, Azure İşlevleri standart bir ters proxy değildir. Yanıt akışı, HTTP/2 ve WebSockets gibi bazı özellikler kullanılamaz. BELIRLI üst bilgiler ve yollar gibi HTTP isteğinin bazı bileşenleri kısıtlanabilir. Uygulamanız aşırı soğuk başlatmayla da karşılaşabilir.

Bu durumlara çözüm getirmek için web uygulamalarınızı Azure App Service üzerinde çalıştırmayı göz önünde bulundurun.

Aşağıdaki örnekte, ek bağlamalar veya çıkışlar olmadan HTTP ile tetiklenen bir işlevin nasıl yapılandırıldığı gösterilmektedir. Bu örnekte uygulanan senaryo, veya POST kabul eden adlı hello bir GET işlev içerir.

Uygulama

hello adlı klasörde function.json dosyası HTTP ile tetiklenen işlevi yapılandırıyor.

hello/function.json

{
  "bindings": [
    {
      "type": "httpTrigger",
      "authLevel": "anonymous",
      "direction": "in",
      "name": "req",
      "methods": ["get", "post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

işlevi hem hem de GETPOST isteklerini kabul etmek üzere yapılandırılır ve sonuç değeri adlı resbir bağımsız değişken aracılığıyla sağlanır.

Uygulamanın kökünde host.json dosyası çalıştırılacak handler.exe şekilde yapılandırılır ve enableForwardingHttpRequest olarak trueayarlanır.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "handler.exe"
    },
    "enableForwardingHttpRequest": true
  }
}

olduğunda enableForwardingHttpRequesttrue, yalnızca HTTP işlevlerinin davranışı şu yollarla varsayılan özel işleyici davranışından farklıdır:

  • HTTP isteği, özel işleyiciler istek yükünü içermez. Bunun yerine İşlevler ana bilgisayarı, özgün HTTP isteğinin bir kopyasıyla işleyiciyi çağırır.
  • İşlevler ana bilgisayarı, herhangi bir sorgu dizesi parametresi de dahil olmak üzere özgün istekle aynı yola sahip işleyiciyi çağırır.
  • İşlevler konağı, özgün isteğe yanıt olarak işleyicinin HTTP yanıtının bir kopyasını döndürür.

aşağıda İşlevler konağına gönderilen bir POST isteği yer alır. İşlevler konağı daha sonra isteğin bir kopyasını aynı yoldaki özel işleyiciye gönderir.

POST http://127.0.0.1:7071/api/hello HTTP/1.1
Content-Type: application/json

{
  "message": "Hello World!"
}

handler.go dosyası bir web sunucusu ve HTTP işlevi uygular.

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	if r.Method == "GET" {
		w.Write([]byte("hello world"))
	} else {
		body, _ := ioutil.ReadAll(r.Body)
		w.Write(body)
	}
}

func main() {
	customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
	if !exists {
		customHandlerPort = "8080"
	}
	mux := http.NewServeMux()
	mux.HandleFunc("/api/hello", helloHandler)
	fmt.Println("Go server Listening on: ", customHandlerPort)
	log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux))
}

Bu örnekte, özel işleyici HTTP olaylarını işlemek için bir web sunucusu oluşturur ve aracılığıyla FUNCTIONS_CUSTOMHANDLER_PORTistekleri dinleyecek şekilde ayarlanır.

GET istekler bir dize döndürülerek işlenir ve POST isteklerin istek gövdesine erişimi olur.

Buradaki order işlevinin yolu, /api/helloözgün istekle aynıdır.

Not

FUNCTIONS_CUSTOMHANDLER_PORT işlevi çağırmak için kullanılan genel kullanıma yönelik bağlantı noktası değildir. Bu bağlantı noktası, özel işleyiciyi çağırmak için İşlevler konağı tarafından kullanılır.

Dağıtma

Her Azure İşlevleri barındırma seçeneğine özel bir işleyici dağıtılabilir. İşleyiciniz işletim sistemi veya platform bağımlılıkları (dil çalışma zamanı gibi) gerektiriyorsa , özel bir kapsayıcı kullanmanız gerekebilir.

Azure'da özel işleyiciler için bir işlev uygulaması oluştururken yığın olarak .NET Core'u seçmenizi öneririz.

Azure İşlevleri Core Tools kullanarak özel işleyici uygulaması dağıtmak için aşağıdaki komutu çalıştırın.

func azure functionapp publish $functionAppName

Not

Özel işleyicinizi çalıştırmak için gereken tüm dosyaların klasöründe olduğundan ve dağıtıma dahil olduğundan emin olun. Özel işleyiciniz ikili yürütülebilir dosyaysa veya platforma özgü bağımlılıklara sahipse, bu dosyaların hedef dağıtım platformuyla eşleştiğinden emin olun.

Kısıtlamalar

  • Özel işleyici web sunucusunun 60 saniye içinde başlatılması gerekir.

Örnekler

İşlevleri çeşitli dillerde uygulama örnekleri için GitHub deposundaki özel işleyici örneklerine bakın.

Sorun giderme ve destek

İzleme günlüğü

Özel işleyici işleminiz başlatılamıyorsa veya İşlevler konağıyla iletişimde sorun yaşıyorsa, konaktan daha fazla tanılama iletisi görmek için Trace işlev uygulamasının günlük düzeyini artırabilirsiniz.

İşlev uygulamasının varsayılan günlük düzeyini değiştirmek için host.json dosyasının logging bölümündeki ayarı yapılandırınlogLevel.

{
  "version": "2.0",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "handler.exe"
    }
  },
  "logging": {
    "logLevel": {
      "default": "Trace"
    }
  }
}

İşlevler ana bilgisayarı, özel işleyici işlemiyle ilgili bilgiler de dahil olmak üzere ek günlük iletileri çıkışı sağlar. Özel işleyici işleminizi başlatma veya özel işleyicinizdeki işlevleri çağırma sorunlarını araştırmak için günlükleri kullanın.

Günlükler yerel olarak konsola yazdırılır.

Azure'da, günlük iletilerini görüntülemek için Application Insights izlemelerini sorgulayın . Uygulamanız yüksek hacimli günlükler üretirse, Application Insights'a günlük iletilerinin yalnızca bir alt kümesi gönderilir. Tüm iletilerin günlüğe kaydedildiğinden emin olmak için örneklemeyi devre dışı bırakın.

Özel işleyiciyi yalıtımlı olarak test edin

Özel işleyici uygulamaları bir web sunucusu işlemidir, bu nedenle cURL veya Postman gibi bir araç kullanarak sahte HTTP istekleri göndererek kendi başına başlatmanız ve işlev çağrılarını test etmek yararlı olabilir.

Özel işleyicinizde otomatikleştirilmiş testler çalıştırmak için CI/CD işlem hatlarınızda da bu stratejiyi kullanabilirsiniz.

Yürütme ortamı

Özel işleyiciler, tipik bir Azure İşlevleri uygulamasıyla aynı ortamda çalışır. Ortamın çalışması için gereken tüm bağımlılıkları içerdiğinden emin olmak için işleyicinizi test edin. Ek bağımlılıklar gerektiren uygulamalar için, bunları Azure İşlevleri Premium planında barındırılan özel bir kapsayıcı görüntüsü kullanarak çalıştırmanız gerekebilir.

Destek alın

Özel işleyicileri olan bir işlev uygulamasında yardıma ihtiyacınız varsa, normal destek kanalları aracılığıyla istek gönderebilirsiniz. Ancak, özel işleyici uygulamaları oluşturmak için kullanılan çok çeşitli olası diller nedeniyle destek sınırsız değildir.

İşlevler konağı özel işleyici işlemini başlatırken veya bunlarla iletişim kurarken sorun yaşıyorsa destek sağlanır. Seçilen dil veya çerçeveyle ilgili sorunlar gibi özel işleyici sürecinizin iç çalışmalarına özgü sorunlar için Destek Ekibimiz bu bağlamda yardım sağlayamıyor.

Sonraki adımlar

Özel işleyiciler hızlı başlangıcıyla Go veya Rust'ta bir Azure İşlevleri uygulaması oluşturmaya başlayın.