Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste artigo, utiliza o Azure Developer CLI (azd) para criar uma função de disparo nos Event Hubs para processamento de eventos em tempo real no Funções do Azure. Depois de verificar o código localmente, implementa-o numa nova aplicação de funções serverless a correr num plano Flex Consumption no Azure.
O código-fonte do projeto utiliza azd para criar a aplicação de funções e os recursos relacionados e para desplegar o seu código no Azure. Esta implementação segue as melhores práticas atuais para implementações Funções do Azure seguras e escaláveis.
Por defeito, o plano Flex Consumption segue um modelo de faturação de pagamento pelo que usar , o que significa que pode completar este artigo e apenas incorrer num pequeno custo de alguns cêntimos USD ou menos na sua conta Azure.
Este artigo suporta a versão 4 do modelo de programação Node.js para o Funções do Azure.
Este artigo suporta a versão 2 do modelo de programação Python para o Funções do Azure.
Pré-requisitos
-
Java 21 Kit de Desenvolvimento
- Defina a variável de ambiente
JAVA_HOMEpara o local de instalação da versão correta do Java Development Kit (JDK).
- Defina a variável de ambiente
- Apache Maven 3.8.x
- Node.js 22 ou depois
- Python 3.11 ou posterior
CLI do Azure
Uma conta do Azure com uma assinatura ativa. Crie uma conta gratuitamente.
Inicializar o projeto
Use o azd init comando para criar um projeto de código local do Funções do Azure a partir de um modelo.
No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:
azd init --template functions-quickstart-dotnet-azd-eventhub -e eventhub-dotnet
Este comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O -e sinalizador define um nome para o ambiente atual. No azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.
No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:
azd init --template functions-quickstart-typescript-azd-eventhub -e eventhub-ts
Este comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O -e sinalizador define um nome para o ambiente atual. No azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.
No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:
azd init --template functions-quickstart-python-azd-eventhub -e eventhub-py
Este comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O -e sinalizador define um nome para o ambiente atual. No azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.
Criar e ativar um ambiente virtual
Na pasta raiz, execute estes comandos para criar e ativar um ambiente virtual chamado .venv:
python3 -m venv .venv
source .venv/bin/activate
Se o Python não instalar o pacote venv na sua distribuição Linux, execute o seguinte comando:
sudo apt-get install python3-venv
No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:
azd init --template functions-quickstart-java-azd-eventhub -e eventhub-java
Este comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O -e sinalizador define um nome para o ambiente atual. No azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.
No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:
azd init --template functions-quickstart-javascript-azd-eventhub -e eventhub-js
Este comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O -e sinalizador define um nome para o ambiente atual. No azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.
No terminal local ou prompt de comando, execute este azd init comando em uma pasta vazia:
azd init --template functions-quickstart-powershell-azd-eventhub -e eventhub-ps
Este comando extrai os arquivos de projeto do repositório de modelos e inicializa o projeto na pasta atual. O -e sinalizador define um nome para o ambiente atual. No azd, o ambiente mantém um contexto de implantação exclusivo para seu aplicativo e você pode definir mais de um. O nome do ambiente também é usado no nome do grupo de recursos que crias no Azure.
Criar recursos do Azure
Antes de poderes executar a tua função localmente, precisas de criar um namespace e hub de Event Hubs no Azure. Use azd provision para criar estes recursos e configurar as suas definições locais adicionando o ficheiro delocal.settings.json necessário.
Execute o seguinte comando para entrar no Azure:
azd auth loginSiga as instruções para autenticação usando a sua conta Azure.
A partir da pasta raiz, execute o seguinte comando para criar os seus recursos Azure:
azd provisionQuando solicitado, forneça estes parâmetros de implantação necessários:
Parâmetro Descrição Subscrição do Azure Subscrição na qual cria os seus próprios recursos. Localização do Azure Região do Azure na qual criar o grupo de recursos que contém os novos recursos do Azure. Apenas as regiões que atualmente suportam o plano Flex Consumption são mostradas. vnetEnabled Use um valor de Falsepara evitar o sobrecusto adicional de criar recursos de rede virtual.O
azd provisioncomando cria os recursos Azure necessários, incluindo um namespace e hub Event Hubs, uma aplicação para a função Flex Consumption, Application Insights e uma conta de armazenamento. Também configura o seu ficheiro de local.settings.json com a informação de ligação ao Event Hubs.
Executar no seu ambiente local
Numa janela de terminal separada, inicie o emulador de armazenamento Azurite:
azuriteO processo local Functions host utiliza o emulador Azurite para a ligação interna de armazenamento (
AzureWebJobsStorage) exigida pelo runtime.
Para iniciar a aplicação de funções, execute estes comandos num terminal ou no prompt de comandos para navegar até à
srcpasta do projeto e iniciar a aplicação de funções:cd src func start
Para iniciar a aplicação de funções, execute este comando num terminal ou no prompt de comandos:
func start
Para construir e iniciar a aplicação de funções, execute estes comandos num terminal ou no prompt de comandos:
mvn clean package mvn azure-functions:run
Para instalar dependências e iniciar a aplicação de funções, execute estes comandos num terminal ou prompt de comandos:
npm install npm start
Para instalar dependências e iniciar a aplicação de funções, execute estes comandos num terminal ou prompt de comandos:
cd src npm install npm start
Para iniciar a aplicação de funções, execute este comando num terminal ou no prompt de comandos:
func start
Se solicitado, permita que as Ferramentas Centrais (func.exe) sejam chamadas através do firewall.
Quando o anfitrião Functions começa na pasta local do projeto, ele escreve informações sobre as suas funções na saída do terminal.
Este exemplo inclui uma função de ativação de temporizador que gera automaticamente artigos de notícias a cada 10 segundos e os envia para os Centros de Eventos. A função de disparo dos Event Hubs processa então estes eventos e realiza análise de sentimento e acompanhamento de envolvimento.
Vê uma saída semelhante a este exemplo:
[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)
Quando terminar, pressione Ctrl+C na janela do terminal para interromper o processo do
func.exehost.Fecha a janela por onde a Azurite está a correr.
- Execute
deactivatepara desligar o ambiente virtual.
Rever o código (opcional)
Pode rever o código que define a função de disparo do Event Hubs:
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}");
Pode consultar o projeto modelo completo aqui.
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()));
}
}
}
Pode consultar o projeto modelo completo aqui.
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
});
Pode consultar o projeto modelo completo aqui.
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
});
Pode consultar o projeto modelo completo aqui.
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"
}
O gatilho está definido no correspondente function.json.
Pode consultar o projeto modelo completo aqui.
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')
Pode consultar o projeto modelo completo aqui.
Depois de verificares a tua função localmente, está na altura de a publicares no Azure.
Publicar no Azure
Este projeto está configurado para usar o azd up comando para implementar o seu código numa nova aplicação de funções num plano Flex Consumption no Azure. Como já provisionaste os recursos, este comando envia o teu código para a aplicação de funções existente.
Sugestão
Este projeto inclui um conjunto de ficheiros Bicep que azd servem para criar uma implementação segura num plano Flex Consumption que segue as melhores práticas.
A partir da pasta raiz do repositório, execute o seguinte comando para implementar o seu projeto de código na aplicação de funções no Azure:
azd deploy
A implementação empacota o seu código e implementa-o na aplicação de funções. Quando o comando termina, vê ligações para os recursos que criou.
Verificar a implementação
Após a implementação terminar, a função de disparo do seu Hub de Eventos começa automaticamente a processar eventos à medida que chegam ao hub de eventos.
No portal Azure, vai à tua nova aplicação de funções.
Selecione Log stream no menu esquerdo para monitorizar as execuções das suas funções em tempo real.
Vês entradas de registo que mostram a tua função de disparo do Event Hubs a processar eventos gerados pelo disparador Timer.
Reimplantar o teu código
Executa o azd up comando tantas vezes quanto precisares tanto para provisionar os teus recursos Azure como para implementar atualizações de código na tua aplicação de funções.
Observação
Os arquivos de código implantados são sempre substituídos pelo pacote de implantação mais recente.
Suas respostas iniciais a azd prompts e quaisquer variáveis de ambiente geradas por azd são armazenadas localmente em seu ambiente nomeado. Use o azd env get-values comando para revisar todas as variáveis em seu ambiente que foram usadas ao criar recursos do Azure.
Limpeza de recursos
Quando terminar de trabalhar com a sua function app e recursos relacionados, use este comando para eliminar a function app e os seus recursos relacionados do Azure e evitar quaisquer custos adicionais:
azd down --no-prompt
Observação
A --no-prompt opção instrui azd a excluir seu grupo de recursos sem uma confirmação sua.
Este comando não afeta seu projeto de código local.