Microsoft Azure Functions
Azure 函式介面卡,用於將 Spring Cloud Function 應用程式作為原生 Azure Java 函式部署。
Azure Functions 程式設計模型 大量依賴 Java 註解 來定義函式的處理方法及其輸入和輸出型別。在編譯時,Azure Maven/Gradle 外掛會處理帶註解的類,以生成必要的 Azure Function 繫結檔案、配置和打包工件。Azure 註解只是一種型別安全的方式,用於配置您的 Java 函式,使其被識別為 Azure 函式。
spring-cloud-function-adapter-azure 擴充套件了基本程式設計模型,以提供 Spring 和 Spring Cloud Function 支援。透過該介面卡,您可以使用依賴注入構建 Spring Cloud Function 應用程式,然後將必要的服務自動裝配到您的 Azure 處理方法中。
對於基於 Web 的函式應用程式,您可以用專門的 spring-cloud-function-adapter-azure-web 替換通用的 adapter-azure。使用 Azure Web 介面卡,您可以將任何 Spring Web 應用程式部署為 Azure HttpTrigger 函式。此介面卡隱藏了 Azure 註解的複雜性,而是使用熟悉的 Spring Web 程式設計模型。有關更多資訊,請參閱下面的 Azure Web 介面卡 部分。 |
Azure 介面卡
為 Azure Functions 提供 Spring 和 Spring Cloud Function 整合。
依賴項
為了啟用 Azure Function 整合,請將 Azure 介面卡依賴項新增到您的 pom.xml 或 build.gradle 檔案中
-
Maven
-
Gradle
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure</artifactId>
</dependency>
</dependencies>
dependencies {
implementation 'org.springframework.cloud:spring-cloud-function-adapter-azure'
}
需要 4.0.0+ 版本。類路徑中存在介面卡會啟用 Azure Java Worker 整合。 |
開發指南
使用 @Component (或 @Service) 註解將任何現有 Azure Function 類(例如,帶有 @FunctionName 處理程式)轉換為 Spring 元件。然後,您可以自動裝配所需的依賴項(或 函式目錄 以進行 Spring Cloud Function 組合),並在 Azure 函式處理程式中使用它們。
@Component (1)
public class MyAzureFunction {
// Plain Spring bean - not a Spring Cloud Functions!
@Autowired private Function<String, String> uppercase; (2)
// The FunctionCatalog leverages the Spring Cloud Function framework.
@Autowired private FunctionCatalog functionCatalog; (2)
@FunctionName("spring") (3)
public String plainBean( (4)
@HttpTrigger(name = "req",
methods = { HttpMethod.POST },
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
ExecutionContext context) {
return this.uppercase.apply(request.getBody().get());
}
@FunctionName("scf") (3)
public String springCloudFunction( (5)
@HttpTrigger(name = "req",
methods = { HttpMethod.POST },
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
ExecutionContext context) {
// Use SCF composition. Composed functions are not just spring beans but SCF such.
Function composed = this.functionCatalog.lookup("reverse|uppercase"); (6)
return (String) composed.apply(request.getBody().get());
}
}
| 1 | 表示 MyAzureFunction 類是一個“元件”,Spring Framework 會將其視為自動檢測和類路徑掃描的候選。 |
| 2 | 自動裝配在 HttpTriggerDemoApplication(下文)中定義的 uppercase 和 functionCatalog bean。 |
| 3 | @FunctionName 註解標識指定的 Azure 函式處理程式。當由觸發器(如 @HttpTrigger)呼叫時,函式會處理該觸發器以及任何其他輸入,以產生一個或多個輸出。 |
| 4 | plainBean 方法處理程式對映到使用自動裝配的 uppercase Spring bean 計算結果的 Azure 函式。它演示瞭如何在 Azure 處理程式中使用“普通”Spring 元件。 |
| 5 | springCloudFunction 方法處理程式對映到另一個 Azure 函式,該函式使用自動裝配的 FunctionCatalog 例項計算結果。 |
| 6 | 展示瞭如何利用 Spring Cloud Function 函式目錄 組合 API。 |
| 使用 com.microsoft.azure.functions.annotation.* 包中包含的 Java 註解將輸入和輸出繫結到您的方法。 |
Azure 處理程式內部使用的業務邏輯實現看起來像一個普通的 Spring 應用程式
@SpringBootApplication (1)
public class HttpTriggerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(HttpTriggerDemoApplication.class, args);
}
@Bean
public Function<String, String> uppercase() { (2)
return payload -> payload.toUpperCase();
}
@Bean
public Function<String, String> reverse() { (2)
return payload -> new StringBuilder(payload).reverse().toString();
}
}
| 1 | 帶 @SpringBootApplication 註解的類用作 Main-Class,如 主類配置 中所述。 |
| 2 | 在 Azure 函式處理程式中自動裝配和使用的函式。 |
函式目錄
Spring Cloud Function 支援使用者定義函式的各種型別簽名,同時提供一致的執行模型。為此,它使用 函式目錄 將所有使用者定義函式轉換為規範表示。
Azure 介面卡可以自動裝配任何 Spring 元件,例如上面的 uppercase。但是,這些元件被視為普通 Java 類例項,而不是規範的 Spring Cloud Functions!
要利用 Spring Cloud Function 並訪問規範函式表示,您需要自動裝配 FunctionCatalog 並在處理程式中使用它,就像上面的 springCloudFunction() 處理程式中的 functionCatalog 例項一樣。
訪問 Azure ExecutionContext
有時需要訪問 Azure 執行時提供的目標執行上下文,其形式為 com.microsoft.azure.functions.ExecutionContext。例如,其中一個需求是日誌記錄,以便它可以顯示在 Azure 控制檯中。
為此,AzureFunctionUtil.enhanceInputIfNecessary 允許您將 ExecutionContext 例項新增為訊息頭,以便您可以透過 executionContext 鍵檢索它。
@FunctionName("myfunction")
public String execute(
@HttpTrigger(name = "req",
methods = { HttpMethod.POST },
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
ExecutionContext context) {
Message message =
(Message) AzureFunctionUtil.enhanceInputIfNecessary(request.getBody().get(), context); (1)
return this.uppercase.apply(message);
}
| 1 | 利用 AzureFunctionUtil 工具,使用 AzureFunctionUtil.EXECUTION_CONTEXT 頭鍵將 context 內聯為訊息頭。 |
現在您可以從訊息頭中檢索 ExecutionContext
@Bean
public Function<Message<String>, String> uppercase(JsonMapper mapper) {
return message -> {
String value = message.getPayload();
ExecutionContext context =
(ExecutionContext) message.getHeaders().get(AzureFunctionUtil.EXECUTION_CONTEXT); (1)
. . .
}
}
| 1 | 從頭中檢索 ExecutionContext 例項。 |
配置
要在 Microsoft Azure 上執行您的函式應用程式,您必須提供必要的配置,例如 function.json 和 host.json,並遵守強制性的 打包格式。
通常,Azure Maven(或 Gradle)外掛用於從帶註解的類生成必要的配置並生成所需的包格式。
Azure 打包格式 與預設的 Spring Boot 打包(例如 uber jar)不相容。下面的 停用 Spring Boot 外掛 部分解釋瞭如何處理此問題。 |
Azure Maven/Gradle 外掛
-
Maven
-
Gradle
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<version>1.22.0 or higher</version>
<configuration>
<appName>YOUR-AZURE-FUNCTION-APP-NAME</appName>
<resourceGroup>YOUR-AZURE-FUNCTION-RESOURCE-GROUP</resourceGroup>
<region>YOUR-AZURE-FUNCTION-APP-REGION</region>
<appServicePlanName>YOUR-AZURE-FUNCTION-APP-SERVICE-PLANE-NAME</appServicePlanName>
<pricingTier>YOUR-AZURE-FUNCTION-PRICING-TIER</pricingTier>
<hostJson>${project.basedir}/src/main/resources/host.json</hostJson>
<runtime>
<os>linux</os>
<javaVersion>11</javaVersion>
</runtime>
<appSettings>
<property>
<name>FUNCTIONS_EXTENSION_VERSION</name>
<value>~4</value>
</property>
</appSettings>
</configuration>
<executions>
<execution>
<id>package-functions</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
plugins {
id "com.microsoft.azure.azurefunctions" version "1.11.0"
// ...
}
apply plugin: "com.microsoft.azure.azurefunctions"
azurefunctions {
appName = 'YOUR-AZURE-FUNCTION-APP-NAME'
resourceGroup = 'YOUR-AZURE-FUNCTION-RESOURCE-GROUP'
region = 'YOUR-AZURE-FUNCTION-APP-REGION'
appServicePlanName = 'YOUR-AZURE-FUNCTION-APP-SERVICE-PLANE-NAME'
pricingTier = 'YOUR-AZURE-FUNCTION-APP-SERVICE-PLANE-NAME'
runtime {
os = 'linux'
javaVersion = '11'
}
auth {
type = 'azure_cli'
}
appSettings {
FUNCTIONS_EXTENSION_VERSION = '~4'
}
// Uncomment to enable local debug
// localDebug = "transport=dt_socket,server=y,suspend=n,address=5005"
}
停用 Spring Boot 外掛
不出所料,Azure Functions 在 Azure 執行執行時中執行,而不是在 SpringBoot 執行時中執行!此外,Azure 期望由 Azure Maven/Gradle 外掛生成的特定打包格式,該格式與預設的 Spring Boot 打包不相容。
您必須停用 SpringBoot Maven/Gradle 外掛,或者使用 Spring Boot Thin Launcher,如以下 Maven 程式碼片段所示
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
</dependency>
</dependencies>
</plugin>
主類配置
指定 Main-Class/Start-Class 指向您的 Spring 應用程式入口點,例如上面示例中的 HttpTriggerDemoApplication 類。
您可以使用 Maven 的 start-class 屬性或設定 MANIFEST/META-INFO 的 Main-Class 屬性
-
Maven
-
Gradle
<properties>
<start-class>YOUR APP MAIN CLASS</start-class>
...
</properties>
jar {
manifest {
attributes(
"Main-Class": "YOUR-APP-MAIN-CLASS"
)
}
}
或者,您可以使用 MAIN_CLASS 環境變數明確設定類名。對於本地執行,將 MAIN_CLASS 變數新增到您的 local.settings.json 檔案中;對於 Azure 門戶部署,在 應用程式設定 中設定該變數。 |
如果未設定 MAIN_CLASS 變數,Azure 介面卡將查詢類路徑上找到的 JAR 包中的 MANIFEST/META-INFO 屬性,並選擇第一個帶有 @SpringBootApplication 或 @SpringBootConfiguration 註解的 Main-Class:。 |
元資料配置
您可以使用共享的 host.json 檔案來配置函式應用。
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
host.json 元資料檔案包含影響函式應用程式例項中所有函式的配置選項。
如果檔案不在專案頂層資料夾中,您需要相應地配置您的外掛(例如 hostJson maven 屬性)。 |
Azure Web 介面卡
對於純粹基於 Web 的函式應用程式,您可以用專門的 spring-cloud-function-adapter-azure-web 替換通用的 adapter-azure。Azure Web 介面卡可以將任何 Spring Web 應用程式作為原生 Azure 函式部署,內部使用 HttpTrigger。它隱藏了 Azure 註解的複雜性,並依賴於熟悉的 Spring Web 程式設計模型。
要啟用 Azure Web 介面卡,請將介面卡依賴項新增到您的 pom.xml 或 build.gradle 檔案中
-
Maven
-
Gradle
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure-web</artifactId>
</dependency>
</dependencies>
dependencies {
implementation 'org.springframework.cloud:spring-cloud-function-adapter-azure-web'
}
本地執行
要在 Azure Functions 上本地執行,並部署到您的即時 Azure 環境,您需要安裝 Azure Functions Core Tools 以及 Azure CLI(請參閱 此處)。對於某些配置,您還需要 Azurite 模擬器。
然後執行示例
-
Maven
-
Gradle
./mvnw azure-functions:run
./gradlew azureFunctionsRun
在 Azure 上執行
確保您已登入您的 Azure 帳戶。
az login
並部署
-
Maven
-
Gradle
./mvnw azure-functions:deploy
./gradlew azureFunctionsDeploy
本地除錯
以除錯模式執行函式。
-
Maven
-
Gradle
./mvnw azure-functions:run -DenableDebug
// If you want to debug your functions, please add the following line
// to the azurefunctions section of your build.gradle.
azurefunctions {
...
localDebug = "transport=dt_socket,server=y,suspend=n,address=5005"
}
或者,將 JAVA_OPTS 值新增到您的 local.settings.json,如下所示
{
"IsEncrypted": false,
"Values": {
...
"FUNCTIONS_WORKER_RUNTIME": "java",
"JAVA_OPTS": "-Djava.net.preferIPv4Stack=true -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=127.0.0.1:5005"
}
}
這是一個 VSCode 遠端除錯配置的程式碼片段
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Attach to Remote Program",
"request": "attach",
"hostName": "localhost",
"port": "5005"
},
]
}
FunctionInvoker (已棄用)
傳統的 FunctionInvoker 程式設計模型已棄用,將來將不再支援。 |
有關函式整合方法的更多文件和示例,請參閱 azure-sample README 和程式碼。