Следва обобщение на проблемите при внедряването на високопроизводителен сокет компонент; ако трябва да работите само с хиляди едновременни приложения, можете да обърнете внимание на писането на кода, но трябва да се справите с десетки хиляди или десетки хиляди едновременно използвани приложения. Обобщението на следващите въпроси се смята за голямо полезен при писането на това приложение.
SocketAsyncEventArgs
Този обект се предоставя след .NET 2.0 sp1 и се използва основно за реализиране на високопроизводителна обработка на данни чрез socket (за по-подробно въведение можете да посетите 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 за обработка.
Опашка
Виждам, че много практики са да се отварят нишки директно или да се хвърлят в пула на нишките след получаване на данни, което е много лошо, защото не контролира по-добре работата на нишките, включително чакането на нишките. С персонализирани нишки + опашки можеш да контролираш колко нишки са отговорни за каква работа, а опашената работа ще съществува само в опашката; Няма да има голям брой нишки или голям брой чакащи редове, което ще доведе до загуба на ресурси от операционната система поради планиране на нишки.
Забавена консолидация на данни
Забавеното предаване на данни при сливане е начин за решаване на проблема с прекомерните мрежови IO операции, който не се използва в много ситуации, но е често срещан в игровите сървъри. Някой ми зададе въпрос преди, ако има 400 потребители в сцената, промяната в средата на всеки потребител ще каже на останалите. Ако комбинираните данни не се използват, това ще доведе до много рискована мрежова IO операция, която е трудна за пренасяне от системата за IO операции. Затова е необходимо да се сливат и изпращат данни в рамките на подходящ интервал на забавяне за текущото приложение. |