Hızlı Başlangıç: Azure İşlevlerini kullanarak gerçek zamanlı olayları işleme

Bu makalede, Azure İşlevleri'nde gerçek zamanlı olay işleme için bir Event Hubs tetikleyici işlevi oluşturmak için Azure Geliştirici CLI'sini (azd) kullanacaksınız. Kodu yerel olarak doğruladıktan sonra Azure'da Flex Consumption planında çalışan yeni bir sunucusuz işlev uygulamasına dağıtırsınız.

Proje kaynağı, işlev uygulamasını ve ilgili kaynakları oluşturmak ve kodunuzu Azure'a dağıtmak için kullanır azd . Bu dağıtım, güvenli ve ölçeklenebilir Azure İşlevleri dağıtımları için geçerli en iyi yöntemleri izler.

Flex Tüketim planı varsayılan olarak kullanabildiğiniz kadar öde faturalama modelini izler. Bu, bu makaleyi tamamlayabileceğiniz ve Azure hesabınızda yalnızca birkaç ABD doları veya daha az bir maliyete neden olabileceğiniz anlamına gelir.

Bu makale, Azure İşlevleri için Node.js programlama modelinin 4. sürümünü destekler.

Bu makale, Azure İşlevleri için Python programlama modelinin 2. sürümünü destekler.

Önkoşullar

  • .NET 8 SDK

Projeyi başlatma

azd init Komutunu kullanarak şablondan yerel bir Azure İşlevleri kod projesi oluşturun.

Yerel terminalinizde veya komut isteminizde şu azd init komutu boş bir klasörde çalıştırın:

azd init --template functions-quickstart-dotnet-azd-eventhub -e eventhub-dotnet

Bu komut proje dosyalarını template deposundan çeker ve projeyi geçerli klasörde başlatır. -e bayrağı, geçerli ortam için bir ad tanımlar. ortamında azd, ortamınız uygulamanız için benzersiz bir dağıtım bağlamı tutar ve birden fazla dağıtım bağlamı tanımlayabilirsiniz. Ortam adı, Azure'da oluşturduğunuz kaynak grubunun adında da kullanılır.

Yerel terminalinizde veya komut isteminizde şu azd init komutu boş bir klasörde çalıştırın:

azd init --template functions-quickstart-typescript-azd-eventhub -e eventhub-ts

Bu komut proje dosyalarını template deposundan çeker ve projeyi geçerli klasörde başlatır. -e bayrağı, geçerli ortam için bir ad tanımlar. ortamında azd, ortamınız uygulamanız için benzersiz bir dağıtım bağlamı tutar ve birden fazla dağıtım bağlamı tanımlayabilirsiniz. Ortam adı, Azure'da oluşturduğunuz kaynak grubunun adında da kullanılır.

Yerel terminalinizde veya komut isteminizde şu azd init komutu boş bir klasörde çalıştırın:

azd init --template functions-quickstart-python-azd-eventhub -e eventhub-py

Bu komut proje dosyalarını template deposundan çeker ve projeyi geçerli klasörde başlatır. -e bayrağı, geçerli ortam için bir ad tanımlar. ortamında azd, ortamınız uygulamanız için benzersiz bir dağıtım bağlamı tutar ve birden fazla dağıtım bağlamı tanımlayabilirsiniz. Ortam adı, Azure'da oluşturduğunuz kaynak grubunun adında da kullanılır.

Sanal ortam oluşturma ve etkinleştirme

Kök klasörde şu komutları çalıştırarak adlı .venvbir sanal ortam oluşturun ve etkinleştirin:

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

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

sudo apt-get install python3-venv

Yerel terminalinizde veya komut isteminizde şu azd init komutu boş bir klasörde çalıştırın:

azd init --template functions-quickstart-java-azd-eventhub -e eventhub-java

Bu komut proje dosyalarını template deposundan çeker ve projeyi geçerli klasörde başlatır. -e bayrağı, geçerli ortam için bir ad tanımlar. ortamında azd, ortamınız uygulamanız için benzersiz bir dağıtım bağlamı tutar ve birden fazla dağıtım bağlamı tanımlayabilirsiniz. Ortam adı, Azure'da oluşturduğunuz kaynak grubunun adında da kullanılır.

Yerel terminalinizde veya komut isteminizde şu azd init komutu boş bir klasörde çalıştırın:

azd init --template functions-quickstart-javascript-azd-eventhub -e eventhub-js

Bu komut proje dosyalarını template deposundan çeker ve projeyi geçerli klasörde başlatır. -e bayrağı, geçerli ortam için bir ad tanımlar. ortamında azd, ortamınız uygulamanız için benzersiz bir dağıtım bağlamı tutar ve birden fazla dağıtım bağlamı tanımlayabilirsiniz. Ortam adı, Azure'da oluşturduğunuz kaynak grubunun adında da kullanılır.

Yerel terminalinizde veya komut isteminizde şu azd init komutu boş bir klasörde çalıştırın:

azd init --template functions-quickstart-powershell-azd-eventhub -e eventhub-ps

Bu komut proje dosyalarını template deposundan çeker ve projeyi geçerli klasörde başlatır. -e bayrağı, geçerli ortam için bir ad tanımlar. ortamında azd, ortamınız uygulamanız için benzersiz bir dağıtım bağlamı tutar ve birden fazla dağıtım bağlamı tanımlayabilirsiniz. Ortam adı, Azure'da oluşturduğunuz kaynak grubunun adında da kullanılır.

Azure kaynakları oluşturun

İşlevinizi yerel olarak çalıştırabilmeniz için önce Azure'da bir Event Hubs ad alanı ve hub oluşturmanız gerekir. Gerekli azd provision dosyasını ekleyerek bu kaynakları oluşturmak ve yerel ayarlarınızı yapılandırmak için kullanın.

  1. Azure'da oturum açmak için aşağıdaki komutu çalıştırın:

    azd auth login
    

    Azure hesabınızı kullanarak kimlik doğrulaması yapmak için istemleri izleyin.

  2. Kök klasörden aşağıdaki komutu çalıştırarak Azure kaynaklarınızı oluşturun:

    azd provision
    
  3. İstendiğinde şu gerekli dağıtım parametrelerini sağlayın:

    Parametre Açıklama
    Azure aboneliği Kaynaklarınızı oluşturduğunuz abonelik.
    Azure veri merkezi konumu Yeni Azure kaynaklarını içeren kaynak grubunun oluşturulacağı Azure bölgesi. Yalnızca şu anda Esnek Tüketim planını destekleyen bölgeler gösterilir.
    vnetEnabled Sanal ağ kaynakları oluşturmanın ek yükünü önlemek için değerini False kullanın.

    Komut, azd provision Event Hubs ad alanı ve hub'ı, Flex Consumption işlev uygulaması, Application Insights ve depolama hesabı gibi gerekli Azure kaynaklarını oluşturur. Ayrıca local.settings.json dosyanızı Event Hubs bağlantı bilgileriyle yapılandırıyor.

Yerel ortamınızda çalıştırma

  1. Ayrı bir terminal penceresinde Azurite depolama öykünücüsİnİ başlatın:

    azurite
    

    Yerel İşlevler ana bilgisayar işlemi, çalışma zamanı için gereken iç depolama bağlantısı (AzureWebJobsStorage) için Azurite öykünücüsü kullanır.

  1. İşlev uygulamasını başlatmak için şu komutları bir terminalde veya komut isteminde çalıştırarak proje klasörüne src gidin ve işlev uygulamasını başlatın:

    cd src
    func start
    
  1. İşlev uygulamasını başlatmak için şu komutu bir terminalde veya komut isteminde çalıştırın:

    func start
    
  1. İşlev uygulamasını derlemek ve başlatmak için şu komutları bir terminalde veya komut isteminde çalıştırın:

    mvn clean package
    mvn azure-functions:run
    
  1. Bağımlılıkları yüklemek ve işlev uygulamasını başlatmak için şu komutları bir terminalde veya komut isteminde çalıştırın:

    npm install
    npm start  
    
  1. Bağımlılıkları yüklemek ve işlev uygulamasını başlatmak için şu komutları bir terminalde veya komut isteminde çalıştırın:

    cd src
    npm install
    npm start  
    
  1. İşlev uygulamasını başlatmak için şu komutu bir terminalde veya komut isteminde çalıştırın:

    func start
    
  1. İstenirse, güvenlik duvarı üzerinden Core Tools'un (func.exe) çağrılmasına izin verin.

  2. İşlevler konağı yerel proje klasörünüzde başladığında, işlevlerinizle ilgili bilgileri terminal çıkışına yazar.

    Bu örnek, her 10 saniyede bir otomatik olarak haber makaleleri oluşturan ve bunları Event Hubs'a gönderen bir Zamanlayıcı tetikleyici işlevi içerir. Event Hubs tetikleyici işlevi daha sonra bu olayları işler ve yaklaşım analizi ile etkileşim izleme gerçekleştirir.

    Bu örneğe benzer bir çıktı görürsünüz:

     [2026-03-02T22:37:30.151Z] Executing 'Functions.EventHubsTrigger'
     [2026-03-02T22:37:30.159Z] Trigger Details: PartitionId: 24, OffsetString: 0, EnqueueTimeUtc: 2026-03-02T22:37:29.1790000+00:00, SequenceNumber: 0, Count: 1, Offset: 0, PartionId: 24
     [2026-03-02T22:37:30.169Z] ⭐ High-engagement article NEWS-20260302-0580CB82 (Views: 6123, Sentiment: 0.57) featured!
     [2026-03-02T22:37:30.174Z] 🔥 Viral article: NEWS-20260302-0580CB82 - 6,123 views
     [2026-03-02T22:37:30.181Z] 🌟 Featured article: NEWS-20260302-0580CB82
     [2026-03-02T22:37:30.185Z] ✅ Successfully processed article NEWS-20260302-0580CB82 - 'Technology Breakthrough in Renewable Energy Technology' by Sarah Johnson
     [2026-03-02T22:37:30.191Z] 📰 Processed 1 news articles, 0 failed in batch of 1
     [2026-03-02T22:37:30.196Z] 📊 NEWS BATCH SUMMARY: 1 articles | Total Views: 6,123 | Avg Views: 6,123 | Avg Sentiment: 0.57 | Status: [Featured: 1]
     [2026-03-02T22:37:30.200Z] 📂 Top Categories: [Health: 1] | Top Sources: [Innovation Weekly: 1]
     [2026-03-02T22:37:30.204Z] 🔥 Viral articles in batch: 1
     [2026-03-02T22:37:30.207Z] Executed 'Functions.EventHubsTrigger' (Succeeded, Duration=55ms)
     
  3. İşiniz bittiğinde, ana bilgisayar işlemini durdurmak func.exe için terminal penceresinde Ctrl+C tuşlarına basın.

  4. Azurite'nin çalıştığı pencereyi kapatın.

  1. Sanal ortamı kapatmak için komutunu çalıştırın deactivate .

Kodu gözden geçirme (isteğe bağlı)

Event Hubs tetikleyici işlevini tanımlayan kodu gözden geçirebilirsiniz:

using System.Text.Json;
using Azure.Messaging.EventHubs;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace function_app;

public class EventHubsTrigger
{
    private readonly ILogger<EventHubsTrigger> _logger;
    private readonly NewsProcessingService _newsService;

    public EventHubsTrigger(ILogger<EventHubsTrigger> logger, NewsProcessingService newsService)
    {
        _logger = logger;
        _newsService = newsService;
    }

    [Function(nameof(EventHubsTrigger))]
    public async Task Run([EventHubTrigger("news", Connection = "EventHubConnection")] EventData[] input)
    {
        var processedArticles = new List<NewsArticle>();
        var failedEvents = 0;
        
        foreach (var message in input)
        {
            try
            {
                var messageBody = message.EventBody.ToString();

                // Parse the news article event
                var article = ParseNewsArticleEvent(messageBody);

                if (article != null)
                {
                    processedArticles.Add(article);
                }
                else
                {
                    failedEvents++;
                }
            }
            catch (Exception ex)
            {
                failedEvents++;
                _logger.LogWarning($"Error processing message: {ex.Message}");
            }
        }

        // Log summary of this execution
        _logger.LogInformation($"📰 Processed {processedArticles.Count} news articles, {failedEvents} failed in batch of {input.Length}");

Şablon projesinin tamamını here gözden geçirebilirsiniz.

package com.function;

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

import java.time.Instant;
import java.util.*;
import java.util.logging.Logger;

/**
 * Azure Function that processes messages from an input Event Hub,
 * adds metadata, and sends processed messages to an output Event Hub.
 */
public class EventHubsTriggerFunction {

    @FunctionName("EventHubsTrigger")
    public void run(
            @EventHubTrigger(
                name = "messages",
                eventHubName = "%INPUT_EVENTHUB_NAME%",
                connection = "EventHubConnection",
                cardinality = Cardinality.MANY)
            List<String> messages,
            @EventHubOutput(
                name = "output",
                eventHubName = "%OUTPUT_EVENTHUB_NAME%",
                connection = "EventHubConnection")
            OutputBinding<List<String>> output,
            final ExecutionContext context) {

        Logger logger = context.getLogger();
        logger.info(String.format("🔄 Event hub function processing %d message(s)", messages.size()));

        List<String> processedMessages = new ArrayList<>();

        for (String message : messages) {
            try {
                logger.info("📨 Processing event: " + message);

                // Create processed message with additional metadata
                String processedMessage = String.format(
                    "{\"id\":\"%s\",\"message\":%s,\"timestamp\":\"%s\"}",
                    UUID.randomUUID().toString(),
                    message,
                    Instant.now().toString());

                processedMessages.add(processedMessage);
                logger.info("\u2728 Message processed: " + processedMessage);

            } catch (Exception e) {
                logger.severe("\u274C Error processing message: " + e.getMessage());
            }
        }

        // Send processed messages to output Event Hub
        if (!processedMessages.isEmpty()) {
            output.setValue(processedMessages);
            logger.info(String.format("📤 Sent %d message(s) to output Event Hub", processedMessages.size()));
        }
    }
}

Şablon projesinin tamamını here gözden geçirebilirsiniz.

const { app, output } = require("@azure/functions");

const eventHubOutput = output.eventHub({
    connection: 'EventHubConnection',
    eventHubName: '%OUTPUT_EVENTHUB_NAME%'
});

async function EventHubsTrigger(messages, context) {
    context.log(`🔄 Event hub function processing ${messages.length} message(s)`);
    
    const processedMessages = [];
    
    for (const message of messages) {
        try {
            // Parse the incoming message
            const eventData = typeof message === 'string' ? JSON.parse(message) : message;
            context.log('📨 Processing event:', eventData);
            
            // Create processed message with additional metadata
            const processedMessage = {
                id: eventData.id || crypto.randomUUID(),
                message: eventData.message || JSON.stringify(eventData),
                timestamp: new Date().toISOString()
            };
            
            processedMessages.push(processedMessage);
            context.log('✨ Message processed:', processedMessage);
            
        } catch (error) {
            context.error(`❌ Error processing message: ${error}`);
        }
    }
    
    // Send processed messages to output Event Hub
    if (processedMessages.length > 0) {
        context.extraOutputs.set(eventHubOutput, processedMessages);
        context.log(`📤 Sent ${processedMessages.length} message(s) to output Event Hub`);
    }
}

app.eventHub('EventHubsTrigger', {
    connection: 'EventHubConnection',
    eventHubName: '%INPUT_EVENTHUB_NAME%',
    cardinality: 'many',
    extraOutputs: [eventHubOutput],
    handler: EventHubsTrigger
});

Şablon projesinin tamamını here gözden geçirebilirsiniz.

import { app, InvocationContext, output } from "@azure/functions";

interface EventMessage {
    id: string;
    message: string;
    timestamp: string;
}

const eventHubOutput = output.eventHub({
    connection: 'EventHubConnection',
    eventHubName: '%OUTPUT_EVENTHUB_NAME%'
});

export async function EventHubsTrigger(messages: unknown[], context: InvocationContext): Promise<void> {
    context.log(`🔄 Event hub function processing ${messages.length} message(s)`);
    
    const processedMessages: EventMessage[] = [];
    
    for (const message of messages) {
        try {
            // Parse the incoming message
            const eventData = typeof message === 'string' ? JSON.parse(message) : message;
            context.log('📨 Processing event:', eventData);
            
            // Create processed message with additional metadata
            const processedMessage: EventMessage = {
                id: eventData.id || crypto.randomUUID(),
                message: eventData.message || JSON.stringify(eventData),
                timestamp: new Date().toISOString()
            };
            
            processedMessages.push(processedMessage);
            context.log('✨ Message processed:', processedMessage);
            
        } catch (error) {
            context.error(`❌ Error processing message: ${error}`);
        }
    }
    
    // Send processed messages to output Event Hub
    if (processedMessages.length > 0) {
        context.extraOutputs.set(eventHubOutput, processedMessages);
        context.log(`📤 Sent ${processedMessages.length} message(s) to output Event Hub`);
    }
}

app.eventHub('EventHubsTrigger', {
    connection: 'EventHubConnection',
    eventHubName: '%INPUT_EVENTHUB_NAME%',
    cardinality: 'many',
    extraOutputs: [eventHubOutput],
    handler: EventHubsTrigger
});

Şablon projesinin tamamını here gözden geçirebilirsiniz.

param($InputEvents, $TriggerMetadata)

Write-Host "🔄 Event hub function processing $($InputEvents.Count) message(s)"

$processedMessages = @()

foreach ($message in $InputEvents) {
    try {
        # Parse the incoming message
        $eventData = $message | ConvertFrom-Json -ErrorAction SilentlyContinue
        if (-not $eventData) {
            $eventData = @{ message = $message }
        }

        Write-Host "📨 Processing event: $($eventData | ConvertTo-Json -Compress)"

        # Create processed message with additional metadata
        $processedMessage = @{
            id        = if ($eventData.id) { $eventData.id } else { [guid]::NewGuid().ToString() }
            message   = if ($eventData.message) { $eventData.message } else { ($eventData | ConvertTo-Json -Compress) }
            timestamp = (Get-Date).ToUniversalTime().ToString('o')
        }

        $processedMessages += $processedMessage
        Write-Host "✨ Message processed: $($processedMessage | ConvertTo-Json -Compress)"
    }
    catch {
        Write-Error "❌ Error processing message: $_"
    }
}

# Send processed messages to output Event Hub
if ($processedMessages.Count -gt 0) {
    Push-OutputBinding -Name OutputEvents -Value ($processedMessages | ConvertTo-Json -Compress)
    Write-Host "📤 Sent $($processedMessages.Count) message(s) to output Event Hub"
}

Tetikleyici, karşılık gelen function.json tanımlanır.

Şablon projesinin tamamını here gözden geçirebilirsiniz.

import azure.functions as func
import logging
import json
from datetime import datetime, timezone
import random
import uuid
from typing import List

app = func.FunctionApp()

# News article data model
class NewsArticle:
            title=random.choice(titles_templates).format(topic=topic),
            content=f"Comprehensive coverage of the latest developments in {topic}. " * random.randint(10, 20),
            author=random.choice(authors),
            source=random.choice(sources),
            category=random.choice(categories),
            published_date=datetime.now(timezone.utc),
            view_count=random.randint(100, 10000),
            sentiment_score=round(random.uniform(-1.0, 1.0), 2),
            status=random.choice(["Published", "Featured"]),
            tags=[random.choice(topics) for _ in range(random.randint(3, 5))]
        )
        articles.append(article)
    
    # Send articles to Event Hub
    events_json = json.dumps([article.to_dict() for article in articles])
    event.set(events_json)
    
    logging.info(f'✅ HIGH-THROUGHPUT: Successfully generated {num_articles} news articles in ~10 seconds')


# Event Hub trigger - processes news articles
@app.event_hub_message_trigger(arg_name="events", event_hub_name="news",
                                connection="EventHubConnection")
def EventHubsTrigger(events: List[func.EventHubEvent]):
    """Process news articles from Event Hub with sentiment analysis and engagement tracking"""
    
    # Handle both single event and list of events
    if not isinstance(events, list):
        events = [events]
    
    batch_articles = []
    failed_count = 0
    
    for event in events:
        try:
            # Parse the event data
            event_data = json.loads(event.get_body().decode('utf-8'))
            
            # Handle both single article and array of articles
            articles = event_data if isinstance(event_data, list) else [event_data]
            
            for article_data in articles:
                # Process each article
                article_id = article_data.get('ArticleId')
                title = article_data.get('Title')
                author = article_data.get('Author')

Şablon projesinin tamamını here gözden geçirebilirsiniz.

İşlevinizi yerel olarak doğruladıktan sonra Azure'da yayımlamanın zamanı geldi.

Azure’a dağıtın

Azure'daki Flex Consumption planında yeni bir işlev uygulamasına kodunuzu dağıtmak için azd up komutunu kullanacak şekilde yapılandırılan bu projedir. Kaynakları önceden sağladığınızdan, bu komut kodunuzu mevcut işlev uygulamasına dağıtır.

Tavsiye

Bu proje, en iyi yöntemleri izleyen bir Flex Tüketim planına güvenli bir dağıtım oluşturmak için kullanılan Bicep dosyaları kümesini içerir.

Kod projenizi Azure'daki işlev uygulamasına dağıtmak için depo kök klasöründen aşağıdaki komutu çalıştırın:

azd deploy

Dağıtım, kodunuzu paketler ve işlev uygulamasına dağıtır. Komut tamamlandığında, oluşturduğunuz kaynakların bağlantılarını görürsünüz.

Dağıtımı doğrulayın

Dağıtım tamamlandıktan sonra Event Hubs tetikleyici işleviniz olay hub'ına ulaşan olayları otomatik olarak işlemeye başlar.

  1. Azure portalında yeni işlev uygulamanıza gidin.

  2. İşlev yürütmelerinizi gerçek zamanlı olarak izlemek için sol menüden Günlük akışı'nı seçin.

  3. Event Hubs tetikleyici işlevinizin, Zamanlayıcı tetikleyicisi tarafından oluşturulan olayları işlediğini içeren günlük girdilerini görürsünüz.

Kodunuzu yeniden dağıtma

azd up Komutunu hem Azure kaynaklarınızı sağlamak hem de işlev uygulamanıza kod güncelleştirmeleri dağıtmak için gerektiği kadar çalıştırın.

Uyarı

Dağıtılan kod dosyalarının üzerine her zaman en son dağıtım paketi yazılır.

İstemlere ve tarafından azd oluşturulan tüm ortam değişkenlerine azd yönelik ilk yanıtlarınız adlandırılmış ortamınızda yerel olarak depolanır. azd env get-values Azure kaynakları oluşturulurken kullanılan ortamınızdaki tüm değişkenleri gözden geçirmek için komutunu kullanın.

Kaynakları temizle

İşlev uygulamanızla ve ilgili kaynaklarla çalışmayı bitirdiğinizde, işlev uygulamasını ve ilgili kaynaklarını Azure'dan silmek ve başka maliyetlerle karşılaşmamak için bu komutu kullanın:

azd down --no-prompt

Uyarı

--no-prompt seçeneği, azd'in sizden onay almadan kaynak grubunuzu silmesini belirtir.

Bu komut yerel kod projenizi etkilemez.