Programing/Akka

Akka Actor 개발팁

BUST 2018. 9. 18. 21:58

Akka Actor 개발팁


1. Actor은 하나의 기능만을 담당을 한다.

  • 객체지향의 SRP
  • 기능을 많아 질수록 복잡성이 높아진다. 응집도가 낮아진다. 결합도 높아진다.

2. Actor Message는 Actor Class 내부에 정의한다.

public class DemoMessagesActor extends AbstractLoggingActor {

  static public class Greeting {
    private final String from;

    public Greeting(String from) {
      this.from = from;
    }

    public String getGreeter() {
      return from;
    }
  }
  
  @Override
  public Receive createReceive() {
    return receiveBuilder()
      .match(Greeting.class, g -> {
        log().info("I was greeted by {}", g.getGreeter());
      })
      .build();
  }
}
  • Message가 너무 많아지거나 큰 경우에는 같은 패키지에 둔다.

3. Actor 사이의 메시지 전달은 Most-once-Delivery (최대 한번)

  • Local Jvm에서의 메시지 전달은 유실이 없다고 생각해 된다. (오류가 없는 경우)
  • Remote, Cluster 등의 네트워크를 통한 메시지 전달은 most-once-delivery (최대 한번)
  • 메시지 유실이 유무가 중요한 경우에는 at-least-once-delivery 전달 방식을 구현을 한다.
    • 메시지 1개마다 하나의 id가 존재를 하고 이를 통해 완료 및 re-try 로직를 구현
    • kafka, rabbitmq 등의 broker를 두는 방식도 존재

4. mailbox 사이즈는 기본값은 unbound queue이다

  • 빠른 publisher, 느린 consumer 일때 mailbox가 쌓이는 문제가 발생을 할수가 있다.
  • mailbox가 늘어남에 따라 메모리가 부족을 하게 되고 그에따라 GC overhead limit 에러가 발생이 되고 정상작동이 되지 않을수가 있다.
  • 해결방법
    • Akka Stream을 활용한다, backpressure
    • Pulling Pattern
    • Rate Limiter
    • Dynamic Rate Limiter

5. I/O를 가진 Actor는 별도의 Dispatcher를 사용하라

  • Dispatcher은 하나의 Thread Pool를 통해 Actor를 관리하는 서비스
  • I/O (Network I/O, File I/O)의 로직은 Blocking I/O 인데 그 경우 Thread Pool를 차지 하고 있기 때문에 다른 Actor가 실행이 되지 않는 문제점이 있다.
  • I/O Dispatcher를 따로 할당을 하여 I/O가 없는 로직을 가진 Actor를 실행할수 있게 하는 것이 성능향상이 된다.