A rövid válasz
Egy dedikált játékszerver akkor üzemeltethető, ha azok, akik futtatni fogják, a kódot író fejlesztő nélkül is tudják buildelni, telepíteni, konfigurálni, megfigyelni, visszaállítani és helyreállítani. Amíg ez nem igaz, a szerver egy működő program, de még nem szolgáltatás.
Ez a definíció a release vagy a LiveOps előtt azért hasznos, mert egy homályos érzést („stagingen fut, nem lesz baj”) ellenőrizhető bizonyítékokká alakít. Az alábbi területek mindegyike valami kézzelfoghatót kér: pipeline-t, dokumentumot, dashboardot, begyakorolt eljárást. Ha a bizonyíték hiányzik, a terület nincs kész, bármilyen jól teljesít is a szerver a playteszteken.
A cikk abban a sorrendben megy végig a területeken, ahogy jellemzően elromlanak, a végén pedig egy checklist táblázatba gyűjti őket, soronként felelőssel és „kész, ha” feltétellel.
Két felelős, egy határ
Az átadási problémák többsége valójában felelősségi probléma. Két szerep vesz részt benne, akkor is, ha ugyanaz a cég tölti be mindkettőt:
- A játékfejlesztő felel azért, ami a folyamaton belül fut: a headless szerver buildért, az indítási szerződésért, a játékspecifikus health jelekért, logokért és metrikákért, a verziókompatibilitásért, és azért, hogyan viselkedik a meccs, ha valami elromlik.
- Az infrastruktúra-üzemeltető felel azért, hogy hol és hogyan fut a folyamat: hosting fiókok, régiók, hostok vagy clusterek, container registry, secretek, log- és metrikapipeline-ok, riasztások irányítása, kapacitás és költségkeret, valamint az ügyelet.
A kettő közötti határ egy szerződés: hogyan indul a szerver, milyen konfigurációt vár, milyen jeleket ad, hogyan kell leállítani, és mit jelent az, hogy „egészséges”. Ezt érdemes korán leírni. A checklist nagy része azt teszteli, hogy mindkét fél tartotta-e magát a saját részéhez.
1. Reprodukálható build
Minden más azon múlik, hogy pontosan azt a szervert tudod-e előállítani, amelyet futtatni akarsz. A gyakorlatban ez azt jelenti:
- A headless szervert automatizált job buildeli egy taggelt commitból, nem valaki editorából exportálódik.
- Az engine-verzió, a csomagok és a build-beállítások rögzítettek, így ugyanaz a tag egy hónap múlva is ugyanazt az eredményt adja.
- Minden build hordoz egy build ID-t (verzió, commit, buildszám), amelyet a szerver induláskor kiír és a logjaihoz csatol.
- A csak szerveren futó kódutakat és a kihagyott asseteket ebben a buildben teszteled, nem a kliensből vezeted le.
A tipikus hiba csendes: a szerver csak egy gépen buildelhető, vagy egy hotfix nem reprodukálható, mert senki sem tudja, melyik helyi módosítás került bele.
2. Telepítés
A telepítés legyen megismételhető művelet, ne kézi parancsok sorozata egy szerveren. Konténerizált szervereknél az image definíciója a repóban van, az image a build ID-vel van taggelve, a staginget és a productiont pedig ugyanaz a mechanizmus telepíti, csak más bemenetekkel.
A játékfejlesztő felel azért, hogy az image dokumentált bemenetekből tisztán elinduljon. Az üzemeltető felel a registryért, a telepítési platformért és a hozzáférésekért. Jó próba erre a határra: tud-e az üzemeltető új buildet telepíteni stagingre kizárólag a dokumentáció alapján?
3. Konfiguráció
A „stagingen működik” leggyakrabban a konfigurációnál bukik el élesben. Listázz ki minden beállítást, amit a szerver beolvas: portok, régió- vagy környezetnevek, backend-végpontok, meccsszabályok, tick- vagy szimulációs beállítások, logszint, hitelesítő adatok. Mindegyiknél rögzítsd az alapértéket, a környezetenkénti értéket, hogy secret-e, és ki módosíthatja.
Két viselkedés teszi biztonságossá a konfigurációt. A szerver induláskor validálja a konfigurációját, és egyértelmű logüzenettel megtagadja az indulást, ha valami hiányzik vagy érvénytelen. A secretek pedig az üzemeltető secret store-jából jönnek, soha nem az image-ből vagy a repóból.
4. Régiók és kapacitásfeltételezések
Ez az a terület, ahol a csapatok a legszívesebben mondanak egy számot. Ne tedd, amíg a számnak nincs bizonyítéka. A kapacitás függ a játék szimulációjától, a hosting modelltől, a hardvertől és attól, hogyan viselkednek valójában a játékosok, így egy másik játékból vagy egy csendes playtesztből származó szám nagyon keveset mond.
Szám helyett vezess egy rövid feltételezésnaplót. Minden bejegyzés tartalmazza:
- a feltételezést (például játékosok száma meccsenként, meccsek száma hostonként, memória és CPU meccsenként, célrégiók, várható csúcsidőszakok),
- az alapját: mért (linkeld a tesztet és a build ID-t), becsült (írd le az indoklást) vagy ismeretlen,
- a dátumot és a buildet, amelyre vonatkozik,
- a felelőst és azt a tesztet, amely majd méréssel váltja ki.
A költségre ugyanez a szabály vonatkozik: a költségtényezőket dokumentáld (instance- vagy hosttípus, régiók, kihasználatlan kapacitás, kimenő forgalom, log- és metrikamegőrzés), és azt, hogy melyik feltételezéstől függenek, ne egyetlen havi összeget, amelyet senki nem tud visszakövetni. A játékfejlesztő méri, mennyi erőforrást igényel egy meccs; az üzemeltető ebből állítja elő a hostméretezést, a kvótákat és a költségkeretet.
5. Logok, metrikák és crash-megfigyelhetőség
Egy játékos szombat este 21:40-kor bontott kapcsolatot jelent. Meg tudja találni az üzemeltető azt a meccset, el tudja olvasni a szerverlogját, és látja, mit csinált épp a folyamat? Ez a forgatókönyv jobb teszt bármilyen dashboard-képernyőképnél.
- Logok: strukturáltak, és minden sorban szerepel a build ID, a szerver- vagy meccsazonosító és a régió. A megőrzés és a hozzáférés meghatározott.
- Metrikák: lefedik a folyamatot (CPU, memória, újraindulások) és a játékot (szerver frame- vagy tickidő, csatlakozott játékosok, meccsállapot, sikertelen csatlakozások). A játékfejlesztő határozza meg, mely játékmetrikák számítanak; az üzemeltető felel a gyűjtésért, a tárolásért és a riasztások irányításáért.
- Crashek: keletkezik róluk riport vagy dump, és minden kiadott build debugszimbólumai el vannak tárolva, hogy a riport később is olvasható legyen. Az újraindítási szabály explicit, így egy crash loop látható, nem emészti csendben a kapacitást.
- Riasztások: óvatos, dokumentált kezdeti küszöbökkel indulnak, és mindegyik egy runbook-bejegyzésre mutat. Az a riasztás, amelyre senki sem tudja, hogyan kell reagálni, csak zaj.
6. Verziókezelés
A kliens, a szerver, a hálózati protokoll és a tartalom verzióihoz kell egy meghatározott kompatibilitási szabály. A session- vagy matchmaking-folyamat csak olyan szerverre küldje a klienst, amellyel az kommunikálni tud, a nem megfelelő verziójú kliens pedig meghatározott üzenetet kapjon, ne timeoutot. Írd le a szabályt: mely verzióváltozások igényelnek összehangolt kliens- és szerverkiadást, és melyek mehetnek ki függetlenül.
7. Élesítés és rollback
A dedikált szerverek éles meccseket futtatnak, így az „új verzió telepítése” soha nem csak egy újraindítás. Döntsd el és dokumentáld:
- az új meccsek az új verzión indulnak-e, miközben a futók a régin fejeződnek be (draining), és meddig tarthat a draining;
- hogyan reagál a szerver a leállítási jelre: nem fogad új játékost, tisztán befejezi vagy lezárja a meccset, kiírja a logokat, és a türelmi időn belül kilép;
- hogyan lehet visszaállni: az előző image megmarad, az eljárás le van írva, és stagingen be lett gyakorolva;
- ki dönt a rollbackről, és milyen jelek alapján.
A játékfejlesztő határozza meg a kompatibilitási korlátokat és a leállási viselkedést; az üzemeltető hajtja végre az élesítést és a rollbacket.
8. Hibaforgatókönyvek
Sorold fel a várható hibákat és mindegyiknél a kívánt viselkedést. Elég egy rövid táblázat: forgatókönyv, mit tapasztal a játékos, észlelési jel, runbook-lépés. Tipikus elemek: szerver-crash meccs közben, egy host kiesése, egy régió elérhetetlenné válása, egy backend-függőség (session, hitelesítés, perzisztencia) leállása, egy hibás konfigurációs érték, és a kapacitás elfogyása csúcsidőben.
Release előtt nem fogod mindet begyakorolni. A legnagyobb hatásúakat gyakorold be, a többinél pedig legalább legyen észlelési jel és felelős.
9. Felelősség és runbook
A runbook maga az átadás. Tartalmazza az architektúra áttekintését, a telepítési, rollback- és skálázási eljárásokat, a konfigurációs referenciát, a dashboardokat és azt, hogy hogyan néz ki rajtuk a normál állapot, a hibaforgatókönyv-táblázatot, a feltételezésnaplót, az ismert korlátokat, a költségtényezőket és az eszkalációs utat, beleértve azt is, mi történik munkaidőn kívül.
Az átadás utáni folyamatos üzemeltetés külön döntés. Ha a fejlesztő továbbra is részt vesz benne, a terjedelmet és a válaszidő-elvárásokat kifejezetten rögzíteni kell. Ha nem, az üzemeltetőnek kizárólag a runbookból is dolgoznia kell tudni.
Az átadási checklist
Ezt a táblázatot a release vagy a LiveOps előtti készültségi review-n használd. A „Fejlesztő” a szerverkódért és a buildért felelős csapat; az „Üzemeltető” a hostingért és a napi üzemeltetésért felelős csapat.
| Terület | Szükséges bizonyíték | Felelős | Kész, ha |
|---|---|---|---|
| Reprodukálható build | Automatizált headless szerver build taggelt commitból; rögzített engine- és csomagverziók; beágyazott build ID | Fejlesztő | Valaki, aki nem írta a pipeline-t, ugyanazt a szervert buildeli egy tagből, és a szerver induláskor logolja a build ID-t |
| Container image | Image-definíció a repóban; build ID-vel taggelt image; dokumentált base image és futásidejű függőségek | Fejlesztő (tartalom); Üzemeltető (registry és image-szabályok) | Az image stagingen kizárólag dokumentált bemenetekkel elindul |
| Telepítés | Szkriptelt vagy deklaratív telepítés stagingre és productionre; nincs kézi lépés a hostokon | Üzemeltető (platform és hozzáférés); Fejlesztő (indítási szerződés) | Az üzemeltető fejlesztői segítség nélkül, a dokumentáció alapján telepít új buildet stagingre |
| Konfiguráció | Minden beállítás referenciája: alapérték, környezetenkénti érték, secret-e, ki módosíthatja | Fejlesztő határozza meg; Üzemeltető adja az értékeket és a secreteket | A szerver hiányzó vagy érvénytelen konfigurációval nem indul el, és logolja, melyik érték hibás |
| Health és leállítás | Readiness és liveness jelek; meccsállapot-jelentés; dokumentált türelmi idő leállításkor | Fejlesztő | Egy tesztmeccs közbeni leállítás stagingen a dokumentált viselkedést követi |
| Régiók és kapacitás | Feltételezésnapló alappal (mért, becsült, ismeretlen), dátummal, builddel és felelőssel; költségtényezők listája | Fejlesztő (meccsenkénti erőforrásigény); Üzemeltető (méretezés, kvóták, költségkeret) | A tervben szereplő minden kapacitás- vagy költségadat méréshez kötött, vagy feltételezésként van jelölve, a kiváltó teszttel együtt |
| Logok | Strukturált logok build ID-vel, szerver- vagy meccsazonosítóval és régióval; meghatározott megőrzés és hozzáférés | Fejlesztő előállítja; Üzemeltető gyűjti és megőrzi | Az üzemeltető egy játékosbejelentésből megtalálja egy meccs összes logját |
| Metrikák és riasztások | Folyamat- és játékmetrikák; dashboard; dokumentált kezdeti küszöbök | Fejlesztő (játékmetrikák); Üzemeltető (pipeline, irányítás, ügyelet) | Minden riasztás runbook-bejegyzésre mutat, és stagingen legalább egyszer már kiváltódott |
| Crashek | Crash-rögzítés, kiadott buildenként tárolt szimbólumok, explicit újraindítási szabály | Fejlesztő (szimbólumok, triázs); Üzemeltető (rögzítés, tárolás, újraindítás) | Egy szándékos crash stagingen olvasható, build ID-hez köthető riportot ad |
| Verziókezelés | Leírt kompatibilitási szabály kliensre, szerverre, protokollra és tartalomra; a session-folyamat betartatja | Fejlesztő | A nem megfelelő verziójú klienst meghatározott üzenettel elutasítja a rendszer, tesztelve |
| Élesítés és rollback | Élesítési stratégia drainnel; rollback-eljárás; megőrzött előző image; megnevezett döntéshozó | Üzemeltető végrehajtja; Fejlesztő meghatározza a korlátokat | A rollback stagingen be van gyakorolva, a futó meccsek kezelésével együtt |
| Hibaforgatókönyvek | Forgatókönyv-táblázat: játékosoldali viselkedés, észlelési jel, runbook-lépés | Közös | Minden forgatókönyvnek van felelőse és jele; a legnagyobb hatásúak be vannak gyakorolva |
| Runbook és felelősség | Runbook, eszkalációs út, ismert korlátok, támogatási megállapodás vagy kifejezett „nincs támogatás” | Közös, mindkét fél jóváhagyásával | Az üzemeltető egy telepítést, egy rollbacket és egy incidensgyakorlatot kizárólag a runbook alapján végez el |
Mire építünk
A saját referenciánk a Bad Goons, a Sourcegarden Studio jelenlegi saját IP-je, amely aktív fejlesztés alatt áll. Unity headless buildeket futtat autoritatív Linux dedikált szervereken, konténerizált telepítéssel, és a kapacitást, a leállítást, a health jeleket, a logokat és a verziók élesítését a játékot érintő kérdésként kezeljük, nem valaki más infrastruktúra-problémájaként. A Bad Goons 64 játékos meccsekre készül; ez tervezési cél, nem mért kapacitás, és pontosan ezért javasolja ez a cikk a feltételezésnaplót egy hangzatos szám helyett.
A checklist általános szakmai útmutatás, amely erre a munkára épül. Nem állítjuk, hogy minden pontja éles játékosforgalom mellett már ki lett próbálva.
Hol helyezkedik el ez a projektben
A checklist egy olyan folyamat vége, amely jóval korábban kezdődik. Ha a valós idejű meccs és a körülötte futó szolgáltatások közötti határok még nem tiszták, kezdd a hálózati modellel a multiplayer fejlesztés oldalán, és azzal, mit érdemes meghatározni, mielőtt backend becslést kérsz. A felelősségekről a legolcsóbb az első telepítés előtt megállapodni, nem a launch előtti héten.
Ha a szervered már fut, de a fenti bizonyítékok hiányosak, egy rövid átnézés ezen a táblázaton általában megmutatja, hol érdemes kezdeni. Ilyen munkát végzünk a játék backend fejlesztés keretében: telepítés, megfigyelhetőség és olyan átadás, amellyel a csapatod üzemeltetni tudja a rendszert.