2011-06-11 5 views
1

나는 Erlang을 사용하는 멀티 플레이어 보드 게임을위한 작은 네트워크 서버를 구축하고 있습니다. 이 네트워크 서버는 Mnesia DB의 로컬 인스턴스를 사용하여 연결된 각 클라이언트 응용 프로그램에 대한 세션을 저장합니다. 이 로컬 Mnesia에 저장된 각 클라이언트의 레코드 (세션) 내에 클라이언트의 PID와 NODE (클라이언트가 로그인 한 노드)를 저장합니다.멀티 클라이언트 응용 프로그램을위한 Erlang 네트워크 서버를 구축하는 올바른 방법입니까?

적어도 2 개의 연결된 서버 (노드 A & B)에이 네트워크 서버를 배포 할 계획입니다. 그래서 노드 A에 로그인 한 클라이언트 A가 노드 B에 로그인 한 클라이언트 B에 대해 Mnesia에 대한 쿼리를 검색하도록하려면 노드 A에서 노드 B로, 또는 노드 B에서 바이스 - 그 반대.

클라이언트 A가 클라이언트 B의 PID와 NODE를 조회 한 후에 클라이언트 A와 B는 서로 직접 통신 할 수 있습니다.

두 개의 다른 Erlang 노드에 로그인되어있는 두 개의 클라이언트 응용 프로그램간에 연결을 설정하는 올바른 방법입니까?

답변

3

둘 이상의 노드가 완벽하게 동기화되어있는 시스템을 만드는 것은 정의 상 불가능합니다. 그러나 실제로는 특정 문제에 대해 충분히 근접 할 수 있습니다.

두 노드에서 실행되는 정확한 이유를 말하지 않으므로 확장성에 대한 것이라고 가정합니다. 많은 노드를 사용하면 시스템이 더 유용 해지고 내결함성이 보장됩니다. 그러나 단일 노드에서만 실행되며 마스터를 사용할 수없는 경우 다른 노드를 핫 슬레이브로 전환해야하는 경우 문제가 단순해질 수 있습니다.

두 개의 서로 다른 노드에서 두 프로세스 간의 연결을 설정하려면 일부 전역 주소 지정 (사용자 ID 123은 pid < 123,456,0>)이 필요합니다. 한 번에 한 사용자 A가 실행중인 프로세스 하나만 신경 쓰면 잠금 장치가 필요하거나 주소 지정의 고유 등록 만 허용해야합니다. 자라기를 원한다면 시스템이 실행 중일 때나 중지 될 때 노드를 더 추가 할 수있는 방법이 필요합니다. 당신이 주소 준다 (주어진 키에 프로세스를 등록 할 수 있으며, 글로벌 모드에서

  • gproc :

    지금, 이미 다른 트레이드 오프와 함께, 귀하의 문제를 해결하는 데 도움이 밖에 몇 가지 해결책이 있습니다 잠금). 이것은 단일 실패 지점이없는 전체 클러스터에 배포되지만, 리더 선거 (적어도 내가 마지막으로 보았을 때)는 시스템이 시작될 때 사용 가능한 노드에서만 작동합니다. 새 노드를 추가하려면 실험 버전의 gen_leader가 필요하거나 시스템을 중지해야합니다. 자신의 코드 내에서, 두 명의 플레이어 만 서로 이야기 할 것이라는 것을 안다면, 같은 노드에서 시작할 수 있습니다.

  • riak_core를 사용하면 riak_core를 사용하여 KV 및 riak 검색에 사용 된 잘 테스트되고 입증 된 아키텍처를 기반으로 빌드 할 수 있습니다. 새 노드를 추가하고 키를 재배포 할 수있는 방식으로 키를 버킷에 맵핑합니다. 이 메커니즘에 연결하여 프로세스를 이동할 수 있습니다. 이 방법을 사용하면 프로세스를 시작할 위치를 결정할 수 없으므로 둘 사이에 많은 통신이 있으면 네트워크를 통해 이동하게됩니다.

  • 분산 트랜잭션과 함께 mnesia를 사용하면 트랜잭션이 커미트되기 전에 모든 노드에 데이터가 있음을 보장 할 수 있습니다. 이렇게하면 주소 지정과 잠금을 분산시킬 수 있지만이 모든 것을 수행해야합니다 (자물쇠를 풀 때처럼). 참고 : 프로덕션 환경에서는 분산 트랜잭션을 사용한 적이 없으므로 신뢰할 수있는 트랜잭션을 말할 수는 없습니다.또한 분산되어 있기 때문에 대기 시간이 필요합니다. 주 2 : 기억 상실을 멈추지 않고 가능한 경우 노드를 추가하고 테이블을 복제하는 방법을 정확히 확인해야합니다.

  • Zookeper/doozer/roll your own은 주소 지정을 저장하는 데 사용할 수있는 중앙 집중식 고 가용성 데이터베이스를 제공합니다. 이 경우 자신을 등록 해제 처리해야합니다. 시스템이 실행되는 동안 노드를 추가하는 것은 어드레싱의 관점에서 쉽지만, 애플리케이션에 새로운 노드에 대해 알리고 거기에서 프로세스를 생성하기위한 방법이 필요합니다.

또한 pid에는 메시지를 올바른 노드에 직접 보낼 수있는 충분한 정보가 들어 있으므로 노드를 저장할 필요가 없습니다.

이미 알고있는 멋진 트릭으로 pids는 이진 파일로 일련 번호를 지정할 수 있습니다 (VM 내의 모두 일 수 있음). term_to_binary/1binary_to_term/1을 사용하여 VM 내부의 실제 PID와 바이너리 데이터를 허용하는 바이너리를 바보 같은 방식으로 맹 글링하지 않고 이진 데이터를 허용합니다.

+0

설명 해 주셔서 감사합니다. Knutin :) ... 내가 얼랭 (Erlang, 6 개월)을 처음 보았을 것으로 추측 할 수 있듯이. –

+0

당신이 내 대답에 만족한다면, 당신은 그것을 "받아 들였습니다"라고 표시해야합니다. 나는 당신이 받아 들여지는 최상의 대답을 표시하지 않고도 답변 된 다른 질문을 한 것을 알아 챘다. StackOverflow가 작동하도록 의도 된 방식대로 표시해주세요. – knutin

+0

죄송합니다 ... "수락"버튼은 어디에 있습니까? 미안 나는 너를 정말로 알았어. 고마워. –

관련 문제