You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

스냅샷은 액터의 복구속도를 높일수가 있습니다.

SaveSnapShot을 호출하여 내부상태의 스냅샷을 저장할수가 있습니다.


다음과 같은 메시지액터를 설계한다고 합시다.

  • 단순하게 문자열 메시지만 전송받습니다.
  • 액터가 종료되더라도 최근 50개의 메시지를 복구합니다.
  • 테스트코드에서는 100개의 메시지를 보내고 , 액터를 죽인후 다시 뛰워 복구가되는지 살펴봅니다.


 public class MySnapShotActor : UntypedPersistentActor
{
  private ILoggingAdapter log = Context.GetLogger();
  public override string PersistenceId => "my-stable-persistence-id";
  private const int SnapShotInterval = 5;  //스냅샷은 5의 배수에 저장합니다.
  private object state = new object();

  //복구수 전략을 선택합니다. (최근 50개)
  public override Recovery Recovery => new Recovery(fromSnapshot: new SnapshotSelectionCriteria(minSequenceNr:0, maxSequenceNr: 50, maxTimeStamp: DateTime.UtcNow));
  //public override Recovery Recovery => new Recovery(fromSnapshot: SnapshotSelectionCriteria.None);

  protected override void OnRecover(object message)
  {
      // handle recovery here
      if (message is SnapshotOffer offeredSnapshot)
      {
          log.Debug("이전 스냅샷 복구");
          state = offeredSnapshot.Snapshot;
      }
      else if (message is RecoveryCompleted)
      {
          log.Debug("스냅샷복구완료:");
      }
      else
      {
          // event
          log.Debug("스냅샷e:" + message);
      }
  }

  protected override void OnCommand(object message)
  {
      if (message is SaveSnapshotSuccess s)
      {
          log.Debug("스냅샷 성공");
      }
      else if (message is SaveSnapshotFailure f)
      {
          log.Debug("스냅샷 실패");
      }
      else if (message is string cmd)
      {
          log.Debug("cmd:" + cmd);
          Persist($"evt-{cmd}", e =>
          {
              UpdateState(e);
              if (LastSequenceNr % SnapShotInterval == 0 && LastSequenceNr != 0)
              {
                  log.Debug("스냅샷 시도");
                  SaveSnapshot(state);
              }
          });
      }
  }

  private void UpdateState(string evt)
  {
      state = evt;
  }
}
var actorInfo = Props.Create<MySnapShotActor>();
var myactor = actorSystem.ActorOf(actorInfo, "myActor");
for(int i = 0; i < 100; i++)
{
    string message = "t" + i;
    myactor.Tell(message);
}

waitForTest(1000);
myactor.Tell(Akka.Actor.Kill.Instance, ActorRefs.NoSender);
waitForTest(1000);
//액터가 복구되는지 확인합니다.
myactor = actorSystem.ActorOf(actorInfo, "myActor");

......중간생략( 0-99까지 메시지 전송하고, 액터를 죽이고 다시살림)

...... 복구과장 ( 최근 50개의 메시지가 복구가됩니다. )

[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t87
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t88
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t89
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t90
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t91
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t92
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t93
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t94
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t95
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t96
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t97
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t98
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t99
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷복구완료:


Store Plugin

스냅샷은 다양한 저장소에 저장이 가능합니다.

참고 url : https://petabridge.com/blog/intro-to-persistent-actors/




  • No labels