2012-11-14 2 views
3

이제 우리는 2 개의 얼랭 노드로 구성된 애플리케이션을 설계한다고 가정 해 보겠습니다. 노드 A에서는 매우 많은 프로세스가 수천 개가 될 것입니다. 노드 A에 노드 대 노드 처리량, 시간 초과 및 보증

 
start_server()-> 
    register(zeemq_server,spawn(?MODULE,server,[])),ok.
server()-> receive {{CallerPid, Ref}, {Module, Func, Args}} -> Result = (catch erlang:apply(Module, Func, Args)), CallerPid ! {Ref, Result}, server(); _ -> server() end.
, 실행하고자하는 모든 프로세스 : 노드 B 노드 B에서

에 등록 된 프로세스로 메시지를 전송하여 노드 B에 이러한 프로세스 액세스 자원은 다음과 같은 기능을 실행하여 시작하는 과정이 말할 수 그래서 노드 B에서 해당 프로세스 zeemq_server 가정
 
call(Node, Module, Func, Args)-> 
     Ref = make_ref(), 
     Me = self(), 
     {zeemq_server,Node} ! {{Me, Ref}, {Module, Func, Args}}, 
     receive 
       {Ref, Result} -> Result 
     after timer:minutes(3) -> 
      error_logger:error_report(["Call to server took so long"]), 
      {error,remote_call_failed} 
     end. 
, 아래 수 없을 것이며, 노드 A와 B 사이의 네트워크 연결이 항상 즉, 답변을하시기 바랍니다 : 노드 B에 해당 모듈의 모든 기능은 다음 코드 조각을 사용하여 다음 질문 :

QN 1 : 노드 B에 하나의 수신 프로세스가 있기 때문에, 그 메일 상자가 가득 차있을 가능성이 가장 높은 모든 시간. 이는 프로세스가 노드 A에서 많고 일정한 간격 (예 : 2 초)으로 모든 프로세스가 적어도 노드 B 서버에 대한 단일 호출을하기 때문입니다. 노드 B에서 어떤 방식으로 수신이 중복 될 수 있습니까? 예를 들어 프로세스 그룹 e.t.c 위의 서버 측 코드를 대체하는 방법 (개념)을 설명하십시오. 클라이언트 측에서 어떤 변화가 일어날 지 보여주십시오.

QN 2 : 노드 B에 하나 개의 수신기가있는 상황에서, 공정 메일 상자로 허용 메시지의 최대 수는있다? 단일 프로세스 메일 ox에 너무 많은 메시지가 넘치면 erlang이 어떻게 응답합니까?

Qn 3 : 위의 개념을 사용하면 요청을 보내는 모든 프로세스가 가능한 빨리 응답을 얻도록 보장 할 수 있습니까? 노드 B의 수신부를 병렬 작업으로 변환 할 수 있습니까? 이 같은
 
start_server()-> 
    register(zeemq_server,spawn(?MODULE,server,[])),ok.
server()-> receive {{CallerPid, Ref}, {Module, Func, Args}} -> spawn(?MODULE,child,[Ref,CallerPid,{Module, Func, Args}]), server(); _ -> server() end.
child(Ref,CallerPid,{Module, Func, Args})-> Result = (catch erlang:apply(Module, Func, Args)), CallerPid ! {Ref, Result}, ok.
이 방법은 전술 하였다, 노드 B에서 실행중인 프로세스의 일시 수를 증가 할 수 있으며, 이는 메모리에 크게 서비스에 영향을 미칠 수있다. 그러나, 그것은 좋아 보인다 및 server() 루프는 즉시 다음 요청을 처리 반환합니다. 이 수정에 대한 당신의 생각은 무엇입니까? 마지막으로

: 당신이 노드 B에 Pool of receiver Threads을 구현하는 예, 아직, 수신 메시지는 수신 스레드 사이에 다중화하고, 부하가 프로세스의이 그룹 내에서 공유 노드 A와 같은 관하여 하나 Name 아래로 등장 . 문제의 의미를 동일하게 유지하십시오.

감사합니다. Erlangers!

+0

이것은 java와 관련이 있습니까? –

+0

My Apologies @Quoi –

+0

너무 많은 답변을 얻지 못했지만 결국 나에게 묻지 않았던 것은 무엇이냐고 묻습니다. –

답변

2

처리 사서함 메시지의 최대 수는 메모리의 양을 제외하고, 무제한이다.

[{message_queue_len,0},{messages,[]}] 

내가 제안하는 것은 당신이 먼저 gen_server에 위의 서버를 변환하는 것입니다 : 사서함 크기를 검사해야하는 경우도

,이 같은 뭔가를 반환합니다

erlang:process_info(self(),[message_queue_len,messages]). 

를 사용 . 이 사람.

다음으로 poolboy (https://github.com/devinus/poolboy)를 사용하여 서버 인스턴스를 풀 보이 작업자로 만들 것을 제안합니다 (github Readme.md에 예제가 있음). 마지막으로, 풀 보이스 트랜잭션을 생성하고 풀에서 Worker arg를 함수에 적용하는 도우미 메서드를 사용하여 호출자를위한 모듈을 만드는 것이 좋습니다.그들의 github에서 cribbed의 예 :

squery(PoolName, Sql) -> 
    poolboy:transaction(PoolName, fun(Worker) -> 
            gen_server:call(Worker, {squery, Sql}) 
            end). 

그렇다면 Erlang RPC는 당신의 필요에 더 잘 어울리겠습니까? Erlang RPC에 대한 자세한 내용은 http://www.erlang.org/doc/man/rpc.html입니다. Erlang RPC의 좋은 치료법은 http://learnyousomeerlang.com/distribunomicon#rpc입니다.

+0

+1, 좋은 답변입니다! –

0

각 요청을 처리하기위한 새로운 프로세스를 생성하는 IMO는 잔인한 행위 일 수 있지만 각 요청에 대해 수행해야 할 작업을 모른 채 말하기는 어렵습니다.

라운드 로빈 방식을 사용하여 요청을 배포하거나 처리하는 요청 유형에 따라 처리하거나, 자식 프로세스로 보내거나 프로세스를 생성하여 각 메시지를 처리하는 프로세스 풀을 가질 수 있습니다. 또한 msg 대기열을보고 오버로드 된 새 자식을 시작하여 풀링 된 프로세스의로드를 모니터 할 수 있습니다. 슈퍼 바이저를 사용하면 init에서 send_after를 사용하여 몇 초마다 부하를 모니터링하고 그에 따라 작동합니다. 가능한 경우 OTP를 사용하십시오. 오버 헤드가 있지만 그만한 가치가 있습니다.

전용 회선 통신을 위해 http를 사용하지 않을 것이므로 오버 헤드가 너무 많습니다. 처리 할 풀을 사용하여로드를 제어 할 수 있습니다.