Linux üzerinde özel kapsayıcı kullanarak bir işlev oluşturma

Bu öğreticide, bir Linux temel görüntüsü kullanarak kodunuzu özel bir Docker kapsayıcısı olarak Azure İşlevleri oluşturup dağıtacaksınız. İşlevleriniz belirli bir dil sürümü gerektirdiğinde veya yerleşik görüntü tarafından sağlanmayan belirli bir bağımlılık veya yapılandırmaya sahip olduğunda genellikle özel bir görüntü kullanırsınız.

Azure İşlevleri özel işleyiciler kullanarak herhangi bir dili veya çalışma zamanını destekler. Bu öğreticide kullanılan R programlama dili gibi bazı diller için çalışma zamanını veya daha fazla kitaplığı özel bir kapsayıcının kullanılmasını gerektiren bağımlılıklar olarak yüklemeniz gerekir.

İşlev kodunuzu özel bir Linux kapsayıcısında dağıtmak için Premium plan veya Ayrılmış (App Service) plan barındırma gerekir. Bu öğreticinin tamamlanması, Azure hesabınızda birkaç ABD dolarının maliyetini karşılar ve işiniz bittiğinde kaynakları temizleyerek en aza indirebilirsiniz.

Ayrıca, Linux'ta barındırılan ilk işlevinizi oluşturma bölümünde açıklandığı gibi varsayılan bir Azure App Service kapsayıcısı da kullanabilirsiniz. Azure İşlevleri için desteklenen temel görüntüler Azure İşlevleri temel görüntüler deposunda bulunur.

Bu öğreticide şunların nasıl yapıldığını öğreneceksiniz:

  • Azure İşlevleri Core Tools kullanarak bir işlev uygulaması ve Dockerfile oluşturun.
  • Docker kullanarak özel bir görüntü oluşturun.
  • Özel görüntüyü bir kapsayıcı kayıt defterinde yayımlayın.
  • İşlev uygulaması için Azure'da destekleyici kaynaklar oluşturun.
  • Docker Hub’dan bir işlev uygulaması dağıtın.
  • Uygulama ayarlarını işlevi uygulamasına ekleyin.
  • Sürekli dağıtımı etkinleştirin.
  • Kapsayıcıya SSH bağlantılarını etkinleştirin.
  • Kuyruk depolama çıkış bağlaması ekleyin.
  • Azure İşlevleri Core Tools kullanarak bir işlev uygulaması ve Dockerfile oluşturun.
  • Docker kullanarak özel bir görüntü oluşturun.
  • Özel görüntüyü bir kapsayıcı kayıt defterinde yayımlayın.
  • İşlev uygulaması için Azure'da destekleyici kaynaklar oluşturun.
  • Docker Hub’dan bir işlev uygulaması dağıtın.
  • Uygulama ayarlarını işlevi uygulamasına ekleyin.
  • Sürekli dağıtımı etkinleştirin.
  • Kapsayıcıya SSH bağlantılarını etkinleştirin.

Bu öğreticiyi Windows, macOS veya Linux çalıştıran herhangi bir bilgisayarda izleyebilirsiniz.

Yerel ortamınızı yapılandırma

Başlamadan önce aşağıdaki gereksinimlerin karşılanması gerekir:

  • Node.js, Etkin LTS ve Bakım LTS sürümleri (8.11.1 ve 10.14.1 önerilir).
  • Kullandığınız dile yönelik geliştirme araçları. Bu öğreticide örnek olarak R programlama dili kullanılır.

Azure aboneliğiniz yoksa başlamadan önce ücretsiz bir Azure hesabı oluşturun.

Ayrıca bir Docker ve Docker kimliği de almanız gerekir:

Sanal ortam oluşturma ve etkinleştirme

Uygun bir klasörde aşağıdaki komutları çalıştırarak adlı .venvbir sanal ortam oluşturun ve etkinleştirin. Azure İşlevleri tarafından desteklenen Python 3.8, 3.7 veya 3.6 kullandığınızdan emin olun.

python -m venv .venv
source .venv/bin/activate

Python Venv paketini Linux dağıtımınıza yüklemediyse aşağıdaki komutu çalıştırın:

sudo apt-get install python3-venv

Bu etkinleştirilmiş sanal ortamda sonraki tüm komutları çalıştırırsınız.

Yerel işlevler projesini oluşturma ve test etme

Bir terminalde veya komut isteminde, geçerli klasörde bir işlev uygulaması projesi oluşturmak üzere seçtiğiniz dil için aşağıdaki komutu çalıştırın:

func init --worker-runtime dotnet --docker
func init --worker-runtime node --language javascript --docker
func init --worker-runtime powershell --docker
func init --worker-runtime python --docker
func init --worker-runtime node --language typescript --docker

Boş bir klasörde aşağıdaki komutu çalıştırarak bir Maven arketipinden İşlevler projesini oluşturun:

mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8 -Ddocker

parametresi İşlevler -DjavaVersion çalışma zamanına Hangi Java sürümünün kullanılacağını söyler. İşlevlerinizin Java 11 üzerinde çalışmasını istiyorsanız -DjavaVersion=11 ifadesini kullanın. belirtmediğinizde Maven varsayılan olarak Java 8'i kullanır -DjavaVersion. Daha fazla bilgi için bkz. Java sürümleri.

Önemli

Bu JAVA_HOME makaleyi tamamlamak için ortam değişkeni JDK'nin doğru sürümünün yükleme konumuna ayarlanmalıdır.

Maven, dağıtımda projeyi oluşturma işlemini tamamlamak için gereken değerleri ister. İstemleri izleyin ve aşağıdaki bilgileri sağlayın:

İstem Değer Açıklama
groupId com.fabrikam Java için paket adlandırma kurallarına uyarak projenizi tüm projelerde benzersiz olarak tanımlayan bir değer.
Artifactıd fabrikam-functions Sürüm numarası olmadan jar adı olan bir değer.
Sürüm 1.0-SNAPSHOT Varsayılan değeri seçin.
Paket com.fabrikam.functions Oluşturulan işlev kodu için Java paketi olan bir değer. Varsayılan değeri kullanın.

Onaylamak için Enter tuşuna basın Y .

Maven, proje dosyalarını artifactId adlı yeni bir klasörde oluşturur. Bu örnekte şöyledir fabrikam-functions: .

func init --worker-runtime custom --docker

seçeneği--docker, proje için Azure İşlevleri ve seçilen çalışma zamanıyla kullanmak için uygun bir özel kapsayıcı tanımlayan bir Dockerfile oluşturur.

Proje klasörüne gidin:

cd fabrikam-functions

Dockerfile'da değişiklik yapılması gerekmez.

Aşağıdaki komutu kullanarak projenize işlev ekleyin. Burada --name bağımsız değişken işlevinizin benzersiz adıdır ve --template bağımsız değişken işlevin tetikleyicisini belirtir. func new projenizde bir C# kod dosyası oluşturur.

func new --name HttpExample --template "HTTP trigger" --authlevel anonymous

Aşağıdaki komutu kullanarak projenize işlev ekleyin. Burada --name bağımsız değişken işlevinizin benzersiz adıdır ve --template bağımsız değişken işlevin tetikleyicisini belirtir. func newfunction.json adlı bir yapılandırma dosyası içeren işlev adıyla eşleşen bir alt klasör oluşturur.

func new --name HttpExample --template "HTTP trigger" --authlevel anonymous

Metin düzenleyicisinde, proje klasöründe işleyici adlı bir dosya oluşturun . R. İçeriği olarak aşağıdaki kodu ekleyin:

library(httpuv)

PORTEnv <- Sys.getenv("FUNCTIONS_CUSTOMHANDLER_PORT")
PORT <- strtoi(PORTEnv , base = 0L)

http_not_found <- list(
  status=404,
  body='404 Not Found'
)

http_method_not_allowed <- list(
  status=405,
  body='405 Method Not Allowed'
)

hello_handler <- list(
  GET = function (request) {
    list(body=paste(
      "Hello,",
      if(substr(request$QUERY_STRING,1,6)=="?name=") 
        substr(request$QUERY_STRING,7,40) else "World",
      sep=" "))
  }
)

routes <- list(
  '/api/HttpExample' = hello_handler
)

router <- function (routes, request) {
  if (!request$PATH_INFO %in% names(routes)) {
    return(http_not_found)
  }
  path_handler <- routes[[request$PATH_INFO]]

  if (!request$REQUEST_METHOD %in% names(path_handler)) {
    return(http_method_not_allowed)
  }
  method_handler <- path_handler[[request$REQUEST_METHOD]]

  return(method_handler(request))
}

app <- list(
  call = function (request) {
    response <- router(routes, request)
    if (!'status' %in% names(response)) {
      response$status <- 200
    }
    if (!'headers' %in% names(response)) {
      response$headers <- list()
    }
    if (!'Content-Type' %in% names(response$headers)) {
      response$headers[['Content-Type']] <- 'text/plain'
    }

    return(response)
  }
)

cat(paste0("Server listening on :", PORT, "...\n"))
runServer("0.0.0.0", PORT, app)

host.json dosyasında, özel işleyicinin customHandler başlangıç komutunu yapılandırmak için bölümünü değiştirin.

"customHandler": {
  "description": {
      "defaultExecutablePath": "Rscript",
      "arguments": [
      "handler.R"
    ]
  },
  "enableForwardingHttpRequest": true
}

İşlevi yerel olarak test etmek için proje klasörünün kökünde yerel Azure İşlevleri çalışma zamanı ana bilgisayarını başlatın.

func start  
func start  
npm install
npm start
mvn clean package  
mvn azure-functions:run
R -e "install.packages('httpuv', repos='http://cran.rstudio.com/')"
func start

Çıkışta uç noktanın HttpExample gösterildiğini gördükkten sonra adresine http://localhost:7071/api/HttpExample?name=Functionsgidin. Tarayıcının, sorgu parametresine sağlanan değeri geri Functionsyankılayan bir "hello" iletisi görüntülemesi name gerekir.

Konağı durdurmak için Ctrl+C tuşuna basın.

Kapsayıcı görüntüsünü oluşturma ve yerel olarak test etme

(İsteğe bağlı) Proje klasörünün kökündeki Dockerfile dosyasını inceleyin. Dockerfile, linux üzerinde işlev uygulamasını çalıştırmak için gereken ortamı açıklar. Azure İşlevleri için desteklenen temel görüntülerin tam listesi Azure İşlevleri temel görüntü sayfasında bulunabilir.

Proje klasörünün kökündeki Dockerfile dosyasını inceleyin. Dockerfile, linux üzerinde işlev uygulamasını çalıştırmak için gereken ortamı açıklar. Özel işleyici uygulamaları, temel olarak görüntüyü kullanır mcr.microsoft.com/azure-functions/dotnet:3.0-appservice .

R'yi yüklemek için Dockerfile dosyasını değiştirin. Dockerfile'ın içeriğini aşağıdaki kodla değiştirin:

FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice 
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

RUN apt update && \
    apt install -y r-base && \
    R -e "install.packages('httpuv', repos='http://cran.rstudio.com/')"

COPY . /home/site/wwwroot

Kök proje klasöründe docker build komutunu çalıştırın, olarak azurefunctionsimagebir ad sağlayın ve olarak v1.0.0etiketleyin. <DOCKER_ID> değerini Docker Hub hesabınızın kimliğiyle değiştirin. Bu komut, kapsayıcı için Docker görüntüsünü derler.

docker build --tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 .

Komut tamamlandığında yeni kapsayıcıyı yerel olarak çalıştırabilirsiniz.

Derlemeyi test etmek için docker run komutunu kullanarak görüntüyü yerel bir kapsayıcıda çalıştırın, değerini yeniden Docker Hub hesap kimliğinizle değiştirin <docker_id> ve bağlantı noktaları bağımsız değişkenini olarak -p 8080:80ekleyin:

docker run -p 8080:80 -it <docker_id>/azurefunctionsimage:v1.0.0

Görüntü yerel kapsayıcıda başladıktan sonra, öncekiyle aynı "merhaba" iletisini görüntülemesi gereken öğesine göz atın http://localhost:8080/api/HttpExample?name=Functions. Oluşturduğunuz HTTP ile tetiklenen işlev anonim yetkilendirme kullandığından, erişim anahtarı almak zorunda kalmadan kapsayıcıda çalışan işlevi çağırabilirsiniz. Daha fazla bilgi için bkz. yetkilendirme anahtarları.

Görüntü yerel kapsayıcıda başladıktan sonra, öncekiyle aynı "merhaba" iletisini görüntülemesi gereken öğesine göz atın http://localhost:8080/api/HttpExample?name=Functions. Oluşturduğunuz HTTP ile tetiklenen işlev anonim yetkilendirme kullandığından, erişim anahtarı almak zorunda kalmadan kapsayıcıda çalışan işlevi çağırabilirsiniz. Daha fazla bilgi için bkz. yetkilendirme anahtarları.

Kapsayıcıdaki işlev uygulamasını doğruladıktan sonra docker'ı durdurmak için Ctrl+C tuşuna basın.

Görüntüyü Docker Hub gönderme

Docker Hub, görüntüleri barındıran ve görüntü ile kapsayıcı hizmetleri sağlayan bir kapsayıcı kayıt defteridir. Azure'a dağıtmayı da içeren görüntünüzü paylaşmak için bir kayıt defterine göndermeniz gerekir.

  1. Docker'da henüz oturum açmadıysanız docker oturum açma komutuyla değerini Docker Hub hesap kimliğinizle değiştirerek <docker_id> yapın. Bu komut sizden kullanıcı adınızı ve parolanızı ister. "Oturum Açma Başarılı" iletisi oturum açtığınızı onaylar.

    docker login
    
  2. Oturum açtıktan sonra docker push komutunu kullanarak görüntüyü Docker Hub gönderin, yerine Docker Hub hesap kimliğinizi yazın<docker_id>.

    docker push <docker_id>/azurefunctionsimage:v1.0.0
    
  3. Ağ hızınıza bağlı olarak, görüntüyü ilk kez göndermek birkaç dakika sürebilir (sonraki değişiklikleri göndermek çok daha hızlıdır). Beklerken sonraki bölüme ilerleyebilir ve başka bir terminalde Azure kaynakları oluşturabilirsiniz.

İşleviniz için destekleyici Azure kaynakları oluşturma

İşlev kodunuzu Azure'a dağıtabilmeniz için önce üç kaynak oluşturmanız gerekir:

  • İlgili kaynaklar için mantıksal bir kapsayıcı olan kaynak grubu.
  • İşlevleriniz hakkındaki durumu ve diğer bilgileri korumak için kullanılan bir Depolama hesabı.
  • İşlev kodunuzu yürütmek için ortamı sağlayan bir işlev uygulaması. İşlev uygulaması yerel işlev projenize eşler ve kaynakların daha kolay yönetilmesi, dağıtılması ve paylaşılması için işlevleri mantıksal birim olarak gruplandırmanıza olanak tanır.

Bu öğeleri oluşturmak için aşağıdaki komutları kullanın. Hem Azure CLI hem de PowerShell desteklenir.

  1. Henüz yapmadıysanız Azure'da oturum açın.

    az login
    

    az login komutu, Azure hesabınızda oturum açar.

  2. Seçtiğiniz bölgede adlı AzureFunctionsContainers-rg bir kaynak grubu oluşturun.

    az group create --name AzureFunctionsContainers-rg --location <REGION>
    

    az group create komutu bir kaynak grubu oluşturur. Yukarıdaki komutta değerini, az account list-locations komutundan döndürülen kullanılabilir bir bölge kodunu kullanarak yakınınızdaki bir bölgeyle değiştirin<REGION>.

  3. Kaynak grubunuzda ve bölgenizde genel amaçlı bir depolama hesabı oluşturun.

    az storage account create --name <STORAGE_NAME> --location <REGION> --resource-group AzureFunctionsContainers-rg --sku Standard_LRS
    

    az storage account create komutu, depolama hesabını oluşturur.

    Önceki örnekte değerini size uygun ve Azure Depolama benzersiz bir adla değiştirin<STORAGE_NAME>. Depolama adları yalnızca 3 ile 24 karakter arasında sayı ve küçük harf içermelidir. Standard_LRSİşlevler tarafından desteklenen genel amaçlı bir hesap belirtir.

  4. Elastik Premium 1 fiyatlandırma katmanında () adlı Azure İşlevleri, içinde ve <REGION>bir Linux kapsayıcısında ()--sku EP1--is-linux adlı myPremiumPlanbir Premium planı oluşturmak için komutunu kullanın.

    az functionapp plan create --resource-group AzureFunctionsContainers-rg --name myPremiumPlan --location <REGION> --number-of-workers 1 --sku EP1 --is-linux
    

    Gerektiğinde ölçeklendirilebilen Premium planını burada kullanırız. Barındırma hakkında daha fazla bilgi için bkz. Azure İşlevleri barındırma planları karşılaştırması. Maliyetleri hesaplama hakkında daha fazla bilgi için İşlevler fiyatlandırma sayfasına bakın.

    Komut ayrıca aynı kaynak grubunda ilişkili bir Azure Uygulaması Analizler örneği sağlar. Bu örnekle işlev uygulamanızı izleyebilir ve günlükleri görüntüleyebilirsiniz. Daha fazla bilgi için bkz. İzleme Azure İşlevleri. Örnek, siz etkinleştirene kadar ücret ödemez.

Görüntüyle Azure'da işlev uygulaması oluşturma ve yapılandırma

Barındırma planınızda işlevlerinizin yürütülmesini Azure'daki bir işlev uygulaması yönetir. Bu bölümde, önceki bölümde yer alan Azure kaynaklarını kullanarak Docker Hub bir görüntüden işlev uygulaması oluşturacak ve bunu Azure Depolama bağlantı dizesiyle yapılandıracaksınız.

  1. Aşağıdaki komutu kullanarak bir işlev uygulaması oluşturun:

    az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --resource-group AzureFunctionsContainers-rg --plan myPremiumPlan --deployment-container-image-name <DOCKER_ID>/azurefunctionsimage:v1.0.0
    

    az functionapp create komutunda deployment-container-image-name parametresi, işlev uygulaması için kullanılacak görüntüyü belirtir. Dağıtım için kullanılan görüntü hakkındaki bilgileri görüntülemek için az functionapp config container show komutunu kullanabilirsiniz. Farklı bir görüntüden dağıtmak için az functionapp config container set komutunu da kullanabilirsiniz.

    Not

    Özel bir kapsayıcı kayıt defteri kullanıyorsanız deployment-container-image-name parametresi kayıt defteri URL'sine başvurur.

    Bu örnekte değerini depolama hesabı için önceki bölümde kullandığınız adla değiştirin <STORAGE_NAME> . Ayrıca değerini size uygun genel olarak benzersiz bir adla ve <DOCKER_ID> Docker Hub hesap kimliğinizle değiştirin<APP_NAME>. Özel bir kapsayıcı kayıt defterinden dağıtım yaparken, kayıt defterinin deployment-container-image-name URL'sini belirtmek için parametresini kullanın.

    İpucu

    ANSI denetim karakterlerinin DisableColor kapsayıcı günlüklerine yazılmasını önlemek için host.json dosyasındaki ayarı kullanabilirsiniz.

  2. Oluşturduğunuz depolama hesabının bağlantı dizesini almak için aşağıdaki komutu kullanın:

    az storage account show-connection-string --resource-group AzureFunctionsContainers-rg --name <STORAGE_NAME> --query connectionString --output tsv
    

    Depolama hesabının bağlantı dizesi az storage account show-connection-string komutu kullanılarak döndürülür.

    değerini daha önce oluşturduğunuz depolama hesabının adıyla değiştirin <STORAGE_NAME> .

  3. İşlev uygulamasına ayarı eklemek için aşağıdaki komutu kullanın:

    az functionapp config appsettings set --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage=<CONNECTION_STRING>
    

    az functionapp config appsettings set komutu ayarı oluşturur.

    Bu komutta değerini işlev uygulamanızın adıyla ve <CONNECTION_STRING> önceki adımdaki bağlantı dizesiyle değiştirin<APP_NAME>. Bağlantı ile DefaultEndpointProtocol=başlayan uzun kodlanmış bir dize olmalıdır.

  4. İşlev artık depolama hesabına erişmek için bu bağlantı dizesini kullanabilir.

Not

Özel görüntünüzü özel bir kapsayıcı kayıt defterinde yayımlarsanız, bunun yerine bağlantı dizesi için Dockerfile içindeki ortam değişkenlerini kullanmanız gerekir. Daha fazla bilgi için bkz . ENV yönergesi. ve DOCKER_REGISTRY_SERVER_PASSWORD değişkenlerini de ayarlamanız DOCKER_REGISTRY_SERVER_USERNAME gerekir. Değerleri kullanmak için görüntüyü yeniden oluşturmanız, görüntüyü kayıt defterine göndermeniz ve ardından işlev uygulamasını Azure'da yeniden başlatmanız gerekir.

Azure'da işlevlerinizi doğrulama

Görüntü Azure'daki işlev uygulamanıza dağıtıldığında artık HTTP istekleri aracılığıyla işlevi daha önce olduğu gibi çağırabilirsiniz. Tarayıcınızda aşağıdaki URL'ye gidin:

https://<APP_NAME>.azurewebsites.net/api/HttpExample?name=Functions

https://<APP_NAME>.azurewebsites.net/api/HttpExample?name=Functions

değerini işlev uygulamanızın adıyla değiştirin <APP_NAME> . Bu URL'ye gittiğinizde, tarayıcının işlevi yerel olarak çalıştırdığınızdakine benzer bir çıkış görüntülemesi gerekir.

Azure'a sürekli dağıtımı etkinleştirme

Kayıt defterinde görüntüyü her güncelleştirdiğinizde Azure İşlevleri'nin görüntü dağıtımınızı otomatik olarak güncelleştirmesini sağlayabilirsiniz.

  1. Sürekli dağıtımı etkinleştirmek ve web kancası URL'sini almak için aşağıdaki komutu kullanın:

    az functionapp deployment container config --enable-cd --query CI_CD_URL --output tsv --name <APP_NAME> --resource-group AzureFunctionsContainers-rg
    

    az functionapp deployment container config komutu sürekli dağıtımı etkinleştirir ve dağıtım web kancası URL'sini döndürür. Bu URL'yi daha sonra az functionapp deployment container show-cd-url komutunu kullanarak alabilirsiniz.

    Daha önce olduğu gibi işlevini işlev uygulama adınızla değiştirin <APP_NAME> .

  2. Dağıtım web kancası URL'sini panoya kopyalayın.

  3. Docker Hub açın, oturum açın ve gezinti çubuğunda Depolar'ı seçin. Resmi bulup seçin, Web Kancaları sekmesini seçin, bir Web kancası adı belirtin, URL'nizi Web Kancası URL'sine yapıştırın ve oluştur'u seçin.

    Screenshot showing how to add the webhook in your Docker Hub window.

  4. Web kancası ayarlandığında, Azure İşlevleri görüntünüzü Docker Hub her güncelleştirdiğinizde yeniden dağıtın.

SSH bağlantılarını etkinleştirme

SSH, kapsayıcı ile istemci arasında güvenli iletişime olanak tanır. SSH etkinleştirildiğinde, App Service Gelişmiş Araçlar'ı (Kudu) kullanarak kapsayıcınıza bağlanabilirsiniz. SSH kullanarak kapsayıcınıza kolay bağlantı sağlamak için Azure İşlevleri, SSH'nin zaten etkin olduğu bir temel görüntü sağlar. Yalnızca Dockerfile dosyanızı düzenlemeniz, ardından görüntüyü yeniden oluşturmanız ve yeniden dağıtmanız gerekir. Ardından Gelişmiş Araçlar (Kudu) aracılığıyla kapsayıcıya bağlanabilirsiniz.

  1. Dockerfile dosyanızda dizeyi -appservice yönergenizdeki FROM temel görüntüye ekleyin.

    FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/node:2.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/powershell:2.0-appservice
    
    FROM mcr.microsoft.com/azure-functions/python:2.0-python3.7-appservice
    
    FROM mcr.microsoft.com/azure-functions/node:2.0-appservice
    
  2. komutunu kullanarak docker build görüntüyü yeniden derleyin, öğesini Docker Hub hesap kimliğiniz ile değiştirin<docker_id>.

    docker build --tag <docker_id>/azurefunctionsimage:v1.0.0 .
    
  3. Güncelleştirilmiş görüntüyü Docker Hub göndererek ilk gönderimden çok daha az zaman alacaktır. Görüntünün yalnızca güncelleştirilmiş parçalarının şimdi karşıya yüklenmesi gerekir.

    docker push <docker_id>/azurefunctionsimage:v1.0.0
    
  4. Azure İşlevleri görüntüyü otomatik olarak işlev uygulamanıza yeniden dağıtır; işlem bir dakikadan kısa bir sürede gerçekleşir.

  5. Tarayıcıda açın https://<app_name>.scm.azurewebsites.net/ ve değerini benzersiz adınızla değiştirin <app_name> . Bu URL, işlev uygulaması kapsayıcınız için Gelişmiş Araçlar (Kudu) uç noktasıdır.

  6. Azure hesabınızda oturum açın ve kapsayıcıyla bağlantı kurmak için SSH'yi seçin. Azure kapsayıcı görüntüsünü güncelleştirmeye devam ediyorsa bağlanma işlemi birkaç dakika sürebilir.

  7. Kapsayıcınızla bağlantı kurulduktan sonra komutunu çalıştırarak top çalışmakta olan işlemleri görüntüleyin.

    Screenshot that shows Linux top command running in an SSH session.

Azure Kuyruk Depolama yazma

Azure İşlevleri, kendi tümleştirme kodunuzu yazmak zorunda kalmadan işlevlerinizi diğer Azure hizmetlerine ve kaynaklarına bağlamanıza olanak tanır. Hem girişi hem de çıkışı temsil eden bu bağlamalar işlev tanımı içinde bildirilir. Bağlamalardan alınan veriler işleve parametre olarak sağlanır. Tetikleyici, özel bir giriş bağlama türüdür. Bir işlevin yalnızca bir tetikleyicisi olsa da, birden çok giriş ve çıkış bağlaması olabilir. Daha fazla bilgi için bkz. tetikleyiciler ve bağlamalar kavramları Azure İşlevleri.

Bu bölümde işlevinizi Azure Kuyruk Depolama ile tümleştirme adımları gösterilmektedir. Bu işleve eklediğiniz çıkış bağlaması, bir HTTP isteğinden kuyruktaki bir iletiye veri yazar.

Azure Depolama bağlantı dizesini alma

Daha önce işlev uygulamasının kullanımı için bir Azure Depolama hesabı oluşturdunuz. Bu hesabın bağlantı dizesi Azure'daki uygulama ayarlarında güvenli bir şekilde depolanır. Ayarı local.settings.json dosyasına indirerek, işlevi yerel olarak çalıştırırken aynı hesaptaki bir Depolama kuyruğuna yazmak için bağlantıyı kullanabilirsiniz.

  1. Projenin kökünden aşağıdaki komutu çalıştırın ve değerini önceki adımdaki işlev uygulamanızın adıyla değiştirin <APP_NAME> . Bu komut, dosyadaki mevcut değerlerin üzerine yazar.

    func azure functionapp fetch-app-settings <APP_NAME>
    
  2. local.settings.json dosyasını açın ve Depolama hesabı bağlantı dizesi olan adlı AzureWebJobsStoragedeğeri bulun. Bu makalenin diğer bölümlerinde adı AzureWebJobsStorage ve bağlantı dizesini kullanırsınız.

Önemli

local.settings.json dosyası Azure'dan indirilen gizli dizileri içerdiğinden, bu dosyayı her zaman kaynak denetiminden hariç tutun. Yerel işlevler projesiyle oluşturulan .gitignore dosyası varsayılan olarak dosyayı dışlar.

Bağlama uzantılarını kaydetme

HTTP ve zamanlayıcı tetikleyicileri dışında bağlamalar uzantı paketleri olarak uygulanır. Projenize Depolama uzantı paketini eklemek için Terminal penceresinde aşağıdaki dotnet add package komutunu çalıştırın.

dotnet add package Microsoft.Azure.WebJobs.Extensions.Storage 

Artık projenize depolama çıkış bağlaması ekleyebilirsiniz.

İşleve çıkış bağlama tanımı ekleme

Bir işlevin yalnızca bir tetikleyicisi olsa da, özel tümleştirme kodu yazmadan diğer Azure hizmetlerine ve kaynaklarına bağlanmanızı sağlayan birden çok giriş ve çıkış bağlaması olabilir.

Bu bağlamaları işlev klasörünüzdeki function.json dosyasında bildirirsiniz. Önceki hızlı başlangıçtan itibaren HttpExample klasöründeki function.json dosyanız koleksiyonda bindings iki bağlama içerir:

"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "res"
    }
]
"scriptFile": "__init__.py",
"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "$return"
    }
"bindings": [
  {
    "authLevel": "function",
    "type": "httpTrigger",
    "direction": "in",
    "name": "Request",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "Response"
  }
]

Her bağlamanın en az bir türü, yönü ve adı vardır. Yukarıdaki örnekte, ilk bağlama yönüyle intüründedirhttpTrigger. in yönü için, name tetikleyici tarafından çağrıldığında işleve gönderilen bir giriş parametresinin adını belirtir.

Koleksiyondaki ikinci bağlama olarak adlandırılır res. Bu http bağlama, HTTP yanıtını yazmak için kullanılan bir çıkış bağlamasıdır (out).

Bu işlevden bir Azure Depolama kuyruğuna yazmak için, aşağıdaki kodda gösterildiği gibi adlı msgbir out tür queue bağlaması ekleyin:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Koleksiyondaki ikinci bağlama, yönü outile türündedirhttp. Bu durumda, özel name$return öğesi bu bağlamanın giriş parametresi sağlamak yerine işlevin dönüş değerini kullandığını gösterir.

Bu işlevden bir Azure Depolama kuyruğuna yazmak için, aşağıdaki kodda gösterildiği gibi adlı msgbir out tür queue bağlaması ekleyin:

"bindings": [
  {
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "$return"
  },
  {
    "type": "queue",
    "direction": "out",
    "name": "msg",
    "queueName": "outqueue",
    "connection": "AzureWebJobsStorage"
  }
]

Koleksiyondaki ikinci bağlama olarak adlandırılır res. Bu http bağlama, HTTP yanıtını yazmak için kullanılan bir çıkış bağlamasıdır (out).

Bu işlevden bir Azure Depolama kuyruğuna yazmak için, aşağıdaki kodda gösterildiği gibi adlı msgbir out tür queue bağlaması ekleyin:

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Bu durumda işleve msg çıkış bağımsız değişkeni olarak verilir. Bir queue tür için içindeki kuyruğun queueName adını da belirtmeniz ve içinde Azure Depolama bağlantısının adını (local.settings.json dosyasından) connectionsağlamanız gerekir.

C# projesinde bağlamalar, işlev yönteminde bağlama öznitelikleri olarak tanımlanır. Belirli tanımlar, uygulamanızın işlem içinde mi (C# sınıf kitaplığı) yoksa yalıtılmış bir işlemde mi çalıştığına bağlıdır.

HttpExample.cs proje dosyasını açın ve yöntem tanımına aşağıdaki parametreyi Run ekleyin:

[Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg,

msg parametresi, ICollector<T> işlev tamamlandığında çıkış bağlamasına yazılan bir ileti koleksiyonunu temsil eden bir türdür. Bu durumda, çıktı adlı outqueuebir depolama kuyruğudur. depolama StorageAccountAttribute hesabı için bağlantı dizesini ayarlar. Bu öznitelik, depolama hesabı bağlantı dizesini içeren ayarı gösterir ve sınıf, yöntem veya parametre düzeyinde uygulanabilir. Bu durumda, varsayılan depolama hesabını zaten kullandığınız için atlayabilirsiniz StorageAccountAttribute .

Run yöntemi tanımı artık aşağıdaki kod gibi görünmelidir:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)

Java projesinde bağlamalar, işlev yönteminde bağlama ek açıklamaları olarak tanımlanır. Function.json dosyası daha sonra bu ek açıklamalara göre otomatik olarak oluşturulur.

src/main/java altında işlev kodunuzun konumuna göz atın, Function.java proje dosyasını açın ve yöntem tanımına aşağıdaki parametreyi run ekleyin:

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

msg parametresi, dize OutputBinding<T> koleksiyonunu temsil eden bir türdür. Bu dizeler, işlev tamamlandığında bir çıkış bağlamasına ileti olarak yazılır. Bu durumda, çıktı adlı outqueuebir depolama kuyruğudur. Depolama hesabının bağlantı dizesi yöntemi tarafından connection ayarlanır. Bağlantı dizesinin kendisini geçirmek yerine Depolama hesabı bağlantı dizesini içeren uygulama ayarını geçirirsiniz.

Yöntem run tanımı artık aşağıdaki örnekteki gibi görünmelidir:

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)  
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    ...
}

Çıkış bağlamasını kullanmak için kod ekleme

Kuyruk bağlaması tanımlandığında artık bağlama parametresini kullanarak kuyruğa ileti yazmak için işlevinizi güncelleştirebilirsiniz.

HttpExample\__init__.py dosyasını aşağıdaki kodla eşleşecek şekilde güncelleştirin, parametresini işlev tanımına ve msg.set(name) deyiminin if name: altına ekleyinmsg:

import logging

import azure.functions as func


def main(req: func.HttpRequest, msg: func.Out[func.QueueMessage]) -> str:

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        msg.set(name)
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

msg parametresi, öğesinin azure.functions.Out classbir örneğidir. set yöntemi kuyruğa bir dize iletisi yazar. Bu durumda, URL sorgu dizesindeki işleve geçirilen addır.

Kuyruk iletisi oluşturmak için çıkış context.bindings bağlama nesnesini kullanan msg kod ekleyin. Bu kodu deyiminden context.res önce ekleyin.

// Add a message to the Storage queue,
// which is the name passed to the function.
context.bindings.msg = (req.query.name || req.body.name);

Bu noktada işlevinizin aşağıdaki gibi görünmesi gerekir:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (req.query.name || (req.body && req.body.name)) {
        // Add a message to the Storage queue,
        // which is the name passed to the function.
        context.bindings.msg = (req.query.name || req.body.name);
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

Kuyruk iletisi oluşturmak için çıkış context.bindings bağlama nesnesini kullanan msg kod ekleyin. Bu kodu deyiminden context.res önce ekleyin.

context.bindings.msg = name;

Bu noktada işlevinizin aşağıdaki gibi görünmesi gerekir:

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('HTTP trigger function processed a request.');
    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        // Add a message to the storage queue, 
        // which is the name passed to the function.
        context.bindings.msg = name; 
        // Send a "hello" response.
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

export default httpTrigger;

Çıkış bağlamasını Push-OutputBinding kullanarak kuyruğa metin yazmak için cmdlet'ini msg kullanan kod ekleyin. Deyiminde if Tamam durumunu ayarlamadan önce bu kodu ekleyin.

$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg

Bu noktada işlevinizin aşağıdaki gibi görünmesi gerekir:

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
    # Write the $name value to the queue, 
    # which is the name passed to the function.
    $outputMsg = $name
    Push-OutputBinding -name msg -Value $outputMsg

    $status = [HttpStatusCode]::OK
    $body = "Hello $name"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

Kuyruk iletisi oluşturmak için çıkış bağlama nesnesini kullanan msg kod ekleyin. Yöntem döndürmeden önce bu kodu ekleyin.

if (!string.IsNullOrEmpty(name))
{
    // Add a message to the output collection.
    msg.Add(name);
}

Bu noktada işlevinizin aşağıdaki gibi görünmesi gerekir:

[FunctionName("HttpExample")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, 
    [Queue("outqueue"),StorageAccount("AzureWebJobsStorage")] ICollector<string> msg, 
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    if (!string.IsNullOrEmpty(name))
    {
        // Add a message to the output collection.
        msg.Add(name);
    }
    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

Artık işlev kodunuzdan çıkış bağlamasına yazmak için yeni msg parametresini kullanabilirsiniz. değerini çıkış bağlamasına eklemek namemsg için başarı yanıtının önüne aşağıdaki kod satırını ekleyin.

msg.setValue(name);

Çıkış bağlaması kullandığınızda kimlik doğrulaması, kuyruk başvurusu alma veya veri yazma için Azure Depolama SDK kodunu kullanmanız gerekmez. İşlevler çalışma zamanı ve kuyruk çıkış bağlaması bu görevleri sizin için yapar.

Yönteminiz run şimdi aşağıdaki örnekteki gibi görünmelidir:

public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", 
        connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
        final ExecutionContext context) {
    context.getLogger().info("Java HTTP trigger processed a request.");

    // Parse query parameter
    String query = request.getQueryParameters().get("name");
    String name = request.getBody().orElse(query);

    if (name == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
        .body("Please pass a name on the query string or in the request body").build();
    } else {
        // Write the name to the message queue. 
        msg.setValue(name);

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
}

Testleri güncelleştirme

Archetype bir dizi test oluşturduğundan, bu testleri yöntem imzasında run yeni msg parametreyi işleyecek şekilde güncelleştirmeniz gerekir.

src/test/java altında test kodunuzun konumuna göz atın, Function.java proje dosyasını açın ve altındaki //Invoke kod satırını aşağıdaki kodla değiştirin:

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);

Kayıt defterindeki görüntüyü güncelleştirme

  1. Kök klasörde yeniden çalıştırın docker build ve bu kez etiketindeki sürümü olarak v1.0.1güncelleştirin. Daha önce olduğu gibi değerini Docker Hub hesap kimliğiniz ile değiştirin<docker_id>.

    docker build --tag <docker_id>/azurefunctionsimage:v1.0.1 .
    
  2. Güncelleştirilmiş görüntüyü ile docker pushdepoya geri gönderin.

    docker push <docker_id>/azurefunctionsimage:v1.0.1
    
  3. Sürekli teslim yapılandırdığınız için kayıt defterindeki görüntüyü yeniden güncelleştirmek Azure'daki işlev uygulamanızı otomatik olarak güncelleştirir.

azure Depolama kuyruğunda iletiyi görüntüleme

Bir tarayıcıda işlevinizi çağırmak için önceki URL'yi kullanın. İşlev kodunun bu bölümünü değiştirmediğiniz için tarayıcının öncekiyle aynı yanıtı görüntülemesi gerekir. Ancak eklenen kod, depolama kuyruğunun URL parametresini nameoutqueue kullanarak bir ileti yazdı.

Kuyruğu Azure portal veya Microsoft Azure Depolama Gezgini görüntüleyebilirsiniz. Aşağıdaki adımlarda açıklandığı gibi kuyruğu Azure CLI'da da görüntüleyebilirsiniz:

  1. İşlev projesinin local.setting.json dosyasını açın ve bağlantı dizesi değerini kopyalayın. Terminalde veya komut penceresinde, adlı AZURE_STORAGE_CONNECTION_STRINGbir ortam değişkeni oluşturmak için aşağıdaki komutu çalıştırın ve yerine <MY_CONNECTION_STRING>belirli bağlantı dizenizi yapıştırın. (Bu ortam değişkeni, bağımsız değişkenini kullanarak --connection-string sonraki her komuta bağlantı dizesi sağlamanız gerekmeyecek anlamına gelir.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (İsteğe bağlı) Hesabınızdaki az storage queue list Depolama kuyruklarını görüntülemek için komutunu kullanın. Bu komutun çıktısı, işlev bu kuyruğa ilk iletisini yazdığında oluşturulan adlı outqueuebir kuyruk içermelidir.

    az storage queue list --output tsv
    
  3. az storage message get Bu kuyruktan iletiyi okumak için komutunu kullanın. Bu, daha önce işlevi test ederken sağladığınız değer olmalıdır. komut, kuyruktan ilk iletiyi okur ve kaldırır.

    echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`
    

    İleti gövdesi base64 kodlanmış olarak depolandığından, görüntülenmeden önce iletinin kodunun çözülmesi gerekir. komutunu yürüttkten az storage message getsonra ileti kuyruktan kaldırılır. içinde outqueueyalnızca bir ileti varsa, bu komutu ikinci kez çalıştırdığınızda bir iletiyi alamazsınız ve bunun yerine hata alırsınız.

Kaynakları temizleme

Bu öğreticide oluşturduğunuz kaynakları kullanarak Azure İşlevi ile çalışmaya devam etmek istiyorsanız, tüm bu kaynakları yerinde bırakabilirsiniz. Azure İşlevleri için bir Premium Planı oluşturduğunuz için devam eden maliyetler için günde bir veya iki ABD doları ödemeniz gerekir.

Devam eden maliyetleri önlemek için kaynak grubunu silip AzureFunctionsContainers-rg bu gruptaki tüm kaynakları temizleyin:

az group delete --name AzureFunctionsContainers-rg

Sonraki adımlar