在 Spring Cloud for AWS Lambda 中使用功能 Bean 定义的多个函数

Multiple Functions using Functional Bean Definition in Spring Cloud for AWS Lambda

我正在尝试创建一个 Spring Cloud Function 应用程序,其中定义了多个函数。我需要使用 Functional Bean 定义方法来减少冷启动时间。该 jar 将部署在 AWS Lambda 中。

代码在本地环境中工作,我能够为所有定义的函数卷曲。但是,当部署在 Lambda 中时,该函数未被 AWS 定位。

代码在 Lambda 上运行并按预期工作,如果只定义了 1 个函数。

我会在下面提到我尝试过的东西。

  1. 按照Spring Doc创建项目
  2. 这在本地运行良好,也可以在带有处理程序的 Lambda 中运行 org.springframework.cloud.function.adapter.aws.SpringBootStreamHandler::handleRequest 根据 Thannasi 在 mydeveloperplanet blog post
  3. 上的评论
  4. 接下来我又添加了几个函数并将它们注册到 Generic ApplicationContext
@SpringBootConfiguration
public class Multi_FunctionalBean1Application implements ApplicationContextInitializer<GenericApplicationContext> {
            
                public static void main(String[] args) {
                    FunctionalSpringApplication.run(Multi_FunctionalBean1Application.class, args);
                }
            
                public Function<String, Boolean> containsCloud() {
                    return value -> {
                        System.out.println("Value is " + value);
                        return value.contains("cloud");
                    };
                }
            
                public Function<String, String> lowercase() {
                    return String::toLowerCase;
                }
            
                public Function<String, String> uppercase() {
                    return String::toUpperCase;
                }
            
                @Override
                public void initialize(GenericApplicationContext context) {
                    context.registerBean("containsCloud", FunctionRegistration.class,
                            () -> new FunctionRegistration<>(containsCloud())
                                    .type(FunctionType.from(String.class).to(Boolean.class)));
            
                    context.registerBean("uppercase", FunctionRegistration.class,
                            () -> new FunctionRegistration<>(uppercase()).type(FunctionType.from(String.class).to(String.class)));
                    context.registerBean("lowercase", FunctionRegistration.class,
                            () -> new FunctionRegistration<>(lowercase()).type(FunctionType.from(String.class).to(String.class)));
                    context.registerBean("getLength", FunctionRegistration.class,
                            () -> new FunctionRegistration<>(AnotherDemoFunction.getLength())
                                    .type(FunctionType.from(String.class).to(String.class)));
                    context.registerBean("getSquare", FunctionRegistration.class,
                            () -> new FunctionRegistration<>(DemoFunction.getSquare())
                                    .type(FunctionType.from(Integer.class).to(Double.class)));
                }
            }
  1. 这在本地运行良好,我可以单独调用所有功能,例如。 localhost:8083/lowercase -d ":SFDLKLs is A "localhost:8083/getSquare -d 2
  2. 我在 Lambda 上试过 运行 这个,但我得到了异常 Failed to locate function. Tried locating default function, function by '_HANDLER' env variable as well as'spring.cloud.function.definition。我使用了与以前相同的处理函数。此外还为环境变量 spring_cloud_function_definition 提供了其中一个函数名称作为值
  3. 我也尝试过将处理函数更改为 org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest。但是它给出了缺少 FunctionCatalog
  4. 的例外

以下是我的依赖项和构建插件。 spring-boot-starter-parent 版本为 2.5.4

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        
        <!-- Required only during build phase for spring tests to pass and local run-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-function-webflux</artifactId>
            <version>3.0.10.RELEASE</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Basic Spring Cloud Function dependency -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-context</artifactId>
            <version>3.1.3</version>
        </dependency>


        <!-- AWS Specific dependency for deployment in Lambda -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-adapter-aws</artifactId>
            <version>3.1.2</version>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.2.1</version>
        </dependency>

        <!-- Required for reading the AWS Lambda Request/Response event in Proxy 
            Mode -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-events</artifactId>
            <version>3.9.0</version>
        </dependency>
    </dependencies>

    <!-- Created Shaded and Thin jars -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <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>1.0.27.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                    <shadedArtifactAttached>true</shadedArtifactAttached>
                    <shadedClassifierName>aws</shadedClassifierName>
                </configuration>
            </plugin>
        </plugins>
    </build>

在 Spring AWS Lambda 的 Cloud Functional Bean Definition

中是否有任何其他方法可以拥有多个函数

在 Oleg 的评论的帮助下,我能够在 AWS Lambda 上使用 Functional Bean 定义实现多个功能。

所做的更改如下

  1. 清空主要方法
public static void main(String[] args) {
            //FunctionalSpringApplication.run(Multi_FunctionalBean1Application.class, args);
    
}
  1. 删除了 function-webflux 依赖并添加了 function-web。将所有 spring 云函数依赖项升级到 3.2.0-SNAPSHOT。更新了下面的 pom
<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>11</java.version>
        <wrapper.version>1.0.27.RELEASE</wrapper.version>
        <aws-lambda-events.version>3.9.0</aws-lambda-events.version>
        <spring-cloud-function.version>3.2.0-SNAPSHOT</spring-cloud-function.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-web</artifactId>
        </dependency>


        <!-- AWS Specific dependency for deployment in Lambda -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-adapter-aws</artifactId>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.2.1</version>
            <scope>provided</scope>
        </dependency>

        <!-- Required for reading the AWS Lambda Request/Response event in Proxy 
            Mode -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-events</artifactId>
            <version>3.9.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.json/json -->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20210307</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.vaadin.external.google</groupId>
                    <artifactId>android-json</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-function-dependencies</artifactId>
                <version>${spring-cloud-function.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- Created Shaded and Thin jars -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <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>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                    <shadedArtifactAttached>true</shadedArtifactAttached>
                    <shadedClassifierName>aws</shadedClassifierName>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
  1. 将 AWS Lambda 中的处理函数更改为

org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest

  1. 对于 运行 任何特定函数,使用环境变量 spring_cloud_function_definition 以函数名称作为值或类似 func1|func2|func3
  2. 的组合