Java 中的 Azure 函數
1. 概述
在本教程中,我們將探索Azure Java Functions 。 Azure Function 是一種無伺服器運算服務,可執行程式碼以回應源自 Azure 服務或自訂應用程式的事件。我們可以使用 Python、Powershell、Javascript、C# 和 Typescript 等程式語言來編寫事件驅動程式碼。
此功能可讓自動化工程師開發處理源自各種 Azure 服務的事件的應用程式。 Azure Function 提供了一個無伺服器代管環境來執行程式碼,而無需擔心基礎架構管理。因此,它有助於這些自動化應用程式的快速部署、自動擴展和輕鬆維護。
2. 進階用例
讓我們來看幾個可以使用 Azure Functions 的範例:
Azure Function 是一項出色的無伺服器服務,可協助處理源自不同 Azure 服務或自訂應用程式的事件或資料。 此外,我們可以將該函數配置為按特定計劃運行,以輪詢來自各種來源的資料並執行進一步處理。甚至,自訂應用程式可以透過 HTTP 協定向 Function 應用程式發送訊息。
函數可以從事件上下文中讀取數據,轉換或豐富它們,然後將它們發送到目標系統。該事件可以是上傳到Blob 儲存容器的新檔案、佇列儲存中的新訊息或 Kafka 流服務中的主題。與其他服務相關的此類場景可能還會有更多。
此外, Azure 的事件網格服務可以使用發布-訂閱架構集中管理事件。服務可以將事件發佈到事件網格,訂閱者應用程式可以使用它們。**函數應用程式可以使用和處理來自事件網格的事件**。
3. 關鍵概念
在編寫程式碼之前,我們必須先了解一些關於 Azure Functions 程式設計模型的概念,例如綁定和觸發器。
當我們在 Azure Functions 中部署程式碼時,程式碼必須提供有關如何觸發它的強制資訊。 Azure 使用此資訊來呼叫在其中執行的函數。這稱為觸發器。 Azure Java 函式庫提供了藉由註解以宣告方式指定觸發器的框架。
同樣,這些功能需要與觸發來源相關的資料進行進一步處理。可以藉助輸入綁定來提供此資訊。此外,在某些情況下,該函數必須向目標系統發送一些資料。輸出綁定可以幫助實現這一點。與觸發器不同,綁定是可選的。
假設每當將檔案上傳到 Blob 儲存體時,我們都必須將其內容插入到 Cosmos DB 資料庫中。觸發器將幫助我們定義 Blob 儲存中的檔案上傳事件。此外,我們可以從觸發器中檢索文件內容。此外,使用輸出綁定,我們可以提供與將在其中插入資料的目標 Cosmos DB 相關的資訊。在某種程度上,它還有助於從函數傳回資料。
這些概念將在接下來的部分中更加清晰。
4. 先決條件
要體驗實際的 Azure Function,我們需要有效訂閱 Azure來建立雲端資源。
Eclipse 、 Visual Studio Code和IntelliJ等 IDE 提供擴充或插件,協助使用基於 Maven 的工具在 Azure 中開發、偵錯、測試和部署 Function 應用。它們有助於創建具有框架所有必要組件的腳手架,以加快開發速度。不過,在本教學中,我們將使用 IntelliJ 和Azure Toolkit 外掛程式。
儘管工具包插件可以幫助創建具有必要Maven 依賴項的 Java 項目,但了解它很重要:
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-library</artifactId>
<version>3.1.0</version>
</dependency>
Azure Functions Maven 外掛程式可協助打包和部署 Azure Functions:
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<version>1.24.0</version>
</plugin>
此外掛程式可協助指定部署配置,例如Azure Function的名稱、資源組、執行時間環境、設定等:
<configuration>
<appName>${functionAppName}</appName>
<resourceGroup>java-functions-group</resourceGroup>
<appServicePlanName>java-functions-app-service-plan</appServicePlanName>
<region>westus</region>
<runtime>
<os>windows</os>
<javaVersion>17</javaVersion>
</runtime>
<appSettings>
<property>
<name>FUNCTIONS_EXTENSION_VERSION</name>
<value>~4</value>
</property>
<property>
<name>AZURE_STORAGE</name>
<value>DefaultEndpointsProtocol=https;AccountName=functiondemosta;AccountKey=guymcrXX..XX;EndpointSuffix=core.windows.net</value>
</property>
</appSettings>
</configuration>
azure-functions
插件將整個應用程式打包在預先定義的標準資料夾結構中:
為每個觸發器端點建立的function.json
檔案定義了應用程式的入口點和綁定:
{
"scriptFile" : "../azure-functions-1.0.0-SNAPSHOT.jar",
"entryPoint" : "com.baeldung.functions.BlobTriggerJava.run",
"bindings" : [ {
"type" : "blobTrigger",
"direction" : "in",
"name" : "content",
"path" : "feeds/{name}.csv",
"dataType" : "binary",
"connection" : "AZURE_STORAGE"
}, {
"type" : "cosmosDB",
"direction" : "out",
"name" : "output",
"databaseName" : "organization",
"containerName" : "employee",
"connection" : "COSMOS_DB"
} ]
}
最後,一旦我們在 IntelliJ 中執行 Maven 目標clean
、 compile
、 package
和azure-functions:deploy
,它就會將應用程式部署到 Azure Function 中:
如果 Azure 訂閱中不存在 Function 服務,則該外掛程式將使用最新配置建立或更新它。有趣的是,除了 Function 之外, azure-functions
Maven 插件還創建了許多其他支援的基本雲端資源:
5. Azure Function SDK 的關鍵元件
在使用 Java 開發 Azure 函數時,我們主要處理註解來宣告觸發器和綁定。應用於函數的一些重要觸發器是@HttpTrigger
、 @BlobTrigger
、 @CosmosDBTrigger
、 @EventGridTrigger
、 @TimerTrigger
等。
輸入綁定註解,例如@BlobInput
、 @CosmosDBInput
、 [@TableInput](https://learn.microsoft.com/en-us/java/api/com.microsoft.azure.functions.annotation.tableinput?view=azure-java-stable)
等.
補充觸發器以幫助函數從事件來源存取資料。可以理解的是,我們可以將它們應用於函數的輸入參數。
另一方面,輸出綁定註解(例如@BlobOutput
、 @CosmosDBOutput
、 @TableOutput
等)應用於OutputBinding<T>
類型的函數參數。此外,它們還可協助將從來源接收的資料更新到目標系統,例如 Blob 儲存、Cosmos DB、儲存表等。
此外,我們可以使用某些接口,例如ExecutionContext
ExecutionContext
HttpRequestMessage<T>
、 HttpResponseMessage.Builder,
HttpResponseMessage<T>
、 OutputBinding
讓我們藉助下一節中的範例程式碼來了解這些元件。
6.Java實現
我們將使用 Azure Function 實作一些用例並了解該框架。同樣,我們稍後可以將相同的概念應用於本文中未討論的註釋。
6.1.將 HTTP 請求有效負載移至儲存表
讓我們建立一個函數,用於接收 HTTP 請求負載中的員工數據,然後更新employee
Azure 儲存表:
@FunctionName("addEmployee")
@StorageAccount("AZURE_STORAGE")
public HttpResponseMessage run(@HttpTrigger(name = "req", methods = { HttpMethod.POST }, route = "employee/{partitionKey}/{rowKey}",
authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage<Optional<Employee>> empRequest,
@BindingName("partitionKey") String partitionKey,
@BindingName("rowKey") String rowKey,
@TableOutput(name = "data", tableName = "employee") OutputBinding<Employee> employeeOutputBinding,
final ExecutionContext context) {
context.getLogger().info("Received a http request: " + empRequest.getBody().toString());
Employee employee = new Employee(empRequest.getBody().get().getName(),
empRequest.getBody().get().getDepartment(),
empRequest.getBody().get().getSex(),
partitionKey, rowKey);
employeeOutputBinding.setValue(employee);
return empRequest.createResponseBuilder(HttpStatus.OK)
.body("Employee Inserted")
.build();
}
客戶端程式可以透過在 API 端點https://{Azure Function URL}/api/employee/{partitionKey}/{rowKey}
提交 POST HTTP 請求來觸發此函數。 code={function access key}
.請求內文應包含 JSON 格式的員工資料。客戶端可以在partitionKey
和rowKey
URI路徑變數中傳送表記錄的分區和行鍵。 @BindingName
註解有助於綁定partitionKey
和rowKey
方法變數中的輸入路徑變數。
在該方法的主體中,我們從 HTTP 請求主體建立Employee
對象,然後將其設定為輸出綁定employeeOutputBinding
參數。我們在應用於方法參數employeeOutputBinding 的@TableOutput
註解的tableName
屬性中提供儲存表資訊employeeOutputBinding.
無需明確呼叫任何 API 即可將資料插入employee
表中。
@StorageAccount
註解在值 AZURE_ STORAGE
變數中指定employee
表的儲存帳戶的連接字串。我們可以將其作為運行時環境變數儲存在應用程式的設定中:
現在讓我們呼叫端點以在employee
表中插入一筆記錄:
此外,為了進行故障排除,我們可以檢查Azure入口網站中的函數日誌:
最後,JSON 資料被插入到 Azure 儲存體帳戶中的employee
表中:
6.2.將 Blob 資料移至 Cosmos DB
在前面的用例中,我們明確地呼叫了 HTTP 端點。不過,這次讓我們考慮一個在檔案上傳到 Blob Storage 時自動觸發函數的範例。然後,函數讀取資料並將其插入到 Cosmos DB 資料庫中:
@FunctionName("BlobTriggerJava")
@StorageAccount("AZURE_STORAGE")
public void run(
@BlobTrigger(name = "content", path = "feeds/{name}.csv", dataType = "binary") byte[] content,
@BindingName("name") String fileName,
@CosmosDBOutput(name = "output",
databaseName = "organization",
connection = "COSMOS_DB",
containerName = "employee") OutputBinding<List<Employee>> employeeOutputBinding,
final ExecutionContext context) {
context.getLogger().info("Java Blob trigger function processed a blob. Name: " + fileName + "\n Size: " + content.length + " Bytes");
employeeOutputBinding.setValue(getEmployeeList(content));
context.getLogger().info("Processing finished");
}
@BlobTrigger
註解的path
屬性有助於指定 Blob 儲存體中的檔案。此函數使用檔案的內容填入類型為OutputBinding<List<Employee>>
的參數employeeOutputBinding
。我們在@CosmosDBOutput
註釋中定義目標 Cosmos DB 詳細資訊。連接屬性的值COSMOS_DB
是 Azure 中函數應用程式設定中的環境變數。它包含目標資料庫的連接字串。
為了進行演示,我們將從 IntelliJ IDE 中將employee.csv
檔案上傳到儲存帳戶databasesas
下的 Blob 容器:
最後,呼叫該函數並將資料插入 Cosmos DB employee
容器中:
七、結論
在本文中,我們學習了 Azure Function 的 Java 程式設計模型。該框架設計良好且易於理解。但是,了解功能無法觸發或無法更新目標系統時的基本故障排除步驟非常重要。為此,我們必須學習 Azure Functions 的概念以及儲存帳戶、 Application Insight等補充服務。
與往常一樣,所使用的程式碼可以在 GitHub 上找到。