关于Lagom PersistentEntityRef与PersistentEntityRegistry的技术疑问
解答你的Lagom持久化实体疑问
Great questions—let's break these down clearly, since understanding PersistentEntity mechanics is key to working effectively with Lagom's CQRS/Event Sourcing model.
问题1:PersistentEntityRegistry的内部机制与实体数量
先澄清几个容易混淆的核心点:
PersistentEntityRegistry并不是存储实体实例的容器,它更像一个实体的"地址簿"与工厂:它管理你定义的所有PersistentEntity类型(比如你的CustomerEntity),并提供根据「实体类型+唯一ID」获取通信引用的能力。- 你看到的"单例"规则,是针对单个ID的实体实例,而非整个实体类型。意思是:在整个Lagom集群中,同一个实体ID(比如某个用户的邮箱)对应的内存实例,同一时间只会存在一个。
- 回到10k用户的场景:
- 注册表中绝不会存在10k个实体实例,实际上内存里只会保留当前正在被访问或处理命令的实体实例。
- 那些很久没被访问的用户实体,它们的状态只会存储在持久化数据库(比如Cassandra)中,不会占用内存。当某个用户的实体第一次被访问时,Lagom会从存储加载它的状态(如果是新用户,则初始化你定义的默认状态),创建内存实例;当实体闲置一段时间后,Lagom会把它从内存中卸载以节省资源,但状态依然保存在数据库里。
- 注册表本身不会被"塞满"10k个实例,它只是知道如何根据实体类型和ID,在需要时找到或创建对应的实体实例。
问题2:为何能获取不存在的实体引用
当你调用persistentEntityRegistry.refFor(CustomerEntity.class, request.userEmail)时,返回的并不是实际的内存实体实例,而是一个代理(Proxy)对象——它是你与该ID实体通信的"句柄",不管实体是否已经存在。
具体流程是这样的:
- 当你通过这个代理发送命令(比如创建客户的命令)时,Lagom会先检查集群中是否存在该ID的实体实例:
- 如果不存在,Lagom会自动创建一个新的
CustomerEntity实例,初始化到你定义的初始状态(比如空的客户对象),然后处理你的创建命令,同时将事件持久化到数据库中。 - 如果已经存在,就直接把命令路由到已有的内存实例上。
- 如果不存在,Lagom会自动创建一个新的
- 所以
refFor方法不需要实体提前存在,它只是给你一个能和目标ID实体通信的通道——实体的实际创建(或加载),是在你发送第一个命令时才触发的。
内容的提问来源于stack exchange,提问作者Trace
相关产品推荐
相关产品推荐

