Page History
Info |
---|
자바진영 ( 자바,스칼라,코틀린 ) 에서 모두 활용가능한 패턴으로 RestAPI와 WebSocket의 개발방식의 차이인 StateFul과 Stateless를 먼저알아보고 Reactive 웹소켓을 액터모델과 연동했을때 장점과 확장가능한 샘플코드를 살펴보겠습니다. Let't go |
Stateful VS Stateless
REST API (Stateless 방식)
...
🚀 즉, 성능과 확장성이 중요한 경우 WebFlux, 익숙한 개발 방식과 기존 시스템 통합이 중요한 경우 MVC 웹소켓을 선택하는 것이 좋습니다.
Note |
---|
액터모델이 국내에 개발패턴으로 잘 안알려져 있기도하고 레퍼런스가 부족하지만 이미 성공한 메시징/메신저/통신 테크기업들이 액터모델을 직접 채택하거나 액터모델이 내재화된 프레임워크를 사용하고 있는 것으로 추정합니다. 이 기술을 단지 학습곡선때문에 제외할것이냐? 학습곡선이 높을수 있지만 우리가 필요로하는 스팩이여서 연마가 필요한것인가? 그것을 책임지는 기술팀이 판단해야하는 영역입니다. 학습도에따라 액터모델이 우리에게 고통을 줄수도 있습니다. 액터모델 프로그래밍을 할필요없는 Reactive진영의 우수한 클라우드형 MQ PasS를 채택할수도 있겠지만 ( 트래픽당 클라우드 비용을 잘 계산해야함 ) 직접구현 개발모델을 선택한다고 하면 스레드 모델과 비교할수 있습니다. |
✅ 액터 모델 vs 스레드 모델 비교 요약
비교 항목 | 액터 모델 (Actor Model) | 스레드 모델 (Thread Model) |
---|---|---|
동시성 처리 | 경량 액터 기반으로 수천만 개 병렬 처리 가능 | OS 스레드 기반, 스레드 개수 제한 |
상태 관리 | 각 액터가 자체적으로 상태 유지 (Stateful) | 공유 메모리로 상태 관리 (Mutex, Lock 필요) |
메시지 전달 | 비동기 메시지 패싱 (No Lock) | 동기 방식 (Lock, Context Switching 부담) |
리소스 효율 | 가벼운 액터 (스레드보다 적은 메모리) | 스레드마다 메모리(Stack) 사용량 높음 |
확장성 | 액터 개수와 관계없이 수평 확장 가능 (Cluster 지원) | 스레드 개수 제한으로 확장성 제한적 |
안정성 | 액터 단위 장애 격리 가능 (Supervisor Strategy) | 하나의 스레드 장애 시 전체 영향 가능 |
데드락 발생 | 메시지 기반 → 데드락 없음 | 공유 메모리 접근 시 데드락 발생 가능 |
구현 난이도 | 비동기 메시지 기반, 설계 패턴 필요 | 전통적인 동기 방식으로 직관적 |
🚀 액터 모델의 주요 장점
- 고성능 동시성 처리 (수백만 개 액터 운영 가능)
- 데드락 없는 안정적인 상태 관리 (Lock-Free)
- 확장성 뛰어난 구조 (Akka Cluster, Pekko 활용 가능)
- 분산 시스템에 적합 (분산 액터로 수평 확장 가능)
👉 멀티스레드 환경의 동시성 이슈(Lock, 데드락, 컨텍스트 스위칭)를 해결하고, 확장성과 안정성을 극대화한 모델! 🚀
🔹 액터 모델을 채택한 메시징/메신저 시스템
...
- 기술 스택: Erlang
- 특징:
- 메시지 브로커로 사용되지만, 내부적으로 Erlang의 액터 모델을 활용하여 높은 동시성 처리 가능
- AMQP 프로토콜을 사용하여 안정적인 메시지 큐 제공
- 장점:
- 메시징 시스템에 최적화
- 확장 가능하며, 분산 아키텍처에서 활용 가능
6. Apache Flink
- https://docs.aws.amazon.com/ko_kr/managed-flink/latest/java/what-is.html
- https://docs.aws.amazon.com/ko_kr/managed-flink/latest/java/flink-1-18.html
- Akka(Pekko)가 코어처리 모듈로 채택됨
7. Ray
- https://docs.ray.io/en/latest/ray-core/actors.html
- OpenAI가 ML 파이프라인용으로 채택해 알려진 ray도 액터 프레임워크입니다. ( 파이썬진영 )
🚀 분석: 액터 모델과 웹소켓 연동의 장점
이 코드는 Akka (현재 Apache Pekko) 기반 액터 모델을 활용하여 **웹소켓을 관리하는 세션 관리자(SessionManagerActor)**를 구현한 것입니다.
액터 모델이 웹소켓과 연동될 때 가지는 장점은 다음과 같습니다.
...
💡 예제 코드 적용:
onSubscribeToTopic
→ 클라이언트가 특정 토픽을 구독하면 세션 ID를 저장onSendMessageToTopic
→ 해당 토픽을 구독한 모든 세션에 메시지를 전송
고성능 IO
Info |
---|
AKKA를 소개할때 그것을 프로덕에 적용을 해보았나요? 성능에 문제없나요? 단지 이론에 거치는것을 소개하나요? 라는 질문을 가끔 받기도합니다. 글로벌 기업에 근무할 자바 7인시절 C++ IOCP로작동되는 고성능으로 이루어진 특정 카테고리 글로벌 TOP랭크의 멀티플레이어 서버를 모바일웹에 대응하기위해 C++ 네이티브 분산처리 개발 난이도를 낮추려고 Akka를 성공 적으로 도입하였으며 웹진영에서 AKKA를 사용하면 학습곡선이 높은것에 해당할수 있지만, 분산처리 시스템을 모두 메이드업한 C++시절에서 AKKA는 오히려 분산처리를 단순화하는 툴킷이였습니다. 그래서 고성능 IO관점에서 자바의 네티IO를 리모트장치로 채택할수 있지만 더 성능좋은 IO를 채택할수 있습니다. 단일지점 Remote IO능력으로 본다면 네이테브의 장점으로 IOCPSOCK(C++ WinServer)을 여전히 능가할수 없으며 자바7일시절에도 C++의 단일지점 능력치를 50%만 뽑아내도 성공적인 변환이였습니다. 하지만 단일지점 처리능력보다, 오히려 단일장비 10만이나 처리하는 리소스처리량을 낮추고 더 적고 많은 장치로 트래픽을 분산하는 분산처리 유연함이 더 중요했기때문에 AKKA를 과거 시절 채택을 하였습니다. C++이 안된다라기보다 이 진영은 액터모델에 준하거나 능가하는 액티브오브젝트 패턴을 직접구현하고 네트워크프로그래밍까지화해 최적화 까지 할수 있는 팀역량을 보유해야 했기때문에 어나더 레벨의 개발구성이 필요한것도 AKKA로 전환한 이유중에 하나였습니다. |
도입시 로드테스트 사례및 글로벌 기업
소개가 길었지만~ 본방인 Reactive Websocket과 액터모델을 연동하는 샘플코드를 살펴보겠습니다.
Reactive Websocket with ActorModel 구현체
구현샘플 코드
- base : pub/sub을 로컬클래스 모델로 구현한 기본 Reactive 사용법입니다.
- actor : base버전의 로컬클래스 모델을 로컬액터모델로 변환한 ActorModel버전입니다.
위 버전은 로컬로 작동되며 , 액터모델을 최초한번 연동하고 나면 액터모델 자체만으로 리모트/클러스터 등으로 확장할수 있습니다.
약간의 액터를 배치하고 Discovery요소및 영속성장치를 활용하게 되지만 핵심은 외부장치의 변화로 도메인을 처리하는 액터로직의 코드 수정이 없다는것이 가장 큰장점이며 이러한 장점으로 액터모델의 학습곡선과 장치를 이해한다고 가정하면
외부장치의 도움없이 로컬 Only 모놀리식으로 시작해 기능구현을 모두 해도 나중에 MSA로 확장시 기존 구현된 코드를 변경할 필요 없는것이 액터모델의 큰장점입니다.
로컬액터가 구현되었을때 확장하는 샘플코드는 별도로 구분하였으며 모든 구현코드는 유닛테스트로 코드를 설명하며 활용방법을 알수 있습니다.
확장하기
확장 장치및 설명
- core : actor 모델의 기본 사용법
- discovery : 액터모델을 위치투명성 기법을 이용해 사용하기 ( 로컬에서 필요없지만 클러스터로 확장될시 필요한 개념)
- persitent : 이벤트소싱 durable을 포함 액터모델의 이벤트를 영속화(db장치 선택가능)하는 CQRS 기법을 학습
- state : repository 패턴을 활용해 액터모델의 상태를 동기화하는 예제 ( Redis장치에 대응하고 저비용으로 더 빠르게 사용 )
- timer : 액터모델에 스케줄러 기능을 부여해, 수십만개의 독립적 가능 타이머 생성가능 ( 스레드 모델에 대응)
- bulkprocessor : realTime 에서 발생하는 이벤트를~ 효율적으로 저장해 DB부하를 획기적으로 줄입니다. - 데이터를 부분 지속처리
- router : 액터메시지를 분배처리하는 라우팅 장치 ( 라운드로빈,해쉬로빈등 다양한 분배장치를 채택할수도 커스텀할수도 있음)
- supervisor : 호출자에게 예외를 전파하는 전통적 장애복구 방식이 아닌 부모가 자식객체를 모니터링해 복구하는 전략 방식
- stream : reactive stream 을 준수하는 장치를 활용해 액터모델과 연결하는 샘플 ( kafka등의 외부 장치와 연결 )
- cluster : 로컬로 잘 작성된 액터모델을 클러스터화합니다. 기존 코드의 변경을 최소화하고 클러스터화 시스템에 액터를 배치하게됩니다.
다음장에서는 웹소켓과 여기에 연결된 액터모델을 비동기 수신검사하는 유닛테스트를 알아보겠습니다.
Next : UnitTest Reactive Websocket&Actor