我试图找出如何使用akka管理用户游戏状态。
游戏状态将持久保存到mysql,这不会改变,因为我们有其他需要此服务的服务。
游戏中发生的任何事情都被视为"事件"。
然后你我有"级别"哪个人可以实现。当您完成所有"事件时,将达到一个级别。与之相关。
所以你有:
Level
- event1 e.g. reach a point in the game
- event2 e.g. pickup a sword
- event3 e.g. defeat a monster
所以在游戏中有很多级别,以及与级别相关的100个事件。
所有"事件"通过HTTP发送到我的后端,我将事件保存在数据库中。
然后我必须在内存中加载用户游戏配置文件,然后重新计算自发生新事件以来所达到的等级。 注意:这个计算不能在数据库级别完成,因为我在这里写的比较复杂。
我看到的问题是,如果我使用akka,我就无法让多个actor为同一个用户处理事件,因为数据可能会过时。
为了清楚起见,所以当一个新事件到来时,我必须在内存中加载游戏配置文件,遍历各个级别并查看是否已经实现了任何一个,如果有,则更新数据库
e.g. update levels set achieved=true where level_id = 123 and user_id=234
e.g。 actor1加载配置文件(此用户的所有级别和事件),然后处理刚到达收件箱的新事件。 同时,actor2加载配置文件(与actor1相同),然后处理新事件。当它持续更改mysql时,数据将不在sych中。
如果我使用线程,我必须在游戏配置文件计算期间锁定并持久保存到数据库。
我如何使用Akka执行此操作并能够并行处理,或者这个场景是不允许的?
答案 0 :(得分:5)
让我们思考如何在没有演员的情况下管理它。因此,简而言之,您有以下问题场景:
这是一个经典问题。它至少有两种经典的解决方案:
Serializable
隔离级别来实现。值得一读this answer并对两个世界进行比较。
当您使用Akka时,您可能希望更喜欢更好的并发性和偶然的故障,这些故障很容易恢复。它与Akka座右铭let it crash
相提并论。
所以,你需要做下面的步骤:
version
列添加到您的表格中。它可以是数字或字符串(带哈希)。数字是最简单的。version
值未更改。那么,这是您的更新策略:
version
。where rec_id=$id and version=$version
执行更新查询。OptimisticLockException
或smth就像这样。Akka
完成工作的时候了:提出适当的监督策略(我选择try again in 1 second
之类的东西)。在actor的preRestart
方法中,将更新消息返回到actor的邮箱(参见Akka文档中的Restart Hooks章节)。 使用此策略,即使两个请求尝试一次更新同一条记录,其中一条会失败并会立即再次处理。