跳到主要内容

部署打包函数

DeepSeek V3 中英对照 Deploying a Packaged Function

Spring Cloud Function 提供了一个“部署器”库,允许你使用隔离的类加载器启动一个 jar 文件(或解压的归档文件,或一组 jar 文件),并暴露其中定义的函数。这是一个非常强大的工具,例如,它允许你在不更改目标 jar 文件的情况下,将函数适配到一系列不同的输入输出适配器中。无服务器平台通常内置了这种功能,因此你可以将其视为此类平台中函数调用器的构建块(事实上,Riff 的 Java 函数调用器使用了这个库)。

标准入口是将 spring-cloud-function-deployer 添加到类路径中,部署器会启动并查找一些配置,以告诉它在哪里可以找到函数 jar 包。

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-deployer</artifactId>
<version>${spring.cloud.function.version}</version>
</dependency>
xml

用户至少需要提供一个 spring.cloud.function.location,这是一个包含函数的归档文件的 URL 或资源位置。它可以选择性地使用 maven: 前缀来通过依赖查找定位工件(完整细节请参见 FunctionProperties)。Spring Boot 应用程序从 jar 文件启动,使用 MANIFEST.MF 来定位启动类,因此标准的 Spring Boot fat jar 可以很好地工作。如果目标 jar 可以成功启动,那么结果是一个注册在主应用程序的 FunctionCatalog 中的函数。注册的函数可以由主应用程序中的代码调用,即使它是在隔离的类加载器中创建的(默认情况下)。

以下是部署包含 uppercase 函数的 JAR 文件并调用它的示例。

@SpringBootApplication
public class DeployFunctionDemo {

public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DeployFunctionDemo.class,
"--spring.cloud.function.location=..../target/uppercase-0.0.1-SNAPSHOT.jar",
"--spring.cloud.function.definition=uppercase");

FunctionCatalog catalog = context.getBean(FunctionCatalog.class);
Function<String, String> function = catalog.lookup("uppercase");
System.out.println(function.apply("hello"));
}
}
java

以下是使用 Maven URI 的示例(取自 FunctionDeployerTests 中的一个测试):

@SpringBootApplication
public class DeployFunctionDemo {

public static void main(String[] args) {
String[] args = new String[] {
"--spring.cloud.function.location=maven://oz.demo:demo-uppercase:0.0.1-SNAPSHOT",
"--spring.cloud.function.function-class=oz.demo.uppercase.MyFunction" };

ApplicationContext context = SpringApplication.run(DeployerApplication.class, args);
FunctionCatalog catalog = context.getBean(FunctionCatalog.class);
Function<String, String> function = catalog.lookup("myFunction");

assertThat(function.apply("bob")).isEqualTo("BOB");
}
}
java

请注意,Maven 资源(如本地和远程仓库、用户、密码等)是使用默认的 MavenProperties 来解析的,这些属性有效地使用了本地默认值,并且在大多数情况下都能正常工作。然而,如果您需要自定义,可以简单地提供一个 MavenProperties 类型的 bean,在其中设置额外的属性(参见下面的示例)。

@Bean
public MavenProperties mavenProperties() {
MavenProperties properties = new MavenProperties();
properties.setLocalRepository("target/it/");
return properties;
}
java

支持的打包场景

目前,Spring Cloud Function 支持多种打包场景,以便在部署函数时提供最大的灵活性。

简单的 JAR

此打包选项意味着不依赖于任何与 Spring 相关的内容。例如:假设这样的 JAR 包含以下类:

. . .
public class UpperCaseFunction implements Function<String, String> {
@Override
public String apply(String value) {
return value.toUpperCase();
}
}
java

在部署此类包时,您只需指定 locationfunction-class 属性:

--spring.cloud.function.location=target/it/simplestjar/target/simplestjar-1.0.0.RELEASE.jar
--spring.cloud.function.function-class=function.example.UpperCaseFunction
none

在某些情况下,您可能希望将多个函数打包在一起。对于这种情况,您可以使用 spring.cloud.function.function-class 属性来列出多个类,并用 ; 分隔它们。

例如,

--spring.cloud.function.function-class=function.example.UpperCaseFunction;function.example.ReverseFunction
none

在这里,我们确定了两个要部署的函数,现在我们可以通过名称在函数目录中访问它们(例如,catalog.lookup("reverseFunction");)。

更多详细信息请参考完整的示例,该示例可在这里找到。您还可以在FunctionDeployerTests中找到相应的测试。

  • 组件扫描 *

从版本 3.1.4 开始,你可以通过 [[Function Component Scan]](#Function Component Scan) 中描述的组件扫描功能来简化配置。如果你将功能类放置在名为 functions 的包中,你可以省略 spring.cloud.function.function-class 属性,因为框架会自动发现功能类并将它们加载到功能目录中。请注意在进行功能查找时需要遵循的命名约定。例如,功能类 functions.UpperCaseFunction 将在 FunctionCatalog 中以名称 upperCaseFunction 提供。

Spring Boot JAR

这种打包选项意味着依赖于 Spring Boot,并且 JAR 是作为 Spring Boot JAR 生成的。也就是说,鉴于部署的 JAR 在隔离的类加载器中运行,不会与实际部署者使用的 Spring Boot 版本产生任何版本冲突。例如:假设此类 JAR 包含以下类(如果 Spring/Spring Boot 在类路径上,则可能具有一些额外的 Spring 依赖项):

. . .
public class UpperCaseFunction implements Function<String, String> {
@Override
public String apply(String value) {
return value.toUpperCase();
}
}
java

和之前一样,在部署此类包时,您只需要指定 locationfunction-class 属性即可:

--spring.cloud.function.location=target/it/simplestjar/target/simplestjar-1.0.0.RELEASE.jar
--spring.cloud.function.function-class=function.example.UpperCaseFunction
none

更多详情请参考这里提供的完整示例。您还可以在FunctionDeployerTests中找到相应的测试。

Spring Boot 应用

这种打包方式意味着你的 JAR 是一个完全独立的 Spring Boot 应用程序,其中的功能作为受管理的 Spring Bean。与之前一样,这里有一个明显的假设,即依赖于 Spring Boot,并且 JAR 是作为 Spring Boot JAR 生成的。也就是说,由于部署的 JAR 在隔离的类加载器中运行,因此不会与实际部署者使用的 Spring Boot 版本产生任何版本冲突。例如:假设这样的 JAR 包含以下类:

. . .
@SpringBootApplication
public class SimpleFunctionAppApplication {

public static void main(String[] args) {
SpringApplication.run(SimpleFunctionAppApplication.class, args);
}

@Bean
public Function<String, String> uppercase() {
return value -> value.toUpperCase();
}
}
java

鉴于我们实际上是在处理另一个 Spring 应用上下文,并且函数是 Spring 管理的 bean,除了 location 属性外,我们还指定了 definition 属性,而不是 function-class

--spring.cloud.function.location=target/it/bootapp/target/bootapp-1.0.0.RELEASE-exec.jar
--spring.cloud.function.definition=uppercase
none

更多详细信息请参考完整的示例,可在这里找到。你也可以在FunctionDeployerTests中找到相应的测试。

备注

此特定的部署选项可能在其类路径上包含或不包含 Spring Cloud Function。从部署者的角度来看,这并不重要。