할리우드는 속도 및 저도 애플리케이션을위한 초고속 액터 엔진 빌드입니다. 게임 서버, 광고 중개인, 거래 엔진 등에 대해 생각해보십시오. 1 초 안에 천만 개의 메시지를 처리 할 수 있습니다.
액터 모델은 동시성과 분산 시스템을 구축하는 데 사용되는 계산 모델입니다. 1973 년 Carl Hewitt가 복잡한 시스템을보다 확장 가능하고 결함이있는 방식으로 처리하는 방법으로 소개했습니다.
배우 모델에서 기본 빌딩 블록은 액터이며, 때로는 할리우드에서 수신기라고도하는 행위자이며, 이는 메시지를 교환함으로써 다른 배우와 의사 소통하는 독립적 인 계산 단위입니다. 각 배우는 고유 한 상태와 행동을 가지고 있으며 메시지를 보내면 다른 배우와 만 의사 소통 할 수 있습니다. 이 메시지 통과 패러다임은 다른 행위자가 실패하거나 이용할 수 없어도 배우가 계속 독립적으로 작동 할 수 있기 때문에 고도로 분산되고 결함이없는 시스템을 허용합니다.
배우는 하위 수준의 행위자를 감독하고 조정하는 상위 수준의 배우와 함께 계층 구조로 구성 될 수 있습니다. 이를 통해 실패와 오류를 우아하고 예측 가능한 방식으로 처리 할 수있는 복잡한 시스템을 생성 할 수 있습니다.
애플리케이션에서 액터 모델을 사용하면 많은 동시 사용자와 복잡한 상호 작용을 처리 할 수있는 고도로 확장 가능하고 결함이없는 시스템을 구축 할 수 있습니다.
액터 실패에 대한 보장 된 메시지 전달 (버퍼 메커니즘)
Fire & Forget 또는 요청 및 응답 메시징 또는 둘 다
전송 계층으로서 고성능 DRPC
반사없이 최적화 된 프로토 버퍼
가볍고 사용자 정의가 가능합니다
분산 자체 발견 행위자를 작성하는 클러스터 지원
make bench
spawned 10 engines spawned 2000 actors per engine Send storm starting, will send for 10s using 20 workers Messages sent per second 3244217 .. Messages sent per second 3387478 Concurrent senders: 20 messages sent 35116641, messages received 35116641 - duration: 10s messages per second: 3511664 deadletters: 0
go get github.com/anthdm/hollywood/...
할리우드에는 골란 버전
1.21필요합니다
로컬에서 실행되는 몇 가지 예를 작성하여 시작하는 것이 좋습니다. 컴파일러가 사용 된 유형을 파악할 수 있으므로 로컬로 달리는 것이 약간 간단합니다. 원격으로 실행할 때는 컴파일러에 대한 프로토 버퍼 정의를 제공해야합니다.
Hello World 메시지를 살펴 보겠습니다. 전체 예제는 Hello World 폴더에서 사용할 수 있습니다. 메인에서 시작합시다 :
엔진, err : = actor (actor.newengineconfig ())
이것은 새로운 엔진을 만듭니다. 엔진은 할리우드의 핵심입니다. 배우 산란, 메시지 보내기 및 배우의 수명주기를 처리하는 데 책임이 있습니다. 할리우드가 엔진을 생성하지 않으면 오류를 반환합니다. 개발을 위해서는 엔진에 옵션을 전달하는 데 사용해서는 안됩니다. 나중에 옵션을 살펴 보겠습니다.
다음으로 배우를 만들어야합니다. 이들은 구현 해야하는 인터페이스 후 Receivers 라고 불리는 경우가 있습니다. 메시지를받을 때 메시지를 인쇄 할 새 배우를 만들어 봅시다.
PID : = Engine.spawn (Newhelloer, "Hello")
이로 인해 엔진이 ID "Hello"로 배우를 생성하게됩니다. 배우는 제공된 기능 newHelloer 에 의해 만들어집니다. ID는 독특해야합니다. PID에 포인터를 반환합니다. PID는 프로세스 식별자입니다. 배우의 고유 식별자입니다. 대부분의 경우 PID를 사용하여 배우에게 메시지를 보냅니다. 원격 시스템에서는 ID를 사용하여 메시지를 보내지 만 로컬 시스템에서는 주로 PID를 사용합니다.
newHelloer 기능과 그것이 돌아 오는 배우를 살펴 보겠습니다.
helloer struct {} func newhelloer () actor.receiver {return & helloer {}을 입력하십시오.
} 충분히 간단합니다. newHelloer 기능은 새로운 배우를 반환합니다. 배우는 배우를 구현하는 구조물입니다. Receive 방법을 살펴 보겠습니다.
유형 Message Struct {} func (h *helloer) 수신 (ctx *actor.context) {switch msg : = ctx.message (). actor.started : fmt.println ( "Helloer Starting") case actor.stopped : fmt.println ( "helloer worded") case *메시지 : fmt.println ( "Hello World", msg.data)
}
}메시지 구조를 정의하는 것을 볼 수 있습니다. 이것은 나중에 배우에게 보낼 메시지입니다. 수신 방법은 다른 몇 가지 메시지를 처리합니다. 이 수명주기 메시지는 엔진이 배우에게 전송되며,이를 사용하여 액터를 초기화합니다.
엔진은 actor.context를 Receive 방법으로 전달합니다. 이 컨텍스트에는 메시지, 발신자의 PID 및 사용할 수있는 다른 종속성이 포함됩니다.
이제 배우에게 메시지를 보내 드리겠습니다. message 보내 드리지만 원하는 모든 유형의 메시지를 보낼 수 있습니다. 유일한 요구 사항은 배우가 메시지를 처리 할 수 있어야한다는 것입니다. 메시지가 와이어를 건너 갈 수 있으려면 직렬화 할 수 있어야합니다. Protobuf가 메시지를 직렬화 할 수 있으려면 포인터 여야합니다. 로컬 메시지는 모든 유형 일 수 있습니다.
마지막으로 배우에게 메시지를 보내 드리겠습니다.
Engine.Send (PID, "Hello World!")
이것은 배우에게 메시지를 보냅니다. 할리우드는 메시지를 올바른 배우에게 라우팅 할 것입니다. 그런 다음 배우는 콘솔에 메시지를 인쇄합니다.
예제 폴더는 할리우드를 더 배우고 탐색하기에 가장 좋은 곳입니다.
배우를 스폰하면 새 배우를 반환하는 기능을 제공해야합니다. 배우가 스폰되면 제공 할 수있는 몇 가지 조정 가능한 옵션이 있습니다.
E.spawn (Newfoo, "Myactorname")
때때로 당신은 배우 생성자에게 인수를 전달하고 싶을 것입니다. 이것은 클로저를 사용하여 수행 할 수 있습니다. 요청 예제에는 이것의 예가 있습니다. 코드를 봅시다.
기본 생성자는 다음과 같습니다.
func newnameresponder () actor.receiver {return & nameresponder {name : "noname"}
}이름으로 새 배우를 구축하려면 다음을 수행 할 수 있습니다.
func NewCustomNamerEsponder (name String) actor.producer {return func () actor.receiver {return & nameresponder {name}
}
}그런 다음 다음 코드로 배우를 스폰 할 수 있습니다.
PID : = Engine.spawn (NewCustomNamerEsponder ( "Anthony"), "이름 표시")
e.spawn (Newfoo, "Myactorname", actor.withmaxRestarts (4), actor.withInboxsize (1024 * 2), actor.withid ( "bar"), )) ))
옵션은 매우 자기 설명이어야합니다. 최대 재시작 수를 설정할 수 있습니다. 이는 공황 상태의 경우 주어진 액터가 몇 번이나받은 편지함의 크기를 다시 시작 해야하는 경우 엔진을 알려주는 엔진을 알려줍니다. 차단합니다.
상태가없는 액터는 빠르고 단순하기 때문에 함수로 스폰 될 수 있습니다.
e.spawnfunc (func (c *actor.context) {switch msg : = c.message (). (type) {case actor.started : fmt.println ( "시작") _ = msg
}
}, "foo")액터는 원격 패키지로 네트워크를 통해 서로 통신 할 수 있습니다. 이것은 로컬 액터와 동일하지만 "와이어 위"와 동일하게 작동합니다. 할리우드는 Protobuf와의 직렬화를 지원합니다.
remote.new ()는 청취 주소와 remote.config struct를 사용합니다.
다음 코드로 새 리모컨을 인스턴스화합니다.
tlsconfig : = tlsconfig : & tls.config {인증서 : [] tls.certificate {cert},
} config : = remote.newconfig (). thetls (tlsconfig) 원격 : = remote.new ( "0.0.0.0:2222", config) 엔진, err : = actor.newengine (actor.newengineconfig (). withremote (remote) ))자세한 내용은 원격 액터 예제와 채팅 클라이언트 및 서버를 참조하십시오.
생산 시스템에서는 결국 잘못 될 것입니다. 액터는 충돌하고 기계가 실패하고 메시지가 마감일 대기열에서 끝납니다. 이벤트 스트림을 사용하여 이러한 이벤트를 우아하고 예측 가능한 방식으로 처리 할 수있는 소프트웨어를 구축 할 수 있습니다.
EventStream은 의존성없이 유연하고 플러그 가능한 시스템을 구축 할 수있는 강력한 추상화입니다.
다양한 시스템 이벤트 목록에 행위자 가입
사용자 정의 이벤트를 모든 가입자에게 방송합니다
배우가 처리하지 않은 이벤트는 삭제됩니다. 이벤트를 받으려면 이벤트 스트림에 배우가 가입해야합니다. 최소한 DeadLetterEvent 처리하고 싶을 것입니다. 할리우드가 배우에게 메시지를 전달하지 못하면 DeadLetterEvent 를 이벤트 스트림에 보냅니다.
actor.LogEvent log() 메소드가 설정 한 이벤트의 심각도 레벨, 메시지 및 이벤트 속성과 함께 actor.LogEvent log () 메서드가있는 이벤트의 속성을 사용하여 기본 로거에 로그인하는 모든 이벤트가 기본 로거에 로그인됩니다.
actor.ActorInitializedEvent , 액터가 초기화되었지만 actor.Started message 처리하지 않았습니다.
actor.ActorStartedEvent , 배우가 시작되었습니다
actor.ActorStoppedEvent , 배우가 멈췄습니다
actor.DeadLetterEvent , 메시지가 배우에게 전달되지 않았습니다.
actor.ActorRestartedEvent , 배우가 충돌/공황 후 다시 시작되었습니다.
actor.RemoteUnreachableEvent , 도달 할 수없는 리모컨으로 와이어 위의 메시지를 전송합니다.
cluster.MemberJoinEvent , 새로운 멤버가 클러스터에 가입합니다
cluster.MemberLeaveEvent , 새로운 멤버가 클러스터를 떠났습니다
cluster.ActivationEvent , 새로운 액터가 클러스터에서 활성화됩니다.
cluster.DeactivationEvent , 배우가 클러스터에서 비활성화됩니다
이벤트 스트림 사용 방법을 보여주는 EventStream 모니터링 예제가 있습니다. 두 명의 배우가 특징이며, 하나는 불안정하고 매 초마다 충돌합니다. 다른 배우는 이벤트 스트림에 가입하고 충돌 등과 같은 다른 이벤트에 대해 몇 가지 카운터를 유지합니다.
응용 프로그램은 몇 초 동안 실행되며 불안정한 배우의 독이 있습니다. 그런 다음 요청으로 모니터를 쿼리합니다. 액터가 엔진 내부에 떠 다니면서 이것이 당신이 그들과 상호 작용하는 방식입니다. 그런 다음 메인은 쿼리 결과를 인쇄하고 응용 프로그램이 종료됩니다.
기능 옵션 패턴을 사용하고 있습니다. 모든 기능 옵션은 액터 패키지에 있으며 "EngineOpt"로 이름을 시작합니다. 현재 유일한 옵션은 리모컨을 제공하는 것입니다. 이것은 이에 의해 수행됩니다
r : = remote.new (remote.config {haresaddr : addr}) 엔진, err : = actor.newengine (actor.engineoptremote (r))addr는 형식 "호스트 : 포트"가있는 문자열입니다.
수신기에 사용자 정의 미들웨어를 추가 할 수 있습니다. 이는 메트릭을 저장, actor.Started 에 actor.Stopped 데이터를 저장 및로드하는 데 유용 할 수 있습니다.
사용자 정의 미들웨어를 구현하는 방법에 대한 예는 예제 에서 미들웨어 폴더를 확인하십시오.
할리우드에는 로깅이 내장되어 있습니다. log/slog 패키지에서 기본 로거를 사용합니다. slog.SetDefaultLogger() 사용하여 기본 로거를 설정하여 Logger를 좋아하는 것에 대해 로거를 구성 할 수 있습니다. 이를 통해 로그 레벨, 형식 및 출력을 사용자 정의 할 수 있습니다. 자세한 내용은 slog 그 패키지를 참조하십시오.
이러한 이벤트는 actor.LogEvent Interface를 충족하므로 DeadLetterEvent 및 ActorStartedEvent 와 같은 일부 이벤트가 기본 로거에 로그인 될 수 있습니다. 자세한 내용은 위의 EventStream 섹션을 참조하십시오.
make test
질문과 좋은 대화를 위해 2000 명 이상의 회원과 Discord 커뮤니티에 가입하십시오.
이 프로젝트는 현재 다음 조직/프로젝트에서 생산에 사용됩니다.
센서라 IoT
할리우드는 MIT 라이센스에 따라 라이센스가 부여됩니다.