我可能需要一些帮助...
我正在使用Spring Cloud Function,我想使用适用于AWS的适配器在AWS Lambda上部署我的功能。
我的应用程序类如下:
package example;
@SpringBootApplication
public class SpringCloudFunctionApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudFunctionApiGatewayApplication.class, args);
}
}
功能1如下所示:
package example;
@Component
public class StoreFunction implements Consumer<Message<DemoEntity>>{
@Override
public void accept(Message<DemoEntity> t) {
System.out.println("Stored entity " + ((DemoEntity)t.getPayload()).getName());
return;
}
}
最后,我的函数处理程序如下所示:
package example;
public class TestFunctionHandler extends SpringBootApiGatewayRequestHandler {
}
此设置可完美运行。 部署到Lambda时,我在AWS控制台中提供 example.TestFunctionHandler 作为处理程序,并且Spring Cloud自动识别 example.QueryFunction 是上下文中的唯一函数。>
日志输出如下:
START RequestId: 3bd996e7-ef5e-11e8-9829-1f50e2b93b6c Version: $LATEST
20:27:45.821 [main] INFO org.springframework.cloud.function.adapter.aws.SpringFunctionInitializer - Initializing: class de.margul.awstutorials.springcloudfunction.apigateway.SpringCloudFunctionApiGatewayApplication
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::
2018-11-23 20:27:48.221 INFO 1 --- [ main] lambdainternal.LambdaRTEntry : Starting LambdaRTEntry on ip-10-153-127-174.ec2.internal with PID 1 (/var/runtime/lib/LambdaJavaRTEntry-1.0.jar started by sbx_user1060 in /)
2018-11-23 20:27:48.242 INFO 1 --- [ main] lambdainternal.LambdaRTEntry : No active profile set, falling back to default profiles: default
2018-11-23 20:27:52.081 INFO 1 --- [ main] lambdainternal.LambdaRTEntry : Started LambdaRTEntry in 5.941 seconds (JVM running for 7.429)
Stored entity John Doe
END RequestId: 3bd996e7-ef5e-11e8-9829-1f50e2b93b6c
REPORT RequestId: 3bd996e7-ef5e-11e8-9829-1f50e2b93b6c Duration: 7113.98 ms Billed Duration: 7200 ms Memory Size: 1088 MB Max Memory Used: 113 MB
现在,我的问题来了。 我想在一个项目中具有多种功能。 我知道,在Lambda上,每个部署只能有一个功能。 但是,出于代码维护的原因(实际项目中有一些共享的代码以及配置),我们希望在一个项目中拥有所有功能,多次部署该项目,并在部署中进行定义,这是相关功能。
使用适用于Lambda的本机AWS开发工具包很容易(例如4.2节中的in this example): RequestStreamHandler 的一种实现,具有多种方法(即使 RequestStreamHandler 只有一个 handleRequest()方法)。 关键是可以将相关函数定义为处理程序: package.ClassName :: methodName
但是,这不适用于Spring Cloud Function(因为我们只能有一个处理程序,在这种情况下为 TestFunctionHandler )。 The documentations mentions可以通过在 application.properties 中指定 function.name 或作为Lambda环境变量 FUNCTION_NAME 来实现多种功能。 无论如何,我无法正常工作。
我的功能2如下:
package example;
@Component
public class QueryFunction implements Function<Message<String>, Message<DemoEntity>>{
@Override
public Message<DemoEntity> apply(Message<String> m) {
String name = m.getPayload();
DemoEntity response = new DemoEntity();
response.setName(name);
Message<DemoEntity> message = MessageBuilder
.withPayload(response)
.setHeader("contentType", "application/json")
.build();
return message;
}
}
在我的 application.properties 中,有以下一行:
function.name = example.StoreFunction
如果我创建环境变量 FUNCTION_NAME,则同样适用:example.StoreFunction
如果我现在部署该库并触发它,则会得到以下日志:
START RequestId: 67e64098-ef5d-11e8-bdbf-9ddadadef0ce Version: $LATEST
20:21:50.802 [main] INFO org.springframework.cloud.function.adapter.aws.SpringFunctionInitializer - Initializing: class example.SpringCloudFunctionApiGatewayApplication
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::
2018-11-23 20:21:53.684 INFO 1 --- [ main] lambdainternal.LambdaRTEntry : Starting LambdaRTEntry on ip-10-153-127-174.ec2.internal with PID 1 (/var/runtime/lib/LambdaJavaRTEntry-1.0.jar started by sbx_user1059 in /)
2018-11-23 20:21:53.687 INFO 1 --- [ main] lambdainternal.LambdaRTEntry : No active profile set, falling back to default profiles: default
2018-11-23 20:21:57.488 INFO 1 --- [ main] lambdainternal.LambdaRTEntry : Started LambdaRTEntry in 6.353 seconds (JVM running for 8.326)
No function defined: java.lang.IllegalStateException
java.lang.IllegalStateException: No function defined
at org.springframework.cloud.function.adapter.aws.SpringFunctionInitializer.apply(SpringFunctionInitializer.java:134)
at org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler.handleRequest(SpringBootRequestHandler.java:48)
END RequestId: 67e64098-ef5d-11e8-bdbf-9ddadadef0ce
REPORT RequestId: 67e64098-ef5d-11e8-bdbf-9ddadadef0ce Duration: 7454.73 ms Billed Duration: 7500 ms Memory Size: 1088 MB Max Memory Used: 130 MB
我们非常感谢所有帮助!
答案 0 :(得分:1)
好吧,问题显然是我对Spring Beans的了解有限。
在查看上下文中所有可用bean的列表之后,很明显,我不得不使用类名,但是以小写字母i开头。 e。 function.name = storeFunction 或 function.name = queryFunction 。
编辑以详细说明我的解决方案:
在我的项目中,我具有以下几种功能:
@Component
public class StoreFunction implements Consumer<String>{
@Override
public void accept(String s) {
// Logic comes here
}
}
@Component
public class QueryFunction implements Function<String, String>{
@Override
public void apply(String s) {
return s;
}
}
然后,我将它们注册为bean,例如。 G。像这样:
@SpringBootApplication
public class SpringCloudFunctionApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudFunctionApiGatewayApplication.class, args);
}
@Bean
StoreFunction storeFunction(){
return new StoreFunction();
}
@Bean
QueryFunction queryFunction(){
return new QueryFunction();
}
}
现在,我在Spring上下文中有两个bean storeFunction 和 queryFunction (上面@Bean方法的名称)。
最后,我必须告诉Spring要调用哪个函数。这可以通过创建环境变量FUNCTION_NAME并将其设置为bean名称之一来实现。
现在将项目部署到AWS Lambda时,我必须告诉Lambda调用哪个函数(因为Lambda每次部署只能调用一个函数)。
顺便说一句,我为此创建了a tutorial。