2011-01-13 2 views
2

P2P가 아닌 클라이언트 - 서버 기반의 인스턴트 메시징 응용 프로그램이 있다고 가정 해 봅니다. 실제 프로토콜은 중요하지 않습니다. 중요한 것은 서버 아키텍처입니다. 이 서버는 논 블로킹 소켓을 사용하여 단일 스레드, 비 병렬 모드로 작동하도록 코딩 할 수 있습니다.이 소켓은 정의에 따라 읽기 - 쓰기와 같은 작업을 즉시 또는 즉시 수행 할 수 있습니다. 비 블로킹 소켓의이 기능 덕분에 서버의 핵심 부분에서 일종의 선택/폴링 기능을 사용할 수 있으며 실제 소켓 읽기/쓰기 작업 시간을 낭비하지 않고이 모든 정보를 처리하는 데 시간을 소비 할 수 있습니다 . 적절하게 코딩되었으므로 이해하는 한 매우 빠를 수 있습니다. 그러나 두 번째 방법은 적극적으로 멀티 쓰레드를 만드는 것입니다. 새로운 스레드를 생성하는 것입니다 (어떤 종류의 스레드 풀을 사용하는 것은 분명합니다. 왜냐하면 바로 그 작업이 일부 플랫폼과 경우에 따라 느려질 수 있기 때문입니다) 병렬로 작업하는 반면, 기본 백그라운드 스레드는 accept()와 stuff를 처리합니다. 이 접근법이 인터넷을 통해 여러 곳에서 설명 된 것을 보았 기 때문에 분명히 존재합니다.Instant Messaging Server 디자인

이제 비 블로킹 소켓과 즉각적인 읽기/쓰기 작업 및 간단하고 쉽게 코딩 된 디자인이있는 경우 두 번째 변형이 왜 존재합니까? 두 번째 디자인, 즉 쓰레드로 극복하려는 문제는 무엇입니까? AFAIK는 일반적으로 느리고 가능하면 차단 작업을 처리하는 데 사용되지만 이러한 작업은 여기에있는 것처럼 보이지 않습니다!

답변

1

클라이언트마다 스레드가 있다고 말하는 것은 아닙니다. 일반적으로 이러한 디자인은 완전히 다른 이유로 사용되지만 스레드 풀은 각각 여러 개의 동시 클라이언트를 처리합니다.

arcitecture와 단일 스레드 서버의 이유는 단순히 다중 프로세서를 이용하는 것입니다. 단순히 I/O보다 많은 작업을 수행하고 있습니다. 메시지를 구문 분석하고, 다양한 작업을 수행하고, 더 많은 중량 암호화 알고리즘을 실행해야합니다. 이 모든 것은 CPU를 필요로합니다. 크기를 조정하려는 경우 다중 프로세서를 활용하면 더 많은 확장이 가능하고 클라이언트 당 대기 시간을 더욱 낮게 유지할 수 있습니다.

이러한 디자인에서 얻을 수있는 이점 중 하나는 멀티 스레드 환경에서 더 많은 잠금이 필요할 수 있지만 실제로 완료되고 실제로 수행중인 작업에 집중하면 약간의 차이가있을 수 있다는 것입니다. - 더 복잡한 것을 희생해서.

또한 OS 제한 사항을 해결하는 데 도움이 될 수 있습니다. 커널의 I/O 경로가 프로세서간에 더 많이 분산 될 수 있습니다. 모든 운영 체제가 단일 스레드 응용 프로그램에서 IO를 완전히 스레드 할 수있는 것은 아닙니다. 옛날에는 옛날에 * nix select()에 대한 훌륭한 대안이 없었습니다. 보통 1024의 filedesciptor 제한이 있었고 유사한 API는 너무 많은 소켓을 모니터하라는 말을 듣고 품질이 떨어지기 시작했습니다. 모든 클라이언트를 여러 스레드 또는 프로세스에 분산 시키면 이러한 한계를 극복하는 데 도움이되었습니다. 1에 관해서는

:

  • 쉽게 프로그래밍 모델, 버그를 찾기 위해 적은 하드로 이어질 수 있으며 구현 속도 : 스레드 간의 1 매핑은, 여러 가지 이유가 아키텍처를 구현할 수있다.

  • 블로킹 API를 지원합니다. 이것들은 모두 곳곳에 있습니다. 많은 수의/모든 클라이언트를 처리하는 스레드가 있고 데이터베이스에 대한 블로킹 호출을 수행하면 모든 사람이 마비됩니다. 파일을 읽는 것조차도 응용 프로그램을 차단할 수 있으며 일반적으로 IO 이벤트에 대한 일반 파일 핸들/설명자를 모니터 할 수 없습니다. 또는 가능할 때 프로그래밍 모델은 종종 매우 복잡합니다.

여기서 결점은 가장 널리 사용되는 언어/프레임 워크로는 확장되지 않는다는 것입니다.수천 개의 고유 스레드가 있으면 성능이 저하됩니다. 일부 언어는 얼랑 (Erlang)과 어느 정도까지는 가볍게 접근 할 수 있지만 여기서는 훨씬 더 가벼운 접근법을 제공합니다.

+0

사실, 정확히 1 : 1 클라이언트 : 스레드 매핑 디자인을 언급했습니다. 당신이 언급 한 하이브리드 디자인은 의미가 있으며 실제로 잘 알고 있습니다. 1 : 1 디자인에 대해 좀 더 자세히 설명해 주시겠습니까? – iksemyonov

+0

감사합니다 !!! 여기에 "Win32 fiber"만 추가 할 수 있습니다. 그건 내가 알고있는 유일한 가벼운 API이다. 그러나 일반적으로 그렇습니다. 당신이 말하는 것은 말이됩니다. 단일 스레드 모델에서 데이터베이스 호출을 막는 방법 (이 토론의 맥락에서 스레드와 스레드를 즉시 염두에 두는 것이 가장 명백한 방법입니다)을 피하는 방법은 무엇입니까? – iksemyonov

+0

섬유는 가벼울 수 있지만 차단 호출을 원할 경우 절약 할 수는 없습니다. 차단 호출을 피하는 것은 일반적으로 불가능하므로 1 : 1 모델이 일반적입니다. 일부 DB API는 비 차단 호출을 제공하지만 대부분은 그렇지 않습니다. 후자의 경우 비동기 패턴을 구현하고 (풀 풀) 차단 호출을 예약하고 완료되면 통지를받을 수 있습니다. 즉, 차단 호출을 처리하는 스레드 (많은 스레드)에 많은 클라이언트를 매핑 할 수 있습니다. 호출이 차단되는 속도와 각 호출에 걸리는 평균 시간에 따라 잘 작동하는지 여부에 달려 있습니다. – nos

관련 문제