spring-boot - Spring Cloud Function 需要 Flux在 Azure Functions 上部署时,而不是 String
问题描述
我目前正在研究 Spring Cloud Function 及其在不同云环境(AWS Lambda 和 Azure Functions)上部署一个函数的可能性。
我的函数看起来像这样(当然非常简化):
@Component
public class EchoFunction implements Function<String, String> {
@Override
public String apply(String m) {
String message = "Received message: " + m;
return message;
}
}
在 AWS Lambda 上部署它时,它可以完美运行(可以在此处找到完整的项目)。
但是,如果我使用 Azure Functions Core Tools 运行与本地 Azure Functions 部署相同的函数,则在调用该函数时会出现以下异常:
24.01.19 21:58:50] Caused by: java.lang.ClassCastException: reactor.core.publisher.FluxJust cannot be cast to java.lang.String
[24.01.19 21:58:50] at de.margul.awstutorials.springcloudfunction.function.EchoFunction.apply(EchoFunction.java:9)
[24.01.19 21:58:50] at org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler.handleRequest(AzureSpringBootRequestHandler.java:56)
[24.01.19 21:58:50] at de.margul.awstutorials.springcloudfunction.azure.handler.FunctionHandler.execute(FunctionHandler.java:19)
[24.01.19 21:58:50] ... 16 more
出于某种原因,该函数似乎期望使用 Flux 而不是 String。我认为这可能与[文档]有关(https://cloud.spring.io/spring-cloud-static/spring-cloud-function/2.0.0.RELEASE/single/spring-cloud-function.html #_function_catalog_and_flexible_function_signatures)这样说:
Spring Cloud Function 的主要特性之一是为用户定义的函数适配和支持一系列类型签名,同时提供一致的执行模型。这就是为什么所有用户定义的函数都被 FunctionCatalog 转换为规范表示,使用 Project Reactor 定义的原语(即 Flux 和 Mono)。例如,用户可以提供一个 Function 类型的 bean,FunctionCatalog 会将它包装成一个 Function,Flux>。
所以问题可能与此有关:
如果我按以下方式更改功能,它会起作用:
@Component
public class EchoFunction implements Function<String, Flux<String>> {
@Override
public Flux<String> apply(String m) {
String message = "Received message: "+m;
return Flux.just(message);
}
}
我的函数处理程序如下所示:
public class FunctionHandler extends AzureSpringBootRequestHandler<String, String> {
@FunctionName("createEntityFunction")
public String execute(@HttpTrigger(name = "req", methods = {
HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<String> entity,
ExecutionContext context) {
return handleRequest(entity.getBody(), context);
}
@Bean
public EchoFunction createEntityFunction() {
return new EchoFunction();
}
}
对于 AWS 部署,我有以下依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.2.5</version>
</dependency>
</dependencies>
对于 Azure 部署,我只有一个依赖项:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure</artifactId>
<version>2.0.0</version>
</dependency>
我已经查看了这两个适配器的源代码: 在 AWS 上,SpringBootRequestHandler调用目标函数(在第 48 行)。
在 Azure 上,AzureSpringBootRequestHandler调用目标函数(在第 56 行)。
对我来说,看起来在这两种情况下,都交出了 Flux。但是,对于 AWS 适配器,对象显然是在两者之间的某个位置展开的。但 Azure 适配器并非如此。
任何想法为什么?
解决方案
@margul 抱歉回复晚了/没有新创建的spring-cloud-function
标签,您的问题有点丢失。我刚刚看了它以及您在 GH 中打开的问题,这似乎是我们这边的一个错误。基本上,如果我们在目录中找不到函数,我们就回退到 bean 工厂。这种方法的问题是 bean factory 有原始函数 bean(函数尚未流动),因此 ClassCast 异常。
无论如何,我将在 GH 中解决其余的问题。
只是为了关闭它,请看这个问题
推荐阅读
- python - 为什么 python 多线程在向服务器发送消息时在套接字中不起作用?
- windows - 如何通过 cmd 或 PowerShell 命令执行以下手动方法?
- matlab - 如何停止matlab plot3 scale
- symfony - Symfony 4,来自存储库或其他地方的闪存消息?
- postgresql - 带有自签名证书的 SSL POSTGRES 连接
- tcp - 通过 TCP IP 节点接收数据头 红色
- python-3.x - 在 python 3 中使用反斜杠
- c# - 无法在 Windows 10 上的 TransactionScope 内打开两个 SqlConnection
- json - 发布 JSON 布尔值 Django
- asp.net-core-mvc - MVC .Net Core - 将数据库内容导出为 .csv 文件