Неугодна прича: Зашто је мој сервер могао да прими само 10 играча

Оно што би могло бити још непријатније је то што сам се у једном тренутку уверио да је 10 играча по серверу нормално.

Све је почело са идејом почетком лета. Стајао сам у својој соби покушавајући да смислим ио игру коју бих могао да направим (одлучио сам ако желим да направим игру, ограничио сам се да направим ио игру за максималан вирусни потенцијал - то је ствар, кунем се).

Тако сам почео да анализирам шта је неке ио игре (агар.ио, слитхер.ио, итд.) Изазвало зависност. Проналазио сам поређења и сличности између таквих игара, као што се види на доњој слици:

Коначно, након још мало мозгања, слетео сам на кнцкоут.ио. То је име игре. Покушајте да останете на мапи и избаците друге. Допало ми се. Једноставне контроле, јасан циљ и лепа механика игре.

Након што сам изложио како желим да игра изгледа и осећа се, почео сам да радим. Свакодневно бих се враћао кући са летње праксе, вежбао, па шифровао.

Прво сам натерао играча да се креће како сам желео. Тада сам се позабавио појачањем. Затим судари. Напокон је игра завршена и спремна за тестирање у јавности. Или сам бар мислио ...

Прошлог викенда (пре отприлике недељу дана) био сам сав задовољан и спреман да покажем свету шта сам направио. Тако сам прешао на интернетске мреже и пронашао мали подредит под називом „плаимигаме“. Написао сам кратак резиме и објавио га (пс у коментарима поста јасно видите да сам наглашавао способност свог сервера). Стрпљиво сам чекао, па ХУЗЗАХ! Играч се придружио.

Ишли смо једни према другима у игри. У међувремену сам био под стресом и забринут због онога што овај играч мисли. Након што је овај играч изгубио цео живот и избачен из меча у којем смо били, сачекао сам да видим да ли ће се вратити. И јесу! Али још боље: играч је поставио своје име на „иликетхисгаме“. Очи су ми се рашириле и навала адреналина! Био сам најсрећнији дечак на свету.

Убрзо су се придружили и други играчи, а неки су оставили коментаре на Реддит пост. Још играча је рекло да су уживали у игри! Била сам усхићена. Затим сам проверио како се мој сервер држи (15.8.) ...

Чинило ми се као да је неко избацио ветар из мене. Да ли је ово било стварно? Ово је морало бити лажно, помислила сам у себи. Само две игре и сервер их тешко обрађује.

Почео сам да размишљам о томе где сам погрешио у свом коду. Мислио сам да откривање судара сигурно мора бити уско грло. Али већ сам користио квадреве како бих смањио број пролаза за откривање судара.

Морао сам да урадим прљав посао, па сам окренуо нови Дигитал Оцеан сервер који ћу користити као свој развојни сервер. Затим сам привремено онемогућио откривање судара у потпуности и видео да проблем још увек постоји.

ОК - ако откривање судара није био проблем, шта би друго могло бити?

Размишљао сам о томе колико информација сваке секунде шаљем са сервера сваком клијенту. Имао сам ову функцију емитовања која је слала стање игре сваке 22 милисекунде сваком клијенту. У овој функцији сам непотребно филтрирао локалног играча датог клијента у allPlayersсвојству, само да бих локалног играча ставио у своје власништво. Дакле, не само што сам ставио фор петљу (филтрирање) у другу фор петљу (емитовање за сваког клијента), већ сам прилагодио и податке које би ова функција емитовања слала за сваког клијента.

Ово прилагођавање није било потребно. Само бих могао да пошаљем стање игре свима без икаквог прилагођавања. Сви би требали добити исте податке (и подаци не би требали бити прилагођени одређеном клијенту). Ово је морало бити место где се једе ЦПУ. Зато сам оптимизовао ову функцију, гурнуо је до дев сервера и проверио графички процесор. Нема поправке.

Својим незнањем почео сам да се убеђујем да је ~ 10–20 играча по 1 језгреном серверу било добро. Е сад, како да дођем до таквог закључка? Па, моје крајње поверење у моје техничке способности очигледно ме је заслепљивало од стварности. Налетео сам на пост где је творац агар.ио рекао да његов 1 цоре сервер може да прими око 190 играча. Брзо сам се одвојио од тога.

Следећи кривац којег сам заредао био је: соцкет.ио. Користио сам соцкет.ио за управљање комуникацијом у реалном времену између клијента и сервера. Већ сам чуо да та соцкет.ио није била лагана као друге алтернативе.

Некада, ако сте желели да поруку пошаљете асинхроно, морали сте да примените неку врсту хаковања: дугачка анкета или флеш сокети. То је било зато што нису сви веб прегледачи подржавали вебсокете. Али већина прегледача сада нуди изворну подршку. Али да би соцкет.ио успоставио везу, прво то чини помоћу једног од поменутих доступних хакова, а затим надограђује везу ако клијент подржава бољи начин. Иако су веб-утичнице већ широко подржане. Овај приступ долази на штету ЦПУ-а и меморије. Али не онолико колико сам мислио ...

Ускочио сам на мрежу и наивно укуцао „соцкет ио цпу проблем“ у Гоогле. Резултати првих пар били су насловљени „Ноде.јс - Како отклонити грешке у Ноде + Соцкет.ио ЦПУ Иссуес - Сервер Фаулт“ и „Ноде.јс - Соцкет.ио ноде сервер који користи висок ЦПУ - Стацк Оверфлов“. Очи су ми засветлеле. Био сам уверен да је то кривац за мој проблем. Али кликнуо сам на први чланак и аутор је споменуо да има посла са око 1.500 истовремених прикључака сокета. Нисам математичар, али 20 играча је знатно мање од 1.500 играча.

Само за врага, пребацио сам своју апликацију Ноде на серверу да користи мале веб-утичнице, а затим сам заменио апликацију Ноде на страни клијента да користи изворну подршку за веб-утичницу, директно у прегледачу. Гурнуо сам промене на дев сервер и проверио ЦПУ графикон. Нема поправке.

Мој морал је био у сваком тренутку низак. Почео сам да се најежим сваки пут кад бих морао да проверим проклети ЦПУ граф. Мислио сам да никада нећу добити ту плаву линију да престанем да бежим од мене. Ово је био једини пут да сам се икада осећао потпуно неспособним да се бавим неким техничким задатком. Али онда се догодило ...

Седео сам испред графа ЦПУ-а утапајући се у својој беди кад сам нешто приметио. Није било важно колико је пуних игара било покренуто нити колико су све заједно започете. ЦПУ се стално повећавао константном брзином. Никада нисам остао довољно дуго да то посматрам. Цурење меморије!

Скенирао сам свој код, ред по ред, тражећи грешку (што је требало да учиним на самом почетку). Ето га.

У мојој игри догађај је објекат који бележи информације о стварима попут смрти играча, појачања и судара. Дакле, догађај се ствара сваки пут када се догоди једна од тих ствари.

Имам ову петљу која пролази кроз сваки догађај и ажурира га. Зове се сваких 16 мс. Након што догађај испуни своју дужност, требало би да буде избрисан. Кључне речи: „требало би“.

Бинго. Имао сам гомилу меморије, као и све већу количину непотребних фор-лооп пролаза. Убацио сам ред кода и воила!

Огроман уздах олакшања.

Мој следећи задатак је да видим колико игара (4 играча по игри) један сервер сада може глатко да подржи. (Знам да има најмање 12 игара, али још нисам покушао више). Сад кад знам да број догађаја има огроман утицај на ЦПУ ... шта ће се догодити у производњи кад сви играчи сваке секунде испаљују појачане догађаје, сударе и смрт? Моји тестови то нису узели у обзир.

Такође, након што овај пост постане виралан, а моја игра то следи, мораћу да брзо прилагодим број доступних сервера. То ћу поставити као тему будућег поста уз: „Како је кнцкоут.ио нарастао до милиона играча.“ Пратите ме овде за новости. :)