Microsoft Azure Functions
Azure 函数适配器,用于将 Spring Cloud Function 应用程序部署为原生 Azure Java 函数。
spring-cloud-function-adapter-azure 扩展了基本的编程模型,提供了 Spring 和 Spring Cloud Function 支持。借助该适配器,您可以使用依赖注入构建 Spring Cloud Function 应用程序,然后将必要的服务自动连接到您的 Azure 处理方法中。
对于基于 Web 的函数应用程序,您可以将通用的 adapter-azure 替换为专门的 spring-cloud-function-adapter-azure-web。使用 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 组件。然后,你可以自动装配所需的依赖项(或 Function Catalog 用于 Spring Cloud Function 组合),并在 Azure function 处理程序中使用它们。
@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());
}
}
表示
MyAzureFunction类是一个“组件”,Spring 框架会将其视为自动检测和类路径扫描的候选对象。自动装配在
HttpTriggerDemoApplication中定义的uppercase和functionCatalogbean(见下文)。@FunctionName 注解标识了指定的 Azure 函数处理器。当由触发器(如
@HttpTrigger)调用时,函数处理该触发器以及任何其他输入,以生成一个或多个输出。plainBean方法处理器映射到一个使用自动装配的uppercasespring bean 计算结果的 Azure 函数。它演示了如何在 Azure 处理器中使用“普通”的 Spring 组件。springCloudFunction方法处理器映射到另一个使用自动装配的FunctionCatalog实例计算结果的 Azure 函数。展示了如何利用 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();
}
}
用
@SpringBootApplication注解的类被用作Main-Class,如主类配置中所述。在 Azure 函数处理程序中自动装配和使用的函数。
函数目录
Spring Cloud Function 支持一系列用户定义函数的类型签名,同时提供了一致的执行模型。为此,它使用 Function Catalog 将所有用户定义的函数转换为规范表示。
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);
}
利用
AzureFunctionUtil工具将context作为消息头内联,使用AzureFunctionUtil.EXECUTION_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
. . .
}
}
从头部检索 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 执行运行时内运行,而不是在 Spring Boot 运行时内运行!此外,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 属性)。
示例
以下是一些你可以探索的 Spring Cloud Function Azure 适配器示例:
Azure Web 适配器
对于纯基于 Web 的函数应用程序,您可以将通用的 adapter-azure 替换为专门的 spring-cloud-function-adapter-azure-web。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'
}
Azure 示例
有关更多信息,请查阅以下内容,Azure Web 适配器示例:
用法
构建和部署 Azure Adapter 和 Azure Web Adapter 类型应用程序的通用指令。
构建
- Maven
- Gradle
./mvnw -U clean package
./gradlew azureFunctionsPackage
本地运行
要在 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 和代码。