Study 1. 개발 환경 세팅
Scala
1. App / Class / Object
case class = java vo
object = singleton? / object가 되어야지 app을 상속받을 수 있음
trait = 확장해서 쓸 수 있는 abstract, interface 느낌
app을 상속받으면 메인이 들어있음
2. sbt = simple build tool
3. partialfunction - scala / 명시하는게 좋은데 생략해도 partialfunction으로 tuple
4. 함수를 기호로 선언해놓음....!? => ! ? ++= ㄸㄸㄸㄸ.....
5. yield
Akka
Actor
https://doc.akka.io/docs/akka/current/guide/index.html
https://yehongj.tistory.com/44
actorSystem => 최상위
다른 actor에서 same name으로 생성 안됨 - actor path / actor name unknown
actor 생성한 곳에서 terminate가 나오면 actor가 끝나든 말든 종료시켜버림ㅋㅋㅋ
actor에 넘기는 message는 순서가 있어도 나오는 건 순서대로 나오는게 아니라 끝나는 대로 나옴
tell vs ask => ask는 응답 받음 scala에서 tell 은 ! ask는 ? // ?,! scala akka library 에서 def 해놓은거
Study 2. Actor Model, Lifecycle, hierarchy
1. Actor Model
actor model은 간단히 설명하면 behavior, state, mailbox로 구성된 actor를 기본 단위로 하는 message processing을 이용하여 behavior를 비동기적으로 실행하는 model이다.
Actor의 구성과 역할
1) State
- 각 Actor는 message를 이용해서만 간섭할 수 있다.
- Actor간에 공유하는 자원이 없으며 서로 간의 state를 건드릴 수 없다.
2) mailbox
- message는 mailbox에 쌓였다가 들어온 순서대로 처리된다.
3) behavior
- behavior는 message에 의해 결정
- behavior가 할 수 있는 일
자신의 state를 바꾸거나
child actor를 만들거나
child actor를 죽이거나
다른 actor에 message를 보낼 수 있다.
actor model의 actor는 사실 OOP에서 말하는 object와 매우 비슷하다.
Actor Model | OOP | |
주체 | Actor | Object |
has | state | member variable |
동작 정의 | behavior |
method |
가장 큰 차이 | actor는 message를 보낸 context와 독립적인 context에서 비동기적으로 실행된다. | Object의 method는 message를 보낸 context에서 바로 실행되어 method가 끝날 때까지 기다린다. |
[출처] https://blog.seulgi.kim/2014/04/actor-model-and-akka.html
2. The Akka actor hierarchy & lifecycle
1. hierarchy
getContext().actorOf() 를 이용해서 actor 생성
freestanding(자립형) actor를 생성하기보다는 기존 actor tree에 자식 actor로 injection.
System.actorOf() 를 통해서 actor 밑에 자식 actor를 생성한다.
2. lifecycle
actor가 stop하면 그것의 모든 children은 같이 재귀적으로 stop됨
-> 이렇기 때문에 자원이 simple하고 clear하게 관리될 수 있음. ( resource leak을 방지하기 위해서)
-> a commonly overlooked difficulty when dealing with low-level multi-threaded code is the lifecycle management of various concurrent resources.
-> 낮은 수준의 멀티 스레드 코드를 처리할 때 일반적으로 간과되는 어려움은 다양한 동시 리소스의 수명주기 관리
lifecycle hook
preStart()
Actor가 시작된 후 첫 message를 처리하기 전에 invoke됨
데이터베이스 연결, 파일 등과 같은 필요한 리소스를 얻을 수 있음.
postStop()
Actor가 멈추기 직전에 호출, 이 시점 이후에는 메세지가 처리되지 않음.
액터 생명주기의 마지막, 액터는 새 메세지 수신을 중지하고 현재 메세지는 데드 레터 메일함deadLettersActorRef으로 리디렉션
actor will stop receiving any new messages and the current messages will be redirected to dead letter mailbox.
preRestart(), postRestart
액터 생명주기 중간에 오류 등의 이슈로 supervisor가 액터를 관리할 때 하는 이벤트들
The preRestart( ) and postRestart( ) methods help us handle what happens in case an actor fails and is restarted for some reason.
앞에서 뭐 때문에 장애가 발생하는지 reason을 통해서 주고받을 수 있음.
[출처] https://doc.akka.io/docs/akka/current/guide/tutorial_1.html
Akka in action 책 내용
4.1 내고장성이란(그리고 내고장성이 아닌 것은)?
- fault tolerance : 내고장성, 결함 허용
- catch-all 접근 방법 : 실패가 발생하면 가능한 한 빨리 시스템을 중단시키는 복원 방법
- Akka에서 제공하는 내고장성 전략?
고장 봉쇄 또는 격리, 구조, 다중화, 교체, 리부트, 컴포넌트 생명주기, 일시 정지, 관심사 분리
4.1.1 일반 객체와 예외
4.1.2 중단되게 내버려 두기 ( 장애 허용 시스템, 회복력이 있는 시스템 )
일반 코드와 복구 코드를 모두 한 흐름에서 처리하는 대신, 아카 actor는 두 가지 흐름을 제공한다. 하나는 일반 로직 처리를 위한 것이고, 다른 하나는 오류 복구 로직을 위한 것이다.
일반 흐름은 일반적인 메세지를 처리하는 액터로 이뤄져 있었고, 복구 흐름은 일반 흐름을 수행 중인 액터를 감시하는 액터로 이뤄진다.
다른 액터를 감시하는 액터를 슈퍼바이저라고 말한다.
supervisor의 복구 방법 - restart, resume, stop, escalate (study 3에 이어짐)
중단되게 내버려 두기의 장점 - 고장 격리, 구조, 다중화, 교체, 리부트, 컴포넌트 생명주기
4.2 액터 생명주기
4.2.1 시작 이벤트
최상위 액터는 actorsystem의 actorof 메서드로 만들어짐
4.2.2 종료 이벤트
actorcontext의 stop 메서드
poisonPill 메세지를 보내서 액터를 멈추게 함
4.2.3. 재시작 이벤트
액터의 생명주기 중간에 슈퍼바이저가 액터를 재시작하기로 결정할 수도 있음.
재시작 이벤트는 액터 인스턴스가 교체되므로 시작/종료 이벤트보다 조금 더 복잡,
재시작되면 중단된 액터 인스턴스의 prerestart메서드 호출 ** override할때 이 훅 조심,
-> prestart : 기본 동작으로 해당 액터의 모든 자식 액터를 종료한 다음 poststop을 호출함, 이때 super.prerestart를 호출하지 않으면 기본 동작이 일어나지 않음
4.2.4. 생명주기 처리를 한데 모으기
4.2.5 생명주기 감시하기
부모만 자식 액터를 감독할 수 있는 것과 달리, 아무 액터나 다른 액터를 감시할 수 있다.
감시 대상 액터의 actorref를 알면 context.watch(actorref)를 호출하기만 하면 감독 대상 액터 종료 시 terminated 메세지를 받게 된다.
4.3 감독
4.3.1 슈퍼바이저 계층
4.3.2 미리 정의된 전략
4.3.3 사용자 정의 전략
4.4 요약
내고장성
- 감독은 일반 코드로부터 복구 코드를 깔끔하게 분리할 수 있다는 뜻
- 메세지 기반으로 액터 모델을 구축한다는 것은 액터 중 하나가 잘못되더라도 시스템이 여전히 정상 작동할 수 있게 한다는 것
- 계속 진행할 수 있고, 포기할 수도 있고, 재시작할 수도있다, 상황별 요구 조건에 따른 선택은 개발자가 알아서
- 슈펒바이저 계층 구조를 따라 문제를 위로 전달 할 수 있음
* 애플리케이션 실제 동작이 필요한 내용을 코드에서 뽑아내서 툴킷의 도움을 받아 그 작업을 더 구조적으로 수행한다.
[스터디 내용]
모든 액터에는 이름이 있고 이름은 같은 계층 내에서 유일해야함 - 같은 path level / sibling - 일반적인 folder directory 생각하면됨
actorRef, 우편함, 액터의 관계
dispatcher - mailbox에서 message를 꺼내주는 역할, 디스패쳐의 종류가 여러개있음- 사용자 정의 디스패쳐
가디언? != supervisor
fullname = path
actorselection
actor message 전달 pattern - tell, ask, forward, pipe
** dispatcher가 어떻게 굴러가는지
** single responsibility principle ㅋㅋㅋㅋㅋㅋㅋㅋㅋ.. oop solid
** Actor.class 보면 기본 정의 있음
** Props?
- properties 약자인가 ?
** 가디언 : https://blog.rajephon.dev/2019/02/17/akka-04/
** scala 동반객체? - scala에서는 object를 사용해서 factory pattern으로 많이씀
thread랑 akka 비교 ?
state - 실행중인지 아닌지 등등의 정말 상태
akka, thread 비교했을 때 akka actotr가 훨씬 경량임
Study 3. 액터사이의 통신, 액터관리 고장&예외 ,상태머신
출처: https://hamait.tistory.com/662?category=79128
1. 액터 사이의 통신 및 액터 멈추기
액터 사이의 통신 방법
통신 방법 | 방법 |
tell | 연산자 ! |
ask | 연산자 ? |
router | 메서드 forward |
액터 멈추기 방법
context.stop | 멈추게하자. (우편함의 메세지 날라감) |
Kill | 멈추진 말고 단순 재시작하게 하자. (우편함의 메세지 살아있음) |
PoisonPill | 어떤 메세지까지는 처리하고 중단하게하자. (PoisonPill 메세지전까지 모두 처리함) |
watch | 다른 액터가 끝날때까지 기다리게 하자. (액터 내부에서 기다림) |
greacefulStop |
다른 액터가 끝날때까지 기다리게 하자. (액터 외부에서 기다림) |
2. 액터 관리 (고장/예외처리하기)
OneForOneStrategy
AllForOneStarategy
여기선 OneForOneStrategy 라고 하나의 액터에 대해서 처리를 정의한다. AllForOneStarategy 는 모두에게 연대책임을 묻는다. (즉, 말썽을 부린 액터의 형제/자매 액터들에게) 한꺼번에 적용시킬 수도 있다.
3. 상태머신(상태따른 행동 변화)
http://wiki.webnori.com/display/AKKA/04.FSM+Actor
https://sslee05.github.io/blog/2018/05/10/akka-state/
유한상태기계(FSM, Finite State Machine)
receiver()
become?
--
Future
자바에서는 blocking..?
akka를 위한 것이 아니라, 비동기 처리를 위한 스칼라의 일반적인 오브젝트임
actor에서 exception이 발생하면 recover에서 값을 복구함 -> timeout이 지나면 recover에서 복구된 값을 future에서 가져감
감시는 액터의 ActorRef를 알기만 하면 누구나 가능한데, 감독은 부모 액터만 자식 액터에 대해서 가능하다.
context.watch를하면 acor에서 종료되는 메세지를 전달받음
onComplete , await
오류가나면 하위계층애들까지 다 죽었다가 다시 살아나기때문에 오류가능성이 높은 애를 가장 하위 계층으로 둔다.
unbecome - state를 복구시킴
trait - java의 abstract, interface
lazy val -> lazy를 사용하면 system을 사용하는 시점에 actorsystem을 생성한다.
--
원격노드, = 수평적 액터 확장 = 클러스터 구축 이런느낌으로 생각할 수잇을듯
my name is london,
excutionContext - theread pool을 관리 / ask 쓸 때는 excution context가 반드시 있어야한다. java의 excuteService
actor의 상태는 lifecycle처럼 정해진게아니라 사용자가 지정해서 만드는 것이다
case object = 단순한 message, case class = 뭔가 값이 있는
https://docs.scala-lang.org/ko/tutorials/scala-for-java-programmers.html
---
아카 클러스터링 개념
- 노드(Node)
- 클러스터의 논리적 구성원
- hostname:port:uid 튜플로 정의 - 노드가 클러스터를 떠나고 다시 합류시에는 새로운 uid를 할당해야함
- 클러스터(Cluster)
- 멤버십 서비스에 걸쳐 같이 묶여 있는 노드의 집합
- 클러스터의 모든 노드는 클러스터 내의 구성 요소와 통신하기 위해 현재 멤버의 상태를 알아야함
- Gossip Convergence컨버젼스 - 서로가모두의 상태를 아는 상태
- 클러스터에서 노드의 비집중화된 레지스트리를 유지하는데 가십 프로토콜(Gossip protocol)을 활용함
- 가십 프로토콜(Gossip protocol)
- 바이러스가 퍼지는 방식으로 동작하여 전염병 프로토콜(epidemic protocol) 이라고도 불림
- 소문과 같이 빠르게 퍼져나가 소문 프로토콜(rumor protocol)이라 부르고 싶음
- 즉, 마스터가 없는 대신 각 노드가 주기적으로 UDP/TCP로 서로 메타 정보를 주고 받음
- 이와 같은 방식을 통해 노드는 다른 노드가 살아 있는지 여부 파악
- 토렌트에서도 가십 프로토콜을 사용 ㅋ
- 리더(Leader)-마스터는 없지만 리더는 필요해
- 클러스터에서 리더로써 활동하는 하나의 노드
- Gossip Convergence 시점마다 리더가 결정 됨 - 멤버 리스트의 첫 번째 정렬된 노드로 정렬 기준은 노드 전체 주소)
- 리더는 통합 및 멤버십 상태 전이를 관리함
- 시드 노드(Seed nodes)
- 다른 노드가 클러스터에 합류하는 데 사용하는 노드의 집합
- 클러스터는 다중 노드를 유지하여 단일 장애 지점이 없도록 유지해야함
- 가장 먼저 응답한 시드 노드를 통해서 새로운 노드가 합류할 수 있음
- 장애 감지기(Failure detector)
- 노드가 클러스터의 다른 노드로부터 접속 불가능한지 감지하는 책임을 가짐
- 아카 클러스터는 파이 누적 장애 감지기를 사용함
- 실패했던 통계 이력을 기반으로 파이 점수를 계산하여 점수가 임계치(임계치 조정 가능) 초과시 해당 노드 접근 불가로 감지
- 접근 불가능 노드 처리
- 각 노드는 하트비트 프로세스를 통해 자신의 피어 중 몇몇에게 감시됨 →
접근 불가(파이값 임계치 초과)일 경우 클러스터에 알림 →
리더 노드에 의해 조치가 결정 됨 - 접근 불가일때는 Gossip Convergence가 진행 될 수 없기 때문에 빠르게 처리하여야 함
- 처리방법
- 사용자의 수작업으로 노드를 다운시킴
- 자동 다운 기능 사용
- 실서버 환경에서는 사용하지 않는 것이 좋음
- 노드 충돌시는 잘 작동함
- 네트워크 파티션에서는 잘 동작하지 않음 - 스플릿 브레인 현상 유발하여 파트별 자신만의 컨버전스 및 리더 선출을 수행하게 됨
- 각 노드는 하트비트 프로세스를 통해 자신의 피어 중 몇몇에게 감시됨 →
- 역할(Role)
- 클러스터 내 서로 다른 구성원에게 역할을 주는 체계를 제공함
- 각 구성원은 0부터 n개의 역할을 할당받을 수 있음
클러스터 샤딩
- 하나의 액터시스템의 여러 액터가 여러 네트워크에 걸쳐서 존재할 수 있게하는 것
'기타내용' 카테고리의 다른 글
블록체인 관련 링크 (0) | 2019.10.27 |
---|---|
Use Case Diagram (0) | 2019.10.15 |
API 호출 후 취소하기 (0) | 2018.10.26 |
Governance (0) | 2018.06.21 |
fidler ?? (0) | 2018.05.08 |