Ниже приведено краткое изложение проблем при реализации высокопроизводительного компонента сокета: если вам нужно работать только с тысячами одновременных приложений, то можно обратить внимание на написание кода, но нужно работать с десятками тысяч или десятками тысяч одновременно работающих приложений. Краткое изложение следующих вопросов считается значительным способом при написании этого заявления.
SocketAsyncEventArgs
Этот объект предоставляется после .NET 2.0 sp1 и в основном используется для реализации высокопроизводительной обработки данных через сокеты (для более подробного введения вы можете перейти в MSDN). Этот объект предлагает три способа настройки буферов для отправки и получения связанных отправок: SetBuffer(Int32, Int32), SetBuffer(Byte(), Int32, Int32, BufferList, первые два не могут сосуществовать с последним ( MSDN объясняет почему). Когда вы устанавливаете буфер, будь то SetBuffer(Byte(), Int32, Int32) или BufferList, старайтесь устанавливать его только один раз на экземпляр SocketAsyncEventArgs за всю жизнь программы, так как эта настройка может быть очень ресурсоёмкой. Рекомендуется задавать буфер данных через SetBuffer(Byte(), Int32, Int32) при создании SocketAsyncEventArgs, а затем использовать SetBuffer(Int32, Int32) для обработки. Когда вы хотите установить BufferList, лучше не менять <byte>источник байта[] на который ссылается IList<ArraySegment>. Если это изменить, это заставит SocketAsyncEventArgs переназначить буфер, что повлияет на эффективность.
Пул SocketAsyncEventArgs
Как уже упоминалось, старайтесь не менять буфер, на который ссылается SocketAsyncEventArgs, насколько это возможно, чтобы достичь этой цели. Поэтому необходимо создать пул приложений SocketAsyncEventArgs и максимально инициализировать объект SocketAsyncEventArgs в начале программы. Помимо сокращения создания SocketAsyncEventArgs, создание пулов также значительно экономит память. Основная причина в том, что нельзя знать, насколько большое сообщение, конечно, можно задать максимальный лимит перед проектированием, а затем установить буфер, соответствующий SocketAsyncEventArgs. Однако это большая трата памяти, потому что не все сообщения имеют максимальную длину. Выделяйте соответствующий размер буфера SocketAsyncEventArgs, предоставляйте вызовы через пулы и гибко записывайте сообщения в один или несколько SocketAsyncEventArgs или храните несколько сообщений в одном SocketAsyncEventArgs для обработки.
Очередь
Я вижу, что многие практики — открывать потоки напрямую или отправлять их в пул потоков после получения данных, что очень плохо, потому что это не позволяет лучше контролировать работу потоков, включая ожидание потоков. С пользовательскими потоками + очередями вы можете контролировать, сколько потоков отвечает за какую работу, и очередь будет существовать только в очереди; Не будет большого количества потоков или ожидания большого количества линий, что приведёт к потере ресурсов операционной системы из-за планирования потоков.
Задержка консолидации данных
Задержка передачи данных слияния — это способ решения проблемы чрезмерных сетевых операций ввода-вывода, которая не используется во многих случаях, но часто встречается на игровых серверах. Кто-то уже задавал мне вопрос: если в сцене 400 пользователей, изменение среды каждого пользователя повлияет на это другим. Если объединённые данные не использоваться, это приведёт к очень опасной сетевой операции ввода-вывода, что сложно переносить системе номеров операций IO. Поэтому необходимо объединять и отправлять данные в соответствующий интервал задержки для текущего приложения. |