지난 일주일 동안 저는 가상 배우 개념을 연구하며 소프트웨어 개발에 도전했습니다. 결국 두 가지 다른 프레임워크를 살펴보게 되었습니다: Dapr과 Orleans.
두 프로젝트 모두 매우 간결하고 흥미로운 사용 사례가 많습니다. 두 경우 모두 '가상' 액터라는 개념을 사용합니다. 가상 액터는 다음과 같은 상태 및 논리 유닛입니다:
- ID로 고유하게 식별할 수 있습니다
- 단일 스레드입니다
- 메모리 내 또는 영속 구조일 수 있으며, 프레임워크가 그 수명주기를 관리합니다
저는 가상 액터라는 개념이 정말 마음에 들고, 복잡한 작업 흐름을 처리할 수 있는 확장 가능하고 신뢰할 수 있는 도구를 만드는 데 매우 도움이 된다고 생각합니다. 각 작업이 단일 스레드 가상 참가자라면, 경쟁 조건 문제는 사라집니다.
Orleans와 Dapr 모두 마이크로소프트 프로젝트이기 때문에, 저는 마이크로소프트 카페테리아에서 서구 이야기 스타일의 대결을 상상합니다.
오를레앙
유튜브에서 관련 영상을 보고 오랜 시간 관심을 가져왔던 Orleans부터 시작했어요. 처음에는 모든 NuGet 패키지의 4.x 버전을 사용할 거라고 생각해서 처음에는 정말 안 좋았어요. 하지만 그들의 문서는 4.x 패키지와 전혀 호환되지 않습니다. 결국 3.6.2 버전을 사용했습니다.
곡물 / 상태 / 타이머
자신의 상태를 추적하고 동작을 수행하는 그레인을 만드는 것은 매우 간단합니다. 그레인 영속성을 위한 문서를 따라 IGrainStorage 자체 CosmosDB(SQL API) 구현도 만들 수 있었습니다.
미리 알림
알림도 쉽게 설정할 수 있습니다. 하지만 실제 지속성 설정을 시도해보려 했습니다. 현재 제 연구는 모든 것을 깔끔하게 유지하고 ComsosDB에 저장하려고 노력 중입니다. 안타깝게도 Orleans의 리마인더 지속 패키지가 전혀 작동하지 않습니다. 결국 AzureStorage 패키지로 전환해야 했습니다. 그래서 이제 제 데이터는 절반은 SQL API 계정에, 나머지 절반은 테이블 API 계정에 있습니다.
스트림
거기서 잘 안 됐어요. Orleans에서는 플로우가 GUID와 선택적 네임스페이스로 식별됩니다. 스트림을 GUID로 식별해야 하는 데는 분명 이유가 있을 텐데, 와, 그건 비현실적이네요.
스트림을 쉽게 만들 수 있었는데, 프로젝트를 멈추고 재시작하고 새 이벤트를 실행하면 모든 게 크래시가 나서 매우 답답합니다.
이어서 매우 귀중한 정보가 있습니다. Orleans 코드를 역설계하는 데 8시간이 걸렸습니다:
그레인이 스트림 구독자일 경우, 그레인은 OnActivateAsync 메서드에서 구독 핸들에 대해 ResumeAsync를 호출해야 하며, 그렇지 않으면 인식되지 않은 오류가 발생해 크래시가 발생할 수 있습니다.
같은 구독이 중복되는 문제도 있었는데, 그 코드를 사용해 곡물 구독을 모두 삭제한 후 다시 만들었습니다:
다른 올리언스 함정 / 팁
Streams는 Azure Event Hubs(AddEventHubStreams 경유)와 잘 작동합니다.
CosmosDB SQL API의 Grain 이름에 /또는 다른 특수 문자를 사용하지 마세요!
오를레앙 결론
저는 오를레앙을 좋아하고 잠재력이 있다고 생각합니다. 하지만 학습 곡선이 매우 가파릅니다. 스트리밍에 오랜 어려움을 겪어서 클러스터나 배포가 어떻게 작동하는지 공부할 시간이 없습니다.
다프르
저는 오를레앙 대안을 찾다가 Dapr을 알게 되었습니다. 이 프로젝트가 마이크로소프트가 후원하는 프로젝트라는 점이 좀 이상하네요. 아마도 그들은 적자생존 방식을 택하러 온 것일지도 모릅니다. 만약 그렇다면, Dapr는 생존자가 될 거라고 생각합니다.
첫째, Dapr의 REST/gRPC 기반 설계는 어떤 프로그래밍 언어로든 액터를 구현할 수 있게 합니다. 또한 모든 것(참가자, 상태, 타이머, 알림, 이벤트)을 하나의 Redis 인스턴스에서 실행하는 것이 매우 간단하다고 느꼈습니다. 게다가 Dapr을 사용하기 시작하는 데 3분의 1 정도 걸렸습니다. 이렇게 빠른 시작 시간은 Dapr의 훌륭한 문서 작업 덕분입니다.
배우 / 타이머 / 알림
제가 방금 Dapr의 문서가 훌륭하다고 말했나요? 사실 JavaScript 예제를 제외하면 어디에나 있습니다. 저는 대부분의 시간을 Dapr에서 배우에게 메서드를 호출하는 방법을 찾으려고 노력하며 보냅니다. Dapr 자바스크립트 샘플의 코드는 다음과 같습니다:
이 주장은 명백히 구식입니다. 이 세 줄을 Dapr의 테스트/샘플 코드 탐색을 통해 유도하는 데 많은 시간을 들여야 했습니다
상태 생성/설정 코드 예제들도 비슷한 문제가 있어서, 그들을 위해 GitHub 이슈를 만들었습니다.
그런 사소한 문제들을 제외하면, 배우를 설정하는 것은 식은 죽 먹기다.
캐스트들의 타이머와 알림을 설정하는 것도 매우 쉽습니다.
상태
저는 Dapr을 Postgres와 함께 유지하도록 쉽게 설정할 수 있었습니다.
제가 느낀 한 가지는 알림 저장 방식에 확장성 문제가 있을 수 있다는 점입니다. Dapr은 특정 참가자 유형에 대한 모든 알림을 단일 JSON 배열에 저장합니다. 누군가 알림이 너무 많으면 어떻게 되나요?
다른 Dapr 관련 문제점 / 팁
JavaScript SDK 코드를 둘러보면서 한 가지 눈에 띄는 점은 코드베이스에 주석이 거의 없다는 것입니다. 이로 인해 무언가를 알아내는 것이 거의 불가능해집니다. 예를 들어, 상태 관리자의 addOrUpdateState 메서드에는 updateValueFactory라는 세 번째 매개변수가 있습니다. 코드에 주석이 없으면 콜백이 무엇을 위한 것인지 거의 알 수 없습니다.
또한 redis 컨테이너를 설정하고 실행하는 데 "dapr init" 명령어가 얼마나 마음에 드는지도 잘 모르겠습니다. 이미 redis 컨테이너가 있다면 어떻게 되나요? 만약 포스트그레스를 사용하고 싶다면요? dapr init 기능을 변경하는 방법에 대한 문서를 찾을 수가 없습니다.
pubsub 사용에 어려움을 겪는 분들께 한 가지 안내입니다. 출판사와 구독자 모두를 실행하려면 반드시 "dapr run"을 사용해야 합니다:
액터와 퍼블리브의 경우, --app-port 매개변수를 사용하여 dapr에 서비스가 어느 포트에서 실행 중인지 알려주는 것이 중요합니다. pubsub 이벤트와 actor 호출은 Dapr 사이드카에서 http 호출을 통해 귀하의 서비스로 전송되므로, 어디로 보내야 하는지 알아야 합니다:
저는 집 네트워크의 두 대의 다른 기기에서 pubsub 가입자 인스턴스를 실행해 작은 Dapr 자체 호스팅 "클러스터"를 테스트했습니다. 그냥 잘 됐어요!
DAPR 결론
분산 애플리케이션이나 가상 액터에 대해 더 알고 싶다면 Dapr부터 시작하는 것을 추천합니다. Orleans는 원조 개척자였고, Dapr은 한 단계 더 높은 리부트였다.
원본 링크:하이퍼링크 로그인이 보입니다.
|