Microsoft Azure Functions
用於將 Spring Cloud Function
應用部署為原生 Azure Java Functions 的 Azure 函式介面卡。
Azure Functions 程式設計模型廣泛依賴 Java 註解來定義函式的處理方法及其輸入和輸出型別。在編譯時,提供的 Azure Maven/Gradle 外掛會處理帶註解的類,以生成必要的 Azure Function 繫結檔案、配置和打包 artifacts。Azure 註解只是一種型別安全的方式,用於配置您的 Java 函式使其被識別為 Azure 函式。
spring-cloud-function-adapter-azure 擴充套件了基本程式設計模型,以提供對 Spring 和 Spring Cloud Function 的支援。透過此介面卡,您可以使用依賴注入構建您的 Spring Cloud Function 應用,然後將必要的服務自動裝配到您的 Azure handler 方法中。
對於基於 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+ 。在 classpath 中包含此介面卡會啟用 Azure Java Worker 整合。 |
開發指南
使用 @Component
(或 @Service
)註解將任何現有 Azure Function 類(例如帶有 @FunctionName
handler)轉換為 Spring 元件。然後,您可以自動裝配所需的依賴項(或 Spring Cloud Function 組合的Function Catalog),並在 Azure 函式 handler 中使用它們。
@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 在自動檢測和 classpath 掃描時考慮的“元件”。 |
2 | 自動裝配 HttpTriggerDemoApplication (如下所示)中定義的 uppercase 和 functionCatalog bean。 |
3 | @FunctionName 註解標識指定的 Azure 函式 handler。當由 trigger(例如 @HttpTrigger )呼叫時,函式會處理該 trigger 以及任何其他輸入,以產生一個或多個輸出。 |
4 | plainBean 方法 handler 對映到一個 Azure 函式,該函式使用自動裝配的 uppercase Spring bean 計算結果。這演示瞭如何在 Azure handler 中使用“普通”Spring 元件。 |
5 | springCloudFunction 方法 handler 對映到另一個 Azure 函式,該函式使用自動裝配的 FunctionCatalog 例項計算結果。 |
6 | 展示瞭如何利用 Spring Cloud Function Function Catalog 組合 API。 |
使用 com.microsoft.azure.functions.annotation.* 包中包含的 Java 註解來將輸入和輸出繫結到您的方法。 |
Azure handler 中使用的業務邏輯實現看起來像一個普通的 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 函式 handler 中自動裝配和使用的函式。 |
Function Catalog
Spring Cloud Function 支援各種使用者定義函式的型別簽名,同時提供一致的執行模型。為此,它使用 Function Catalog 將所有使用者定義函式轉換為規範表示。
Azure 介面卡可以自動裝配任何 Spring 元件,例如上面提到的 uppercase
。但它們被視為普通的 Java 類例項,而不是規範的 Spring Cloud Functions!
要利用 Spring Cloud Function 並訪問規範函式表示,您需要在 handler 中自動裝配 FunctionCatalog
並使用它,就像上面 springCloudFunction()
handler 中的 functionCatalog
例項一樣。
訪問 Azure ExecutionContext
有時需要訪問 Azure 執行時提供的目標執行上下文,其形式為 com.microsoft.azure.functions.ExecutionContext
。例如,其中一個需求是日誌記錄,以便它能顯示在 Azure 控制檯中。
為此,AzureFunctionUtil.enhanceInputIfNecessary
允許您將 ExecutionContext
例項新增為 Message header,以便您可以透過 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 header 鍵將 context 內聯為 message header。 |
現在您可以從 message header 中檢索 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 | 從 header 中檢索 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 配置
指定 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 介面卡將查詢 classpath 中找到的 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 介面卡可以作為原生 Azure 函式部署任何 Spring Web 應用,內部使用 HttpTrigger。它隱藏了 Azure 註解的複雜性,而是依賴於熟悉的 Spring Web 程式設計模型。更多資訊請參閱下面的 Azure 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 和程式碼。