다음은 고성능 소켓 컴포넌트를 구현할 때 겪는 문제점에 대한 요약입니다. 수천 개의 동시 애플리케이션만 처리하면 된다면 코드 작성에 집중할 수 있지만, 수만 또는 수만 개의 동시 애플리케이션을 처리해야 합니다. 다음 질문들의 요약은 이 지원서 작성에 큰 도움이 될 것으로 여겨집니다.
소켓AsyncEventArgs
이 객체는 .NET 2.0 sp1 이후에 제공되었으며, 주로 고성능 소켓 데이터 송수신 처리를 구현하는 데 사용됩니다(더 자세한 소개는 MSDN을 참고하세요). 이 객체는 송수신 관련 전송을 위한 버퍼를 설정하는 세 가지 방법을 제공합니다: SetBuffer(Int32, Int32), SetBuffer(Byte(), Int32, Int32, BufferList, 앞의 두 가지는 후자와 공존할 수 없습니다 ( MSDN에서 그 이유를 설명하고 있습니다). 버퍼를 설정할 때, SetBuffer(Byte(), Int32, Int32, BufferList 등 어떤 것이든 프로그램 수명 동안 SocketAsyncEventArgs 인스턴스당 한 번만 설정하도록 하세요. 이 설정은 매우 자원을 많이 소모할 수 있습니다. SocketAsyncEventArgs 구축 시 SetBuffer(Byte(), Int32, Int32)를 통해 데이터 버퍼를 설정한 후 SetBuffer(Int32, Int32)를 사용해 처리하는 것이 권장됩니다. 버퍼리스트를 설정하고 싶을 때는 <byte>IList가 참조하는 바이트[] 소스를 변경하지 않는 것이 좋습니다<ArraySegment>. 변경하면 SocketAsyncEventArgs가 버퍼를 다시 바인딩하여 효율성에 영향을 줄 수 있습니다.
SocketAsyncEventArgs 풀
앞서 언급했듯이, 이 목표를 달성하기 위해 SocketAsyncEventArgs가 참조하는 버퍼를 최대한 변경하지 않는 것이 좋습니다. 따라서 SocketAsyncEventArgs 애플리케이션 풀을 구축하고 프로그램 시작 시 가능한 한 SocketAsyncEventArgs 객체를 초기화하는 것이 필요합니다. SocketAsyncEventArgs 생성 감소 외에도, 풀을 구성하면 메모리를 크게 절약할 수 있습니다. 주요 이유는 각 메시지의 크기를 알 수 없기 때문입니다. 물론 설계 전에 메시지 최대 한도를 설정한 후 SocketAsyncEventArgs에 대응하는 버퍼를 설정할 수 있습니다. 하지만 모든 메시지에 최대 길이가 있는 것은 아니기 때문에 메모리 낭비입니다. SocketAsyncEventArgs에 적절한 버퍼 크기를 할당하고, 풀을 통해 호출을 제공하며, 하나 이상의 SocketAsyncEventArg에 메시지를 유연하게 쓰거나, 여러 메시지를 하나의 SocketAsyncEventArgs에 저장하여 처리할 수 있습니다.
대기열
많은 관행이 데이터를 받은 후 스레드를 직접 열거나 스레드 풀에 버리는 방식을 보는데, 이는 스레드의 작업을 더 잘 제어하지 못해 매우 좋지 않습니다. 특히 스레드 대기 포함입니다. 커스텀 스레드 + 큐를 사용하면 몇 개의 스레드가 어떤 작업을 담당할지 제어할 수 있고, 대기열에 있는 작업은 큐에만 존재합니다; 스레드 수나 대기 중인 라인이 많지 않아 운영체제가 스레드 스케줄링으로 인해 자원을 잃게 됩니다.
데이터 통합 지연
지연된 머지 데이터 전송은 과도한 네트워크 IO 작업 문제를 해결하기 위한 수단으로, 많은 상황에서는 사용되지 않지만 게임 서버에서는 흔히 사용됩니다. 전에 누군가 저에게 질문했는데, 씬에 400명의 사용자가 있다면 각 사용자의 환경 변화가 다른 사용자에게 알려준다고 합니다. 결합된 데이터가 사용되지 않으면 매우 두려운 네트워크 IO 동작이 발생하여 IO 운영 번호 시스템이 이를 처리하기 어렵습니다. 따라서 현재 애플리케이션에 맞는 적절한 지연 간격 내에서 데이터를 병합하고 전송하는 것이 필요합니다. |