对于最新稳定版本,请使用 spring-cloud-function 5.0.0spring-doc.cadn.net.cn

AWS Lambda

AWS适配器会将Spring Cloud Function应用转换成可以在AWS Lambda中运行的表单。spring-doc.cadn.net.cn

关于如何使用AWS Lambda的细节不在本文档的讨论范围内,因此用户应有一定的了解 AWS和AWS Lambda,想了解Spring带来的额外价值。spring-doc.cadn.net.cn

开始

Spring Cloud Function 框架的一个目标是提供必要的基础设施元素,使简单的函数应用能够在特定环境中以特定方式交互。 简单函数应用(上下文或 Spring 中)是指包含 Supplier、Function 或 Consumer 类型的 beans 的应用程序。 所以,对于AWS来说,这意味着一个简单的函数豆应该能在AWS Lambda环境中被识别并执行。spring-doc.cadn.net.cn

让我们来看这个例子:spring-doc.cadn.net.cn

@SpringBootApplication
public class FunctionConfiguration {

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

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

它展示了一个完整的 Spring Boot 应用程序,里面定义了一个函数 bean。有趣的是,表面上看这只是 另一个启动应用,但在 AWS 适配器的语境下,它也是一个完全有效的 AWS Lambda 应用。没有其他代码或配置 是必需的。你只需要打包和部署它,让我们看看如何实现这一点。spring-doc.cadn.net.cn

为了简化流程,我们提供了一个可以构建和部署的示例项目,你可以在这里访问。spring-doc.cadn.net.cn

你只需要执行./mvnw 清洁封装生成JAR文件。所有必要的 Maven 插件都已经设置好,可以生成 合适的AWS可部署JAR文件。(你可以在JAR布局笔记中阅读更多关于JAR布局的细节。)spring-doc.cadn.net.cn

然后你必须通过AWS仪表盘或AWS的CLI将JAR文件上传到AWS。spring-doc.cadn.net.cn

当被问及处理者时,你会具体说明org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest这是一个通用的请求处理程序。spring-doc.cadn.net.cn

AWS 部署

就这些。保存并执行函数,并使用一些样本数据,对于该函数,这些数据预期为 字符串,函数大写并返回。spring-doc.cadn.net.cn

org.springframework.cloud.function.adapter.aws.FunctionInvoker是一种通用AWS请求处理员实施目标是 这样可以让你远离AWS Lambda API的具体细节,在某些情况下,你可能需要具体说明是哪些AWS请求处理员你想要 用来使用。下一部分将为你解释如何实现这一点。spring-doc.cadn.net.cn

AWS 请求处理程序

而AWS Lambda则允许你实现各种功能请求处理者使用 Spring Cloud 函数时,你不需要实现任何功能,而是使用提供的org.springframework.cloud.function.adapter.aws.FunctionInvoker即 AWS 的实现请求流处理程序. 用户只需在 AWS 仪表盘上指定为“处理程序”来部署函数即可。 它能处理大部分案件,包括Kinesis、流媒体流等。spring-doc.cadn.net.cn

如果你的应用有多个@Bean类型功能等等,然后你可以通过配置来选择要用的那个spring.cloud.function.definition属性或环境变量。这些函数是从春云中提取的功能目录.如果你没有具体说明spring.cloud.function.definition框架会尝试按照搜索顺序找到默认值,先搜索功能然后消费者最后提供商).spring-doc.cadn.net.cn

类型转换

Spring Cloud 函数将尝试透明地处理原始文件之间的类型转换 输入流和类型由你的函数声明。spring-doc.cadn.net.cn

例如,如果你的函数签名是这样功能<福,酒吧>我们将尝试皈依 输入流事件到某个实例.spring-doc.cadn.net.cn

在事件类型未知或无法确定的情况下(例如,功能<?, ?>我们将尝试 将接收流事件转换为通用事件地图.spring-doc.cadn.net.cn

原始输入

有时候你可能想访问原始输入。在这种情况下,你只需要申报你的 函数签名接受输入流.例如Function<InputStream, ?>.在这种情况下 我们不会尝试任何转换,而是直接将原始输入传递给函数。spring-doc.cadn.net.cn

AWS 功能路由

Spring Cloud Function 的核心功能之一是路由功能——能够根据用户提供的路由指令,将一个特殊功能委托给其他功能。spring-doc.cadn.net.cn

在 AWS Lambda 环境中,这个功能还有一个额外好处,因为它允许你绑定一个函数(路由功能) 作为AWS Lambda,因此API网关的单一HTTP端点。所以最终你只管理一个函数和一个端点,同时还能受益 这些功能可以成为你应用的一部分。spring-doc.cadn.net.cn

更多细节可见所提供的样本, 但有几点通用性值得一提。spring-doc.cadn.net.cn

当你的应用中存在多个功能时,路由功能默认会被启用,如下org.springframework.cloud.function.adapter.aws.FunctionInvoker无法确定将哪个函数绑定为 AWS Lambda,因此默认为路由函数. 这意味着你只需要提供路由指令,这些指令可以通过多种机制实现(详见示例)。spring-doc.cadn.net.cn

另外,要注意因为AWS不允许点.在环境变量名称中加上连字符“-”,你可以利用启动支持,只需替换 带下划线的点和骆驼格的连字符。比如说spring.cloud.function.definition成为spring_cloud_function_definitionSpring.cloud.function.routing-expression成为spring_cloud_function_routingExpression.spring-doc.cadn.net.cn

自定义运行时

你还可以利用AWS Lambda的自定义运行时功能 而 Spring Cloud Function 提供了所有必要的组件,使作变得简单。spring-doc.cadn.net.cn

从代码角度看,这个应用应该和其他 Spring Cloud Function 应用没有区别。 你唯一需要做的就是提供启动在运行 Spring Boot 应用的 zip/jar 根节点里的脚本。 在 AWS 创建函数时选择“自定义运行时”。 这里有一个示例“bootstrap”文件:spring-doc.cadn.net.cn

#!/bin/sh

cd ${LAMBDA_TASK_ROOT:-.}

java -Dspring.main.web-application-type=none -Dspring.jmx.enabled=false \
  -noverify -XX:TieredStopAtLevel=1 -Xss256K -XX:MaxMetaspaceSize=128M \
  -Djava.security.egd=file:/dev/./urandom \
  -cp .:`echo lib/*.jar | tr ' ' :` com.example.LambdaApplication

com.example.LambdaApplication代表包含函数豆的应用。spring-doc.cadn.net.cn

在AWS中将处理程序名设置为函数名称。你也可以在这里使用函数复合(例如,大写|反写). 大致就是这样。一旦你把zip/jar文件上传到AWS,函数就会在自定义运行时运行。 我们还提供了一个示例项目,你还可以看到如何配置你的POM以正确生成压缩包。spring-doc.cadn.net.cn

函数式 bean 定义风格同样适用于自定义运行时,且 比@Bean风格。自定义运行时的启动速度甚至比功能性豆实现快得多 Java lambda 的 Lambda 主要取决于运行时需要加载多少类。 Spring在这里作用不大,所以你可以通过函数中只使用原类型来减少冷启动时间,比如, 而且不做任何定制工作@PostConstruct初始化器。spring-doc.cadn.net.cn

AWS函数路由与自定义运行时

使用自定义运行时函数时,路由也是同样的。你只需要具体说明函数路由就像你用函数名称作为handler一样,作为AWS Handler。spring-doc.cadn.net.cn

部署容器镜像

自定义运行时还负责处理容器镜像的部署。 在部署容器镜像时,类似于此处描述的方式,这一点非常重要 记得设置环境变量DEFAULT_HANDLER并附上函数名称。spring-doc.cadn.net.cn

例如,对于函数豆,如下所示DEFAULT_HANDLER值为readMessageFromSQS.spring-doc.cadn.net.cn

@Bean
public Consumer<Message<SQSMessageEvent>> readMessageFromSQS() {
	return incomingMessage -> {..}
}

此外,务必确保spring_cloud_function_web_export_enabled也设置为false.默认是的。spring-doc.cadn.net.cn

JAR布局说明

在 Lambda 运行时你不需要 Spring Cloud Function Web 或 Stream 适配器,所以你可能会 在创建发送给AWS的JAR之前,需要排除这些。Lambda应用必须是 有着色,但Spring Boot的独立应用没有,所以你可以用两个版本运行同一个应用 分开罐子(根据 Samples)。示例应用创建了两个jar文件,其中一个包含AWS用于在 Lambda 中部署的分类器,以及一个可执行的(薄)jar,包含Spring-cloud-function-web在运行时。Spring Cloud 函数会尝试从JAR文件中帮你找到一个“主类” 显现,使用起始级属性(该属性将由Spring靴添加 如果你用起始父节点,就是工具)。如果没有起始级在你的清单里你可以 使用环境变量或系统属性MAIN_CLASS当你将该函数部署到 AWS 时。spring-doc.cadn.net.cn

如果你没有使用功能豆定义,而是依赖 Spring Boot 的自动配置, 并且不依赖于Spring靴启动父, 然后,在 Maven-Shade-plugin 执行中还需配置额外的变换器。spring-doc.cadn.net.cn

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-shade-plugin</artifactId>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<version>2.7.4</version>
		</dependency>
	</dependencies>
	<executions>
		<execution>
			<goals>
			     <goal>shade</goal>
			</goals>
			<configuration>
				<createDependencyReducedPom>false</createDependencyReducedPom>
				<shadedArtifactAttached>true</shadedArtifactAttached>
				<shadedClassifierName>aws</shadedClassifierName>
				<transformers>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring.handlers</resource>
					</transformer>
					<transformer implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
						<resource>META-INF/spring.factories</resource>
					</transformer>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports</resource>
					</transformer>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports</resource>
					</transformer>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring.schemas</resource>
					</transformer>
					<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
						<resource>META-INF/spring.components</resource>
					</transformer>
				</transformers>
			</configuration>
		</execution>
	</executions>
</plugin>

构建文件设置

为了在AWS Lambda上运行Spring Cloud Function应用,你可以利用Maven或Gradle 由云平台提供商提供的插件。spring-doc.cadn.net.cn

梅文

要使用 Maven 的适配器插件,请将插件依赖添加到你的pom.xml文件:spring-doc.cadn.net.cn

<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-function-adapter-aws</artifactId>
	</dependency>
</dependencies>

正如JAR布局笔记中指出的,上传时需要一个带阴影的罐子 转给AWS Lambda。你可以用Maven Shade插件来实现这个功能。 设置示例可见上方。spring-doc.cadn.net.cn

你可以用 Spring Boot Maven 插件生成薄罐子。spring-doc.cadn.net.cn

<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>
			<version>${wrapper.version}</version>
		</dependency>
	</dependencies>
</plugin>

你可以找到完整的样本pom.xml用于部署 Spring Cloud 函数的文件 这里是用 Maven 向 AWS Lambda 应用的应用。spring-doc.cadn.net.cn

格拉德勒

为了使用 Gradle 的适配器插件,请将依赖添加到你的build.gradle文件:spring-doc.cadn.net.cn

dependencies {
	compile("org.springframework.cloud:spring-cloud-function-adapter-aws:${version}")
}

正如JAR布局笔记中指出的,上传时需要一个带阴影的罐子 转给AWS Lambda。你可以用Gradle Shadow插件来实现这个功能:spring-doc.cadn.net.cn

你可以使用 Spring Boot Gradle 插件和 Spring Boot Thin Gradle 插件来生成 那个薄罐子。spring-doc.cadn.net.cn

以下是完整的gradle文件spring-doc.cadn.net.cn

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.2.0-M2'
	id 'io.spring.dependency-management' version '1.1.3'
	id 'com.github.johnrengelman.shadow' version '8.1.1'
	id 'maven-publish'
	id 'org.springframework.boot.experimental.thin-launcher' version "1.0.31.RELEASE"
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

repositories {
	mavenCentral()
	mavenLocal()
	maven { url 'https://repo.spring.io/milestone' }
}

ext {
	set('springCloudVersion', "2023.0.0-M1")
}

assemble.dependsOn = [thinJar, shadowJar]

publishing {
	publications {
		maven(MavenPublication) {
			from components.java
			versionMapping {
				usage('java-api') {
					fromResolutionOf('runtimeClasspath')
				}
				usage('java-runtime') {
					fromResolutionResult()
				}
			}
		}
	}
}

shadowJar.mustRunAfter thinJar


import com.github.jengelman.gradle.plugins.shadow.transformers.*

shadowJar {
	archiveClassifier = 'aws'
	manifest {
    	inheritFrom(project.tasks.thinJar.manifest)
  	}
  	// Required for Spring
	mergeServiceFiles()
	append 'META-INF/spring.handlers'
	append 'META-INF/spring.schemas'
	append 'META-INF/spring.tooling'
	append 'META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports'
	append 'META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports'
	transform(PropertiesFileTransformer) {
		paths = ['META-INF/spring.factories']
		mergeStrategy = "append"
	}
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'
	implementation 'org.springframework.cloud:spring-cloud-function-adapter-aws'
	implementation 'org.springframework.cloud:spring-cloud-function-context'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}

tasks.named('test') {
	useJUnitPlatform()
}

你可以找到完整的样本build.gradle用于部署 Spring Cloud 函数的文件 这里有应用程序可以下载到 AWS Lambda with Gradle。spring-doc.cadn.net.cn