Microsoft Azure Functions
适用于 Spring Cloud Function 应用程序作为本机 Azure Java 函数的 Azure 函数适配器。 Azure 函数编程模型广泛依赖 Java 注释,用于定义函数的处理程序方法及其输入和输出类型。在编译时,已提供 Azure Maven/Gradle 插件来处理带注释的类,以生成必要的 Azure 函数绑定文件、配置和包工件。Azure 注释只是一种类型安全的方式,用于将您的 Java 函数配置为被识别为 Azure 函数。 spring-cloud-function-adapter-azure 扩展了基本编程模型,以提供 Spring 和 Spring Cloud Function 支持。借助此适配器,您可以使用依赖注入功能构建 Spring Cloud Function 应用程序,然后将必要的服务自动注入 Azure 处理程序方法。 image::{github-raw}/docs/src/main/asciidoc/images/scf-azure-adapter.svg[]
对于基于 Web 的函数应用程序,您可以使用专门的 spring-cloud-function-adapter-azure-web 替换通用的 |
Azure Adapter
为 Azure 函数提供 Spring 和 Spring Cloud Function 集成。
Dependencies
为了启用 Azure 函数集成,请将 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'
}
|
Development Guidelines
使用 @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 ,如 main class configuration 中所述。 |
2 | 函数在 Azure 函数处理程序中自动关联并使用。 |
Function Catalog
Spring Cloud Function 支持一系列用户定义函数的类型签名,同时提供一致的执行模型。为此,它使用 Function Catalog 将所有用户定义的函数转换成规范表示形式。
Azure 适配器可以自动连接任何 Spring 组件,例如上面的 uppercase
。不过这些组件被视为普通 Java 类实例,而不是规范的 Spring Cloud Functions!
若要利用 Spring Cloud Function 并访问规范化的函数表示,您需要自动连接 FunctionCatalog
并将其用在处理程序中,例如上面 springCloudFunction()
处理程序中的 functionCatalog
实例。
Accessing Azure ExecutionContext
有时需要以 com.microsoft.azure.functions.ExecutionContext
的形式访问 Azure 运行时提供的目标执行上下文。例如,这些需求之一便是日志记录,以便在 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 实例。 |
Configuration
若要在 Microsoft Azure 上运行函数应用程序,您必须提供必要的配置,例如 function.json
和 host.json
,并遵照必需的格式打包。
通常,Azure Maven(或 Gradle)插件用于从带注释的类生成必要的配置并生成所需的 package 格式。
Azure packaging format 与默认的 Spring Boot 包装(例如 uber jar
)不兼容。下面的 Disable Spring Boot Plugin 部分说明如何处理此问题。
[[azure-maven/gradle-plugins]]=== Azure Maven/Gradle 插件
Azure 提供的 maven 及 gradle 插件用于处理带注释的类、生成必要的配置以及生成预期的 package 布局。插件用于设置平台、运行时和应用程序设置属性,如下所示:
-
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"
}
有关运行时配置的更多信息:Java 版本,部署的操作系统。
Disable Spring Boot Plugin
可以预料,Azure 函数在 Azure 执行运行时内部运行,而不是在 Spring Boot 运行时内部运行!此外,Azure 期望 Azure Maven/Gradle 插件生成的特定打包格式与默认的 Spring Boot 打包不兼容。
您必须禁用 Spring Boot Maven/Gradle 插件或按照以下 Maven 片段中的说明使用 Spring Boot Thin Launcher:
<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 Configuration
指定 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
变量,Azure 适配器将从在类路径上找到的 jar 中查找 MANIFEST/META-INFO
属性,并选择第一个通过 @SpringBootApplication
或 @SpringBootConfiguration
注释标记的 Main-Class:
。
Azure Web Adapter
对于纯粹基于 Web 的函数应用程序,您可以用专门的 spring-cloud-function-adapter-azure-web 替换通用的 adapter-azure
。Azure Web 适配器可以使用 HttpTrigger 在内部部署任何 Spring Web 应用程序作为本机 Azure 函数。它隐藏了 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'
}
相同的 Configuration 和 Usage 指令也适用于 Azure Web Adapter
。
Running locally
若要在 `Azure Functions`之上本地运行并部署到您的实时 Azure 环境,您需要安装 `Azure Functions Core Tools`以及 Azure CLI(见 here)。对于某些配置,您还需要 Azurite emulator。
然后运行示例:
-
Maven
-
Gradle
./mvnw azure-functions:run
./gradlew azureFunctionsRun
Running on Azure
确保您已登录您的 Azure 帐户。
az login
并部署
-
Maven
-
Gradle
./mvnw azure-functions:deploy
./gradlew azureFunctionsDeploy
Debug locally
在调试模式下运行函数。
-
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 (deprecated)
旧的 FunctionInvoker
编程模型已弃用,并且将来将不受支持。
有关函数集成方法的其他文档和示例,请按照 azure-sample中的自述文件和代码进行操作。