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

Compare with Current View Page History

« Previous Version 2 Next »


스칼라

import akka.actor.{Actor, ActorSystem, Props}

// 액터 정의
class HelloActor extends Actor {
  def receive: Receive = {
    case "hello" =>
      sender() ! "world"
    case msg =>
      println(s"Unknown message: $msg")
  }
}

// 메인 또는 테스트 앱
object HelloActorApp extends App {
  // 액터 시스템 생성
  val system = ActorSystem("HelloSystem")

  // 액터 인스턴스 생성

  val helloActor = system.actorOf(Props[HelloActor], name = "helloActor")

  // 응답을 기다릴 임시 액터 생성
  import akka.pattern.ask
  import akka.util.Timeout
  import scala.concurrent.duration._
  import scala.concurrent.Await
  import scala.concurrent.ExecutionContext.Implicits.global

  implicit val timeout: Timeout = Timeout(5.seconds)

  // 메시지 전송 및 응답 대기
  val future = helloActor ? "hello"
  val result = Await.result(future, timeout.duration)

  println(s"응답: $result") // "world" 출력

  // 종료
  system.terminate()
}

주요 설명:

  • "hello" 메시지를 받으면 sender() ! "world"로 응답을 보냄

  • ask 패턴(?)을 사용하여 응답을 Future로 받음

  • Await.result로 블로킹 방식으로 응답을 출력



자바

public class HelloActor extends AbstractActor {

    // 액터 생성 팩토리
    public static Props props() {
        return Props.create(HelloActor.class);
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .matchEquals("hello", msg -> {
                getSender().tell("world", getSelf());
            })
            .matchAny(msg -> {
                System.out.println("Unknown message: " + msg);
            })
            .build();
    }
}

public class HelloActorApp {
    public static void main(String[] args) throws Exception {
        ActorSystem system = ActorSystem.create("HelloSystem");

        ActorRef helloActor = system.actorOf(HelloActor.props(), "helloActor");

        // 메시지 보내고 응답 기다리기
        Future<Object> future = Patterns.ask(helloActor, "hello", 5000);
        String result = (String) Await.result(future, Duration.create(5, TimeUnit.SECONDS));

        System.out.println("응답: " + result); // "world"

        system.terminate();
    }
}



닷넷

public class HelloActor : ReceiveActor
{
    public HelloActor()
    {
        Receive<string>(msg =>
        {
            if (msg == "hello")
            {
                Sender.Tell("world");
            }
            else
            {
                Console.WriteLine($"Unknown message: {msg}");
            }
        });
    }
}

class Program
{
    static async Task Main(string[] args)
    {
        using var system = ActorSystem.Create("HelloSystem");

        var helloActor = system.ActorOf<HelloActor>("helloActor");

        // Ask 패턴으로 메시지 보내고 응답 받기
        var response = await helloActor.Ask<string>("hello", TimeSpan.FromSeconds(5));

        Console.WriteLine($"응답: {response}"); // "world"

        await system.Terminate();
    }
}



코틀린 AKKA 버전

class HelloActor : AbstractActor() {

    override fun createReceive(): Receive {
        return receiveBuilder()
            .matchEquals("hello") {
                sender.tell("world", self)
            }
            .matchAny {
                println("Unknown message: $it")
            }
            .build()
    }

    companion object {
        fun props(): Props = Props.create(HelloActor::class.java)
    }
}

fun main() {
    val system = ActorSystem.create("HelloSystem")
    val helloActor = system.actorOf(HelloActor.props(), "helloActor")

    val future = Patterns.ask(helloActor, "hello", 5000)
    val result = Await.result(future, Duration.create(5, TimeUnit.SECONDS)) as String

    println("응답: $result") // world 출력

    system.terminate()
}



코틀린 액터 코어버전

코틀린은 액터모델을 채택했기때문에 서드파티툴없이 액터모델 이용가능합니다. 

(akka,pekko  이용시 액터모델이 스트림,클러스터로 확장되는 툴은없기때문에 직접 구현해야함) 

import kotlinx.coroutines.channels.actor

// 메시지 정의
sealed class Message
data class Greet(val replyTo: CompletableDeferred<String>) : Message
object Unknown : Message

// 액터 함수
fun CoroutineScope.helloActor() = actor<Message> {
    for (msg in channel) {
        when (msg) {
            is Greet -> msg.replyTo.complete("world")
            else -> println("Unknown message received: $msg")
        }
    }
}

fun main() = runBlocking {
    val actor = helloActor()

    val response = CompletableDeferred<String>()
    actor.send(Greet(response))

    println("응답: ${response.await()}") // 출력: world

    actor.close()
}



파이썬 Ray기반

// hello_actor.py
import ray

# Ray 초기화
ray.init()

# 액터 클래스 정의
@ray.remote
class HelloActor:
    def say(self, msg):
        if msg == "hello":
            return "world"
        else:
            return f"Unknown message: {msg}"

// main.py
import ray
from hello_actor import HelloActor

ray.init(ignore_reinit_error=True)  # 이미 실행 중일 경우 무시

# 액터 생성
actor = HelloActor.remote()

# 메시지 전송 및 응답 받기
response = ray.get(actor.say.remote("hello"))
print(f"응답: {response}")  # 출력: world

# 종료
ray.shutdown()



Erlang(언랭) 

-module(hello_actor).
-export([start/0, loop/0]).

start() ->
    spawn(fun loop/0).

loop() ->
    receive
        {From, "hello"} ->
            From ! "world",
            loop();
        {From, Msg} ->
            From ! {error, "Unknown message: " ++ Msg},
            loop()
    end.


1> c(hello_actor). % 컴파일
2> Pid = hello_actor:start().  % 액터 시작
3> Pid ! {self(), "hello"}.    % 메시지 전송
4> flush().                    % 응답 확인

Shell output:
Shell got "world"

장점 (Erlang식 액터 모델 특징)

  • Lightweight 프로세스 (수십만 개 생성 가능)

  • 모든 액터는 메시지 기반으로 통신

  • 고장 격리 (let it crash 철학)

  • OTP 사용 시 supervision, 상태 관리, 분산까지 매우 쉬움


1. Scala: Akka 프레임워크

Akka는 Scala와 Java에서 사용 가능한 강력한 액터 기반 프레임워크로, 분산 시스템과 동시성 처리를 위한 도구를 제공합니다.

  • 적용 사례:

    • LinkedIn: Akka를 활용하여 실시간 데이터 처리를 개선하고, 대규모 메시징 시스템의 성능을 향상시켰습니다.

    • Lightbend: Akka의 개발사로, 자체 제품과 서비스에 Akka를 적극 활용하여 고성능 애플리케이션을 구축하고 있습니다.

2. Java: Akka 및 Spring Integration

Java 진영에서는 Akka 외에도 Spring Integration과 같은 프레임워크를 통해 액터 모델의 개념을 적용하고 있습니다.

  • 적용 사례:

    • Credit Karma: Akka를 사용하여 마이크로서비스 아키텍처를 구축하고, 사용자에게 실시간 신용 점수 업데이트를 제공하고 있습니다.

    • Netflix: Spring Integration을 활용하여 마이크로서비스 간의 메시지 기반 통신을 구현하고, 서비스 간의 결합도를 낮추는 데 기여했습니다.

3. C#: Akka.NET

Akka.NET은 .NET 환경에서 Akka의 기능을 제공하는 프레임워크로, C#과 F#에서 사용 가능합니다.

  • 적용 사례:

    • Petabridge: Akka.NET의 주요 개발사로, 분산 시스템 구축을 위한 도구와 서비스를 제공하며, 자체 프로젝트에 Akka.NET을 활용하고 있습니다.

    • SIL International: Akka.NET을 사용하여 언어 학습 애플리케이션의 성능과 확장성을 개선하였습니다.

4. Kotlin: 코루틴과 채널

Kotlin에서는 언어 자체의 **코루틴(coroutines)**과 **채널(channels)**을 활용하여 액터 모델을 구현할 수 있습니다.

  • 적용 사례:

    • JetBrains: Kotlin의 개발사로, 내부 도구와 애플리케이션에서 코루틴과 채널을 활용하여 비동기 프로그래밍과 동시성 처리를 효율화하고 있습니다.

5. Python: Ray 프레임워크

Ray는 Python에서 분산 컴퓨팅을 위한 프레임워크로, 액터 모델을 지원하여 대규모 병렬 처리를 가능하게 합니다.

  • 적용 사례:

    • OpenAI: Ray를 활용하여 대규모 머신 러닝 모델의 학습과 배포를 효율적으로 관리하고 있습니다.

    • Ant Group: 금융 서비스에서 Ray를 사용하여 실시간 데이터 분석과 위험 관리를 수행하고 있습니다.

6. Erlang: 내장 액터 시스템

Erlang은 언어 자체에 액터 모델이 내장되어 있어, 높은 동시성과 분산 시스템 구축에 적합합니다.

  • 적용 사례:

    • WhatsApp: Erlang을 사용하여 수억 명의 사용자에게 안정적인 메시징 서비스를 제공하고 있습니다.

    • Ericsson: 통신 시스템의 신뢰성과 가용성을 높이기 위해 Erlang을 활용하고 있습니다.

7. Elixir: Erlang 기반의 액터 모델

Elixir는 Erlang VM 위에서 동작하는 언어로, 액터 모델을 활용하여 확장성과 유지보수성이 높은 애플리케이션을 개발할 수 있습니다.

  • 적용 사례:

    • Discord: Elixir를 사용하여 대규모 실시간 채팅 시스템을 구축하고, 수백만 명의 동시 접속을 처리하고 있습니다.

    • Bleacher Report: Elixir를 활용하여 스포츠 뉴스와 관련 콘텐츠를 실시간으로 제공하는 플랫폼을 운영하고 있습니다.

이처럼 다양한 언어와 프레임워크에서 액터 모델이 구현되어, 여러 테크 기업에서 분산 시스템과 동시성 처리를 위한 핵심 도구로 활용되고 있습니다.









  • No labels