3

많은 동시 요청을 처리하고 비동기 적으로 처리해야하는 프로젝트의 서버 데몬을 설계하고 있습니다. 저는 그러한 프로젝트의 순수한 규모에 대해 알고 있습니다. 그러나 저는 그것에 대해 진지하게 생각하고 앞으로 나아 가기 전에 명확한 설계와 계획을 세우려고 노력하고 있습니다.서비스에서 들어오는 요청을 처리하는 아키텍처

여기 내 목표의 목록입니다 :

  • 확장 성 - 다중 프로세서 또는 여러 서버에 아키텍처를 병렬 처리 할 수 ​​있어야합니다.
  • 엄청난 수의 병렬 연결에 대처하는 능력.
  • 하나의 요청이 처리하는 데 시간이 오래 걸리면 차단 문제가 발생하지 않아야합니다.
  • 응답 소요 시간 요청은 최소화해야합니다.

    Architecture Flow Chart

    : .NET Framework를 중심으로

  • 그래서 여기 내 초기 설계의 차트입니다,

내 제안 된 구조와 흐름이 다소 복잡하다 (C#으로이 글을 쓰는 것) (그리고 심하게 크기가 조정될 경우)

아이디어는 네트워크를 통해 요청이 들어오는 것입니다 (TCP/UDP가 아직 최상인지 결정하지는 않았지만). immediat가 전달됩니다 고속로드 밸런서에 그런 다음로드 밸런서는 가중치 난수 생성 프로그램을 사용하여 요청을 배치 할 요청 큐 (RQ)를 선택합니다. 가중치는 각 대기열의 크기에서 파생됩니다. 가중치가 적용된 RNG를 사용하는 이유는 요청을 가장 사용량이 적은 대기열에 배치하는 것보다는 빈이지만 차단 된 대기열 (정지 된 요청으로 인해)이 전체 서버를 잠그는 것을 방지하기 때문입니다. 모든 RQ가 특정 크기를 초과하면로드 밸런서가 요청을 삭제하고 출력 대기열 (OPQ)에 "서버 사용량이 많음"응답을 표시합니다. 이 부분은 다이어그램에 표시되지 않습니다.

각 대기열은 서버의 CPU 코어 하나에 친화력이 설정된 스레드에 해당합니다. 이 스레드는 병렬 요청 프로세서의 일부로 각 큐에서 요청을 사용합니다. 요청은 세 가지 유형 중 하나로 분류됩니다

  1. 즉시 - 즉각 요청은, 이름에서 알 수 있듯이, 즉시 처리.

  2. 지연 가능은 - 지연 가능 요청이 낮은 우선 순위로 간주됩니다. 이들은 낮은로드 중에 즉시 처리되거나 높은로드 인 경우 지연된 요청 대기열 (DRQ)에 배치됩니다. 로드 밸런서는 DRQ에서 이러한 지연된 요청을 가져와 즉시로 표시 한 다음 적절한 RQ에 다시 배치합니다.

  3. 시간 지정 - 시간 요청은 대상 시간 소인과 함께 시간 요청 큐 (TRQ)에 배치됩니다. 이러한 요청은 종종 클라이언트가 명시 적으로 보내지 않고 다른 요청의 결과로 생성됩니다. 요청 타임 스탬프가 초과되면 다음 사용 가능한 요청 프로세서 스레드가 요청 타임 스탬프를 소비하고 처리합니다.요청이 처리 될 때

는 데이터 키/값 쌍 캐시 또는 디스크, 또는 전용 SQL 데이터베이스 서버로부터 메모리에 한 쌍의 키/값 캐시로부터 페치 할 수있다. 캐시 된 값은 BSON이고 인덱스는 문자열입니다. 나는이 메모리를 구현하기 위해 Dictionary<T1,T2>을 사용하고, 디스크 캐쉬를 위해서는 btree (또는 유사)를 사용하려고 생각하고있다.

응답이 처리가 완료되면 생성되고 출력 대기열 (OPQ)에 배치됩니다. 그런 다음 루프는 OPQ에서 응답을 소비하고이를 네트워크를 통해 다시 클라이언트로 전송합니다. OPQ가 최대 크기의 80 %에 도달하면 요청 프로세서 스레드의 1/4이 중지됩니다. OPQ가 최대 크기의 90 %에 도달하면 요청 프로세서 스레드의 절반이 중지됩니다. OPQ가 최대 크기에 도달하면 모든 요청 프로세서 스레드가 중지됩니다. 이는 개별 요청 프로세서 스레드가 막히거나 부실한 요청을 남기지 않도록하는 세마포어로 수행됩니다.

  • 내가 놓친이 아키텍처에 대한 주요 결함이 있습니까 : 내가 무엇을 찾고

    몇 가지 분야에 대한 제안입니까?

  • 성능상의 이유로 변경해야 할 사항이 있습니까?
  • TCP 또는 UDP가 요청에 더 적합합니까? TCP가 제공하는 "배달 증명"을 갖는 것이 매우 유용 할 것이지만 UDP의 경량 성은 매력적입니다.
  • Windows 서버에서 100k + 동시 연결을 처리 할 때 특별히 고려해야 할 사항이 있습니까? 나는 리눅스의 TCP 스택이 잘 다뤄지는 것을 알고 있지만, 윈도우에서는 그렇게 확신 할 수 없다.
  • 다른 질문이 있습니까? 나는 무엇이라도 생각하는 것을 잊었 느냐?

나는 이것이 많이 읽었으며, 아마도 너무 많이 물어 보았다는 것을 알고 있습니다. 감사합니다.

다이어그램의 업데이트 된 버전 here.

+0

어떻게이 프로젝트는 거지/어떻게하려고? 그것에 대한 모든 블로그 게시물? 나는 그 길을 따라 무엇을 배웠는지와 어떤 결론에 도달했는지에 대해 매우 흥미가 있습니다. – Tyson

답변

2

또한 당신은 다음 고려할 수 :

  • 장애 조치. 서비스가 다시 시작된 후에도 모든 보류중인 요청이 처리되도록 가능한 서비스 충돌이 발생할 때까지 지속 요청에 대한 접근 방식을 설계 할 수 있습니다.
  • 오류 대기열. (Dead Letter Channel 패턴이라고도 함)
  • Pipes and Filters. 이러한 기능을 제공하면 서비스의 유연성과 확장 성이 매우 뛰어납니다.
  • 요청 확인. 사전 정의 된 시간 간격에서 CorrelationId가 초기 RequestId로 설정된 Ack 메시지를 기다리는 서비스에 요청을 보낸 클라이언트는 이러한 방식으로 클라이언트가 특정 요청이 수신되어 인바운드 대기열에 배치되었음을 클라이언트가 알릴 수 있습니다. 그냥 보낸 요청에 대해 Ack를받습니다. 다시 보내거나 실패로 표시 할 수 있습니다.

PS : 또한 내가 좋은 책을 건의 할 것 "Enterprise Integration Patterns"

+0

장애 조치 (failover)의 장점이 있습니다.각 인스턴스는 별도의 서버에서 실행되기 때문에 요청이 어느 서버로 전송되는지는 중요하지 않으며 서버가 다운되면 다시 균형을 조정하게됩니다. 그러나 보류중인 요청으로 무언가를하는 것에 대한 아이디어는 고려하지 않았습니다. 아마도 나는 데몬이 충돌 할 경우를 대비해 디스크에 복제물을 보관해야하지만, 전체 시스템이 다운 될 경우 잃어버린 요청을 고려해야 할 것입니다. 더 좋은 아이디어? – Polynomial

+0

명확한 설명 : 필요한 응답 시간은 실제 서버가 다운 된 경우 재부팅 시간이 너무 길어서 요청이 여전히 관련성이 있음을 의미하므로 디스크 대기열을 버려야합니다. – Polynomial

0

이 아주 잘 확장하려는 경우 모든 구성 요소가 확장되어 있는지 확인해야합니다 - 프로세싱 요소, 입력/출력 조각, 그리고 큐. Microsoft 스택에서이 작업을 수행하려는 경우 Windows Azure를 검토하는 것이 좋습니다. Windows Azure는 필요한 기능을 모두 제공하지는 않지만 대부분을 제공합니다. 언급하지 않은 한 가지 - 영구 저장 영역 (예 : 데이터베이스)이 있습니까? 그렇다면 그것을 확장 할 준비를하십시오. 그렇지 않으면 단일 실패 지점이됩니다.

+0

데이터베이스가 다이어그램에 나와 내 질문에 언급했다. 또한 Azure를 사용하고 싶지 않습니다. 오히려 어플리케이션에 논리를 적용하는 편이 낫습니다. 그 이유는 다른 호스트 (고객 호스트 포함)의 범위에서 설치 가능하게하고 자체 인스턴스 또는 공유 인스턴스의 일부로 작동하게하려는 것입니다. – Polynomial

+0

죄송합니다 - 이미지가 현재 위치에서 차단되어 게시물의 DB 참조가 누락되었습니다. "내 응용 프로그램이 논리를 수행하는"경우, Azure의 확장 성 기능을 사용하여 논리를 조정하는 능력을 제거하는 방법을 알지 못합니다. 고객 호스트에 설치된 응용 프로그램은 "공통"인스턴스를 사용하거나 별도의 계정을 사용하여 설치를 "사유화"할 수 있습니다. –

+0

나는 특정 고객이 Azure를 구입하거나 설치하지 않고도 내 서버의 "팜"을 운영 할 수 있기를 바랍니다. 나는 또한 값 비싼 소프트웨어 의존으로부터 벗어나고 싶다. – Polynomial

1

왜 여러 요청 대기열이 필요한지 이해가되지 않습니다. 여러 개의 프로세서가 모두 하나의 요청 대기열을 필요로한다는 것을 알았습니다. 큐 시스템에 문제가 있어서는 안됩니다. 대기열을 하나만 사용하면 프로세서에서 입력을 분리하여 더 나은 확장 성을 확보 할 수 있습니다. 필요한 경우 더 많은 프로세서를 가동하고 아무도 신경 쓰지 않아도됩니다.

TCP와 UDP의 비교 - 어떤 성능을 찾고 있습니까? ZeroMQ와 같은 기존 통신 인프라를 사용하여 이러한 기술을 처리하는 것이 더 좋지 않습니까?

Itay.

+0

여러 요청 대기열을 갖는 아이디어는 요청 유형 중 하나의 하위 집합을 선호하도록 특정 대기열을 특수화하는 아이디어에서 기인합니다. 이를 통해 특정 메시지 유형을 좀 더 빠르게 처리 할 수 ​​있도록 코드를 조정할 수 있습니다. TCP/UDP/뭔가 다른 측면에서, 나는 내가 무엇이 필요한지 정말로 모른다. 나는 네트워크 프로토콜과 직접 인터페이스하고 싶다. 그러나 그것은 내가 .NET이 지원하는 것으로 제한된다는 것을 의미한다. (TCP와 UDP 뿐이다). – Polynomial

+0

나는 거기에 가지 않을 것이다. 대기열이 우선 순위를 지원하면 (일부 대기열 시스템에서는 MSMQ가 작동하는지 기억하지 못합니다.), 집에는 무료입니다. 일반적으로 나는 당신이 이미 발명 된 많은 것을 재발 명하려고 노력하고 있다고 생각합니다. 오픈 소스입니다. 네트워크를 통해 작업을 시작하기 전에 몇 가지 기존 대기열 처리 시스템을 살펴볼 것입니다. 또한 성능 지향적 인 방법이 확실하지 않더라도 WCF를 살펴보십시오. – zmbq

+0

아마도 여러 대기열을 유지해야하지만 단순히 다른 메시지 우선 순위를 저장하는 데 사용하십시오. 그렇게하면 부하 분산 장치를 큐의 다른 쪽으로 옮기고 프로세스에서 내부 구성 요소를 단순화 할 수 있습니다. – Polynomial

관련 문제