akka mysql_Akka系列(七):Actor持久化之Akka persistence

这次把这部分内容提到现在写,是因为这段时间开发的项目刚好在这一块遇到了一些难点,所以准备把经验分享给大家,我们在使用Akka时,会经常遇到一些存储Actor内部状态的场景,在系统正常运行的情况下,我们不需要担心什么,但是当系统出错,比如Actor错误需要重启,或者内存溢出,亦或者整个系统崩溃,如果我们不采取一定的方案的话,在系统重启时Actor的状态就会丢失,这会导致我们丢失一些关键的数据,造成系统数据不一致的问题。Akka作为一款成熟的生产环境应用,为我们提供了相应的解决方案就是Akka persistence。

为什么需要持久化的Actor?

万变不离其宗,数据的一致性是永恒的主题,一个性能再好的系统,不能保证数据的正确,也称不上是一个好的系统,一个系统在运行的时候难免会出错,如何保证系统在出错后能正确的恢复数据,不让数据出现混乱是一个难题。使用Actor模型的时候,我们会有这么一个想法,就是能不对数据库操作就尽量不对数据库操作(这里我们假定我们的数据库是安全,可靠的,能保证数据的正确性和一致性,比如使用国内某云的云数据库),一方面如果大量的数据操作会使数据库面临的巨大的压力,导致崩溃,另一方面即使数据库能处理的过来,比如一些count,update的大表操作也会消耗很多的时间,远没有内存中直接操作来的快,大大影响性能。但是又有人说几人内存操作这么快,为什么不把数据都放内存中呢?答案显而易见,当出现机器死机,或者内存溢出等问题时,数据很有可能就丢失了导致无法恢复。在这种背景下,我们是不是有一种比较好的解决方案,既能满足需求又能用最小的性能消耗,答案就是上面我们的说的Akka persistence。

Akka persistence的核心架构

在具体深入Akka persistence之前,我们可以先了解一下它的核心设计理念,其实简单来说,我们可以利用一些thing来恢复Actor的状态,这里的thing可以是日志、数据库中的数据,亦或者是文件,所以说它的本质非常容易理解,在Actor处理的时候我们会保存一些数据,Actor在恢复的时候能根据这些数据恢复其自身的状态。

所以Akka persistence 有以下几个关键部分组成:

PersistentActor:任何一个需要持久化的Actor都必须继承它,并必须定义或者实现其中的三个关键属性:

def persistenceId = "example" //作为持久化Actor的唯一表示,用于持久化或者查询时使用

def receiveCommand: Receive = ??? //Actor正常运行时处理处理消息逻辑,可在这部分内容里持久化自己想要的消息

def receiveRecover: Receive = ??? //Actor重启恢复是执行的逻辑

相比普通的Actor,除receiveCommand相似以外,还必须实现另外两个属性。

另外在持久化Actor中还有另外两个关键的的概念就是Journal和Snapshot,前者用于持久化事件,后者用于保存Actor的快照,两者在Actor恢复状态的时候都起到了至关重要的作用。

Akka persistence的demo实战

这里我首先会用一个demo让大家能对Akka persistence的使用有一定了解的,并能大致明白它的工作原理,后面再继续讲解一些实战可能会遇到的问题。

假定现在有这么一个场景,现在假设有一个1w元的大红包,瞬间可能会很多人同时来抢,每个人抢的金额也可能不一样,场景很简单,实现方式也有很多种,但前提是保证数据的正确性,比如最普通的使用数据库保证,但对这方面有所了解的同学都知道这并不是一个很好的方案,因为需要锁,并需要大量的数据库操作,导致性能不高,那么我们是否可以用Actor来实现这个需求么?答案是当然可以。

我们首先来定义一个抽奖命令,

case class LotteryCmd(

userId: Long, // 参与用户Id

username: String, //参与用户名

email: String // 参与用户邮箱

)

然后我们实现一个抽奖Actor,并继承PersistentActor作出相应的实现:

case class LuckyEvent( //抽奖成功事件

userId: Long,

luckyMoney: Int

)

case class FailureEvent( //抽奖失败事件

userId: Long,

reason: String

)

case class Lottery(

totalAmount: Int, //红包总金额

remainAmoun

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值