我试图弄清楚如何使用akka管理用户游戏状态.
游戏状态将持久保存到mysql,这不会改变,因为我们有其他需要此服务.
游戏中发生的任何事情都被视为"事件".
那么你我有一个人可以达到的"水平".完成与其关联的所有"事件"后,将达到一个级别.
所以你有了:
Level
- event1 e.g. reach a point in the game
- event2 e.g. pickup a sword
- event3 e.g. defeat a monster
Run Code Online (Sandbox Code Playgroud)
所以在游戏中有很多级别,以及与级别相关的100个事件.
所以所有"事件"都通过HTTP发送到我的后端,我将事件保存在数据库中.
然后我必须在内存中加载用户游戏配置文件,然后重新计算自发生新事件以来所达到的等级. 注意:这个计算不能在数据库级别完成,因为我在这里写的有点复杂.
我看到的问题是,如果我使用akka,我不能让多个actor为同一个用户处理事件,因为数据可能变得陈旧.
为了清楚起见,所以当一个新事件到来时,我必须在内存中加载游戏配置文件,遍历各个级别并查看是否已经实现了它们,如果有,则更新数据库
e.g. update levels set achieved=true where level_id = 123 and user_id=234
Run Code Online (Sandbox Code Playgroud)
例如,actor1加载配置文件(该用户的所有级别和事件),然后处理刚到达收件箱的新事件.同时,actor2加载配置文件(与actor1相同),然后处理新事件.当它持续更改mysql时,数据将不在sych中.
如果我使用线程,我将不得不在游戏配置文件计算期间锁定并持久保存到数据库.
我怎样才能使用Akka做到这一点并能够并行处理,或者这个场景是不允许的?
让我们思考如何在没有演员的情况下管理它.因此,简而言之,您有以下问题场景:
这是一个经典问题.它至少有两种经典的解决方案:
Serializable对事务应用隔离级别来实现.值得一读这个答案,并对两个世界进行比较.
当您使用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章节).使用此策略,即使两个请求尝试一次更新同一记录,其中一个将失败并将立即再次处理.
| 归档时间: |
|
| 查看次数: |
206 次 |
| 最近记录: |