Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无服务器与事件源相结合是否可行?_Java_Akka_Aws Lambda_Akka Persistence_Serverless Architecture - Fatal编程技术网

Java 无服务器与事件源相结合是否可行?

Java 无服务器与事件源相结合是否可行?,java,akka,aws-lambda,akka-persistence,serverless-architecture,Java,Akka,Aws Lambda,Akka Persistence,Serverless Architecture,一段时间以来,我一直想用一个完整的无服务器架构来实现一个移动应用程序,最后开始研究细节。到目前为止,我发现AWS提供了这种设置所需的大部分服务(API网关、Cognito、Lambda、DynamoDB、SQS等),但我还没有解决一个(可能是理论上的)问题;活动来源 由于(历史)数据现在变得越来越有价值,所以(以我的拙见)存储用户的历史数据非常重要。当前事件源提供(如Akka Persistence)通过仅将事件持久化到数据库并将当前状态保留在内存中(以及将快照保存到数据库等)来实现这一目标 我

一段时间以来,我一直想用一个完整的无服务器架构来实现一个移动应用程序,最后开始研究细节。到目前为止,我发现AWS提供了这种设置所需的大部分服务(API网关、Cognito、Lambda、DynamoDB、SQS等),但我还没有解决一个(可能是理论上的)问题;活动来源

由于(历史)数据现在变得越来越有价值,所以(以我的拙见)存储用户的历史数据非常重要。当前事件源提供(如Akka Persistence)通过仅将事件持久化到数据库并将当前状态保留在内存中(以及将快照保存到数据库等)来实现这一目标

我的问题是,我没有能力在内存中存储这样的状态,因为我的Lambda函数在其单一目的完成后终止。我的问题归根结底是,目前是否有一个框架支持(在Java上)事件源(eventsourcing),它将当前状态保存在类似ElastiCache(Redis)的东西中。因为我有很多关于阿克卡的经验,这是坚持可以做到的吗?是否值得将事件源与无服务器后端相结合(目前),还是现在还不是时候

到目前为止,我还没有在Akka持久性文档中找到关于这个(可能不是)问题的更多信息。请给我一些建议,说明我在无服务器宇宙的使命中可能错过了什么;我仍在学习,就像我们大家一样

这主要是基于观点的,因此不适合堆栈溢出,但我会尽量保持事实性

akka持久性不适合无服务器部署策略,原因如下。它依赖于一个强有力的假设,即给定id在任何时候只有一个persistentator。在分布式环境中,强制执行这一假设意味着节点间的协调,通常使用akka集群分片。这不会让它自己被部署在一个无服务器的环境中,而该环境旨在运行简单的函数


一般来说,事件源意味着从日志中存储的事件(或最新快照+随后的事件)重建状态,而在无状态环境上这样做意味着每次执行函数都会导致效率低下,因为没有本地缓存。在事件源上添加分布式缓存可以在一定程度上缓解这种情况。但是,您仍然面临协调的挑战,以防止函数的多个实例之间出现竞争条件。这些因素与serverless旨在提供的操作简单性背道而驰。

是的,您可以在serverless中进行事件寻源


使用AWS的一种方法是使用DynamoDB作为事件存储。然后,您可以使用带有Lambda触发器的DynamoDB流将它们具体化到您的状态存储中(可以是任何其他DB)。

您可以使用DynamoDB流,但仅使用事件存储是不够的。应序列化生成下一个事件的代码,即,此时只允许一个代码实例为特定聚合实例生成事件。否则,事件的顺序可能不确定

通过事件源,命令被发送到聚合。当命令生效时,即修改聚合时,将生成一个事件,并将其添加到日志中,通常会发布该事件。通常,为命令生成事件需要聚合的当前状态。这就是为什么这样的代码不应该为同一聚合实例并行运行

一个解决方案是有一个“commandstore”,它是一个DynamoDB表,用于存储每个聚合实例的最后一个命令。因此,关联流包含对该项的更新。此流的Lambda触发器使用事件存储重建聚合实例的状态,并生成新事件。然后将事件保存在事件存储中。事件存储的流负责事件的发布

为了加快聚合状态的重建,可以使用快照表。例如,每100个事件,就可以在其中更新完整的聚合。然后,重构包括获取快照,然后仅获取序列号高于快照中序列号的事件


对可能存在于各种读取存储中的事件和关联的聚合副本进行编号具有使幂等性变得容易的优点。通过这种方式可以重播事件。

如果您对(一些可配置的)最终一致性感到满意,并且愿意应用CQR,那么您可以在Lambda中使用akka持久性来进行事件寻源

这样的设置看起来怎么样

您将拥有(1个或多个)lambda函数,这些函数创建n个lambda实例(让我们称它们为查询lambda;其中n基本上不受限制或受帐户中可用并发限制的限制),它们能够处理您的读取端(通过读取日志/快照存储,然后应答来处理查询),以及处理写操作的每个聚合最多1个lambda实例(使用lambda配置中的并发参数确保这一点)(让我们调用它们命令lambda)。这对于确保日志不会因为有多个参与者向其写入而损坏非常重要

根据您的一致性保证,确保在处理查询后立即停止查询lambda中的参与者,或者将接收超时设置为符合一致性保证的值,因为知道多个参与者可能会给您不同的状态

如果您有CRUD操作,请确保在应用更改之前,读取向用户显示当前状态的操作(