2014-05-21 2 views
1

크래시가 발생하는 gen_tcp : listen-thread에 관리자를 추가하는 것이 실제로 해당 작업자를 다시 시작하는 방법을 알지 못합니다. 부서지는 것이 항구를 렌더링 할 것이기 때문에 나는 짧은 순간 동안 쓸모없는 것을 듣고 싶다. 충돌이 발생하고 응용 프로그램을 수동으로 다시 시작하려고하면 "{error, eaddrinuse}"메시지가 나타납니다. 나는 그것이 작동 할 방법을 보지 못했기 때문에 아직이 작업자에 대한 관리자를 수행하지 않았다.Erlang OTP 슈퍼 바이저 gen_tcp - {error, eaddrinuse}

gen_tcp : 어떻게 다시 시작합니까?

+0

때때로 포트가 잠겨 있어도 포트가 여전히 사용중인 것처럼 보입니다. 이유를 모르겠다. – rvirding

+0

@rvirding - 소켓에 보류중인 연결이있는 경우에 분명합니다. 보류중인 연결이 없으면 즉시 CLOSED 상태로 진행해야합니다. Alexander - reuseaddr의 사용에 관한 Paul의 대답을 참조하십시오. 응답이 도움이 되더라도 서버에 사용해야합니다. –

답변

0

gen_tcp 소켓을 관리하는 프로세스가 gen_server입니까? 그렇다면 인생이 더 쉬워 질 것입니다.

gen_server 인 경우 init 함수에 process_flag(trap_exit, true)을 추가하십시오. 이렇게하면 프로세스가 "충돌"할 때 프로세스를 실제로 종료하기 전에 terminate/2 콜백 함수를 호출 할 수 있습니다. 이 방법을 사용하면 terminate 함수에서 청취 소켓을 수동으로 닫을 수 있으므로 포트 정리 지연을 피할 수 있습니다.

gen_server를 사용하지 않는 경우에도 동일한 원칙이 적용되지만 오류를 잡는 방법에 대해 훨씬 더 분명하게 밝혀야합니다.

+0

또는 "수신자"와 별도의 프로세스에서 청취 소켓을 시작할 수도 있습니다. 이 프로세스는 소켓 저장소 역할을하는 것 이상의 아무것도 수행하지 않아야합니다. 따라서 충돌이 발생하지 않도록해야합니다. 이것은'gen_tcp : accept'가 여러 프로세스에서 동시에 호출 될 수 있기 때문에 가능합니다. –

+0

빠른 답장을 보내 주셔서 감사합니다! 나는 gen_server를 실행하고 있기 때문에 함정을 추가하려고 노력할 것입니다. 허용/수신 - 응용 프로그램이 충돌하는 경우 실제로 충분합니까? –

+0

전체 응용 프로그램이 충돌하는 경우 책임을 분리해도 같은 문제가 발생합니다. 그러나 trap_exit을 정말로 필요로하는 곳에서만 지정하고 클라이언트 프로세스가 적절할 때 정상적으로 중단되게함으로써 유용하게 사용할 수 있습니다. 또한, 당신을 위해 많은 것들을 돌볼 수있는 목장 (https://github.com/extend/ranch)을 살펴보십시오. –

1

대부분의 경우 청취 소켓이 제어 프로세스 (프로세스를 생성 한 프로세스)에 연결되어 있기 때문에이 프로세스가 종료되면 소켓이 제대로 닫히고 동일한 포트에서 다시 수신 할 수 있습니다.

기타 모든 경우에는 {reuseaddr, true} 옵션을 gen_tcp:listen/2으로 전달해야합니다. 실제로 응용 프로그램의 청취 소켓은 충돌 후 잠깐 동안 활성 상태로 유지되며이 옵션을 사용하면이 기간 동안 주소를 다시 사용할 수 있습니다.

+0

reuseaddr은 사용자가 제안한 목적과 다른 용도로 사용됩니다. 그것은 실제로 그 목적을 위해 작동 할 수 있지만, 잘못 사용하면 부작용을 일으킬 수도 있습니다. –

+0

reuseaddr은 정확히 OP를 차단하는 것이며, 복구 할 수없는 크래시에 필요합니다. 목장은이 옵션도 사용합니다. –

+0

reuseaddr의 목적은 서버가 이미 사용 된 포트를 재사용하도록 허용하는 것입니다. 그러나이 특정 문제를 해결하는 더 좋은 방법이 있습니다. 즉, 종료시 청취 소켓의 적절한 정리, 목장 * 않습니다. reuseaddr을 더 잘 사용하면 수천 명의 단명 고객을 관리하는 대용량 서버에 적합합니다. –

관련 문제