在本文中,你使用 Azure Developer CLI(azd) 來建立一個 Event Hubs 觸發函式,用於 Azure Functions 中的即時事件處理。 在本地驗證程式碼後,你會部署到一個新的無伺服器函式應用程式,該應用程式在 Azure 的 Flex Consumption 計畫中運行。
專案原始碼用 azd 來建立函式應用程式及相關資源,並將程式碼部署到 Azure。 此部署遵循目前安全且可擴展的 Azure Functions 部署最佳實務。
預設情況下,Flex Consumption 方案採用按 使用量付費 的計費模式,這表示你可以完成本文,且在 Azure 帳戶中只需花費幾美元或更少的費用。
本文支援Azure Functions Node.js 程式設計模型的第四版。
本文支援 Azure Functions 的 Python 程式設計模型第二版。
先決條件
-
Java 21 開發者套件
- 將
JAVA_HOME環境變數設為正確版本的 Java 開發套件(JDK)安裝位置。
- 將
- Apache Maven 3.8.x
- Node.js 22 或更新版本
- Python 3.11 或更新版本
一個有有效訂閱的 Azure 帳號。 免費建立帳戶。
初始化專案
使用命令 azd init 從範本建立本機 Azure Functions 程式碼專案。
在您的本機終端機或命令提示字元中,於空白資料夾中執行此 azd init 命令:
azd init --template functions-quickstart-dotnet-azd-eventhub -e eventhub-dotnet
此指令會從 template 儲存庫 拉取專案檔案,並在目前資料夾中初始化專案。
-e 旗標會設定目前環境的名稱。 在 azd 中,該環境會為您的應用程式維護一個唯一的部署內容,而您可以定義多個部署內容。 環境名稱也會用在你在 Azure 建立的資源群組名稱中。
在您的本機終端機或命令提示字元中,於空白資料夾中執行此 azd init 命令:
azd init --template functions-quickstart-typescript-azd-eventhub -e eventhub-ts
此指令會從 template 儲存庫 拉取專案檔案,並在目前資料夾中初始化專案。
-e 旗標會設定目前環境的名稱。 在 azd 中,該環境會為您的應用程式維護一個唯一的部署內容,而您可以定義多個部署內容。 環境名稱也會用在你在 Azure 建立的資源群組名稱中。
在您的本機終端機或命令提示字元中,於空白資料夾中執行此 azd init 命令:
azd init --template functions-quickstart-python-azd-eventhub -e eventhub-py
此指令會從 template 儲存庫 拉取專案檔案,並在目前資料夾中初始化專案。
-e 旗標會設定目前環境的名稱。 在 azd 中,該環境會為您的應用程式維護一個唯一的部署內容,而您可以定義多個部署內容。 環境名稱也會用在你在 Azure 建立的資源群組名稱中。
建立並啟用虛擬環境
在根資料夾中,執行下列命令來建立並啟用名為 .venv 的虛擬環境:
python3 -m venv .venv
source .venv/bin/activate
如果 Python 沒有在你的 Linux 發行版安裝 venv 套件,請執行以下指令:
sudo apt-get install python3-venv
在您的本機終端機或命令提示字元中,於空白資料夾中執行此 azd init 命令:
azd init --template functions-quickstart-java-azd-eventhub -e eventhub-java
此指令會從 template 儲存庫 拉取專案檔案,並在目前資料夾中初始化專案。
-e 旗標會設定目前環境的名稱。 在 azd 中,該環境會為您的應用程式維護一個唯一的部署內容,而您可以定義多個部署內容。 環境名稱也會用在你在 Azure 建立的資源群組名稱中。
在您的本機終端機或命令提示字元中,於空白資料夾中執行此 azd init 命令:
azd init --template functions-quickstart-javascript-azd-eventhub -e eventhub-js
此指令會從 template 儲存庫 拉取專案檔案,並在目前資料夾中初始化專案。
-e 旗標會設定目前環境的名稱。 在 azd 中,該環境會為您的應用程式維護一個唯一的部署內容,而您可以定義多個部署內容。 環境名稱也會用在你在 Azure 建立的資源群組名稱中。
在您的本機終端機或命令提示字元中,於空白資料夾中執行此 azd init 命令:
azd init --template functions-quickstart-powershell-azd-eventhub -e eventhub-ps
此指令會從 template 儲存庫 拉取專案檔案,並在目前資料夾中初始化專案。
-e 旗標會設定目前環境的名稱。 在 azd 中,該環境會為您的應用程式維護一個唯一的部署內容,而您可以定義多個部署內容。 環境名稱也會用在你在 Azure 建立的資源群組名稱中。
創建 Azure 資源
在你能在本地執行函式之前,你需要在 Azure 中建立一個 Event Hubs 命名空間和一個 Hub。 用 azd provision 來建立這些資源,並透過新增所需的 local.settings.json 檔案來設定本地設定。
執行下列命令以登入 Azure:
azd auth login依照指示使用 Azure 帳號進行驗證。
從根目錄執行以下指令來建立你的 Azure 資源:
azd provision出現提示時,請提供這些必要的部署參數:
參數 說明 Azure 訂用帳戶 訂閱制,讓你創建資源。 Azure 位置 Azure 區域,用來建立包含新 Azure 資源的資源群組。 只會顯示目前支援彈性使用量方案的區域。 vnetEnabled 使用數值 False以避免建立虛擬網路資源時的額外開銷。此
azd provision指令建立所需的 Azure 資源,包括事件中心命名空間與樞紐、Flex Consumption 功能應用程式、Application Insights 以及儲存帳號。 它也會用 Event Hubs 的連線資訊來設定你的 local.settings.json 檔案。
在您的本機環境中執行
在另一個終端機視窗中,啟動 Azurite 儲存模擬器:
azurite本機 Functions 主機程序會使用 Azurite 模擬器,作為執行階段所需之內部儲存體連線 (
AzureWebJobsStorage)。
要啟動函式應用程式,請在終端機或命令提示字元執行以下指令,前往
src專案資料夾並啟動函式應用程式:cd src func start
要啟動函式應用程式,請在終端機或命令提示字元執行以下指令:
func start
要建立並啟動函式應用程式,請在終端機或命令提示字元執行以下指令:
mvn clean package mvn azure-functions:run
要安裝依賴項並啟動函式應用,請在終端機或命令提示字元視窗中執行以下指令:
npm install npm start
要安裝依賴項並啟動函式應用,請在終端機或命令提示字元視窗中執行以下指令:
cd src npm install npm start
要啟動函式應用程式,請在終端機或命令提示字元執行以下指令:
func start
若有提示,允許透過防火牆呼叫核心工具(func.exe)。
當 Functions 主機在你本地專案資料夾啟動時,它會把你的函式資訊寫入終端機輸出。
此範例包含計時器觸發功能,每 10 秒自動產生新聞文章並傳送至事件中心。 事件中心觸發功能接著處理這些事件,並執行情緒分析與互動追蹤。
你會看到類似這個範例的輸出:
[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)
當您完成時,請在終端機視窗中按 Ctrl+C 以停止
func.exe主機程序。關閉 Azurite 正在運行的視窗。
- 執行
deactivate以關閉虛擬環境。
檢閱程式碼 (選用)
你可以查看定義事件中心觸發函數的程式碼:
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}");
你可以查看完整的範本專案here。
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()));
}
}
}
你可以查看完整的範本專案here。
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
});
你可以查看完整的範本專案here。
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
});
你可以查看完整的範本專案here。
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"
}
觸發器定義於對應的 function.json。
你可以查看完整的範本專案here。
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')
你可以查看完整的範本專案here。
在你本地驗證功能後,就可以發佈到 Azure。
部署至 Azure
此專案已設定為使用 azd up 命令,將程式碼部署至 Azure 之彈性使用量方案中的新函數應用程式。 既然你已經配置好資源,這個指令會把你的程式碼部署到現有的函式應用程式。
小提示
此專案包含一組 Bicep 檔案,azd 會使用它們來建立遵循最佳做法、可安全部署到彈性使用量方案的部署。
從 repository root 資料夾執行以下指令,將你的程式碼專案部署到 Azure 的函式應用程式中:
azd deploy
部署會把你的程式碼打包並部署到 function 應用程式。 指令完成後,你會看到連結到你建立的資源。
確認部署
部署完成後,您的 Event Hubs 觸發程序函式會在 Event Hub 中有事件到達時,自動開始處理事件。
在 Azure 入口網站,進入你的新函數應用。
從左側選單選擇 日誌串流 ,即可即時監控你的函式執行。
你會看到日誌條目,顯示你的事件中心觸發函數正在處理由計時器觸發產生的事件。
重新部署程式碼
請重複執行 azd up 指令,以便同時配置 Azure 資源並將程式碼更新部署到函數應用程式。
備註
最新的部署套件一律會覆寫已部署的程式碼檔案。
您對 azd 提示的初始回應,以及 azd 所產生的任何環境變數都會儲存在本機的具名環境中。 使用 azd env get-values 命令來檢閱您環境中建立 Azure 資源時所使用的所有變數。
清理資源
當你完成函式應用程式及相關資源的運作後,請使用此指令從 Azure 刪除函式應用程式及其相關資源,避免產生任何額外費用:
azd down --no-prompt
備註
--no-prompt 選項會指示 azd 刪除您的資源群組,而不需要您確認。
此命令不會影響您的本機程式碼專案。