Microsoft Azure Functions
Azure 函式配接器,用於部署 Spring Cloud Function
應用程式作為原生 Azure Java Functions。
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 的函式應用程式,您可以將通用 adapter-azure 替換為專用的 spring-cloud-function-adapter-azure-web。使用 Azure Web Adapter,您可以將任何 Spring Web 應用程式部署為 Azure HttpTrigger 函式。此配接器隱藏了 Azure 註解的複雜性,並改為使用熟悉的 Spring Web 程式設計模型。如需更多資訊,請參閱下方的 Azure Web Adapter 章節。 |
Azure Adapter
為 Azure Functions 提供 Spring
和 Spring Cloud Function
整合。
相依性
為了啟用 Azure Function 整合,請將 azure adapter 相依性新增至您的 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 組成的 Function Catalog),並在 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 方法處理常式會對應到一個 Azure 函式,該函式使用自動注入的 uppercase Spring Bean 來計算結果。它示範如何在您的 Azure 處理常式中使用「純」Spring 元件。 |
5 | springCloudFunction 方法處理常式會對應到另一個 Azure 函式,該函式使用自動注入的 FunctionCatalog 實例來計算結果。 |
6 | 示範如何利用 Spring Cloud Function Function Catalog 組成 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 函式處理常式中自動注入和使用的函式。 |
Function Catalog
Spring Cloud Function 支援使用者定義函式的各種型別簽章,同時提供一致的執行模型。為此,它使用 Function Catalog 將所有使用者定義的函式轉換為標準表示法。
Azure 配接器可以自動注入任何 Spring 元件,例如上面的 uppercase
。但這些元件被視為純 Java 類別實例,而不是標準 Spring Cloud Functions!
若要利用 Spring Cloud Function 並存取標準函式表示法,您需要自動注入 FunctionCatalog
,並在您的處理常式中使用它,就像 functionCatalog
實例在上面的 springCloudFunction()
處理常式中所做的那樣。
存取 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-plugins]] === 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 Adapter
對於純粹基於 Web 的函式應用程式,您可以將通用 adapter-azure
替換為專用的 spring-cloud-function-adapter-azure-web。Azure Web Adapter 可以使用 HttpTrigger 在內部將任何 Spring Web 應用程式部署為原生 Azure 函式。它隱藏了 Azure 註解的複雜性,並改為依賴熟悉的 Spring Web 程式設計模型。
若要啟用 Azure Web Adapter,請將配接器相依性新增至您的 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 和程式碼。