Kisah Memalukan: Mengapa pelayan saya hanya dapat mengendalikan 10 pemain

Apa yang lebih memalukan adalah bahawa pada satu ketika saya yakin bahawa 10 pemain setiap pelayan adalah normal.

Semuanya bermula dengan idea pada awal musim panas. Saya sedang berdiri di bilik saya untuk memikirkan permainan io yang akan dibuat (saya memutuskan jika saya membuat permainan, saya mengekang diri saya untuk membuat permainan io untuk potensi virus maksimum - itu adalah satu perkara, saya bersumpah).

Oleh itu, saya mula menganalisis apa yang menjadikan permainan io tertentu (agar.io, slither.io, dll.) Ketagihan. Saya mencari perbandingan dan persamaan antara permainan seperti itu, seperti yang dilihat pada gambar di bawah:

Akhirnya, setelah sedikit percambahan fikiran, saya mendarat di knckout.io. Itu namanya permainan. Cuba tetap di peta, dan menjatuhkan orang lain. Saya menyukainya. Kawalan mudah, objektif yang jelas, dan mekanik permainan yang indah.

Setelah menyatakan bagaimana saya mahu permainan kelihatan dan dirasakan, saya mula bekerja. Saya akan pulang dari magang musim panas saya setiap hari, bersenam, kemudian membuat kod.

Saya mula-mula membuat pemain bergerak mengikut kehendak saya. Kemudian saya menangani peningkatan. Kemudian perlanggaran. Akhirnya permainan ini selesai dan siap untuk diuji oleh orang ramai. Atau saya fikir ...

Hujung minggu yang lalu (kira-kira seminggu yang lalu), saya semua sudah terhibur dan bersedia menunjukkan kepada dunia apa yang saya buat. Oleh itu, saya pergi ke interweb dan menjumpai subreddit kecil yang disebut "playmygame." Saya menulis ringkasan pendek dan menyiarkannya (ps dalam komen jawatan anda dapat melihat dengan jelas bahawa saya menekankan tentang kemampuan pelayan saya). Saya menunggu dengan sabar, kemudian HUZZAH! Seorang pemain telah bergabung.

Kami saling bolak-balik dalam permainan. Sementara itu, saya merasa tertekan dan bimbang dengan apa yang difikirkan oleh pemain ini. Selepas pemain ini kehilangan nyawa mereka dan dimulakan dari perlawanan yang kami jalani, saya menunggu untuk melihat apakah mereka akan kembali. Dan mereka berjaya! Tetapi lebih baik lagi: pemain menetapkan nama mereka menjadi "ilikethisgame." Mata saya membesar dan saya mengalami adrenalin! Saya adalah anak lelaki yang paling gembira di dunia.

Tidak lama kemudian, pemain lain turut serta dan meninggalkan komen pada catatan Reddit. Lebih ramai pemain mengatakan bahawa mereka telah menikmati permainan ini! Saya sangat gembira. Kemudian saya memeriksa bagaimana pelayan saya bertahan (pada 8/15)…

Rasanya ada seseorang yang mengeluarkan angin dari saya. Adakah ini nyata? Ini mesti palsu, saya fikir sendiri. Hanya dua permainan dan pelayan sukar untuk memprosesnya.

Saya mula memikirkan di mana salah saya dalam kod saya. Saya fikir pengesanan perlanggaran, pasti, menjadi penghalang. Tetapi saya sudah menggunakan quadtrees untuk mengurangkan bilangan lulus pengesanan perlanggaran.

Saya terpaksa membuat kerja kotor, jadi saya menggunakan pelayan Digital Ocean baru untuk digunakan sebagai pelayan pembangunan saya. Saya kemudian mematikan pengesanan perlanggaran buat sementara waktu dan melihat masalahnya masih ada.

OK - jika pengesanan perlanggaran tidak menjadi masalah, maka apa lagi yang boleh berlaku?

Saya memikirkan berapa banyak maklumat yang saya hantar dari pelayan kepada setiap pelanggan setiap saat. Saya mempunyai fungsi siaran ini yang menghantar keadaan permainan setiap 22 milisaat kepada setiap pelanggan. Dalam fungsi ini, saya tidak perlu menyaring pemain tempatan klien yang diberikan di sebuah allPlayersharta tanah, hanya untuk meletakkan pemain tempatan itu di dalam miliknya sendiri. Jadi, bukan sahaja saya meletakkan loop untuk (penyaringan) yang lain untuk loop (siaran untuk setiap pelanggan), saya juga menyesuaikan data yang akan dihantar oleh fungsi siaran ini untuk setiap pelanggan.

Penyesuaian ini tidak diperlukan. Saya semestinya dapat menyampaikan keadaan permainan kepada semua orang tanpa penyesuaian. Setiap orang harus mendapatkan data yang sama (dan data tersebut tidak boleh disesuaikan dengan klien tertentu). Ini harus menjadi tempat CPU dimakan. Oleh itu, saya mengoptimumkan fungsi ini, mendorongnya ke pelayan dev, dan memeriksa grafik CPU. Tiada penyelesaian.

Dengan ketidakpedulian saya, saya mula meyakinkan diri saya bahawa ~ 10-20 pemain setiap pelayan teras adalah baik. Sekarang, bagaimana saya dapat membuat kesimpulan seperti itu? Oleh itu, keyakinan saya yang tinggi terhadap kebolehan teknikal saya jelas membebaskan saya dari kenyataan. Saya tersandung pada posting di mana pencipta agar.io mengatakan pelayan 1 terasnya dapat mengendalikan kira-kira 190 pemain. Saya cepat-cepat keluar dari situ.

Pelakunya seterusnya yang saya bariskan ialah: socket.io. Saya menggunakan socket.io untuk menguruskan komunikasi masa nyata antara pelanggan dan pelayan. Saya pernah mendengar bahawa socket.io tidak ringan seperti alternatif lain.

Pada waktu yang lalu, jika anda ingin menghantar mesej secara tidak serentak, anda harus melaksanakan semacam hack: pengundian panjang atau soket kilat. Ini kerana tidak semua penyemak imbas web menyokong soket web. Tetapi kebanyakan penyemak imbas kini menawarkan sokongan asli. Tetapi agar socket.io dapat membuat sambungan, pertama-tama ia melakukannya dengan menggunakan salah satu peretasan yang tersedia yang disebutkan, dan kemudian meningkatkan sambungan jika pelanggan menyokong cara yang lebih baik. Walaupun soket web sudah banyak disokong. Pendekatan ini datang dengan mengorbankan CPU dan memori. Tetapi tidak seperti yang saya fikirkan ...

Saya melompat secara dalam talian dan naif menaip "masalah socket io cpu" ke Google. Hasil pasangan pertama diberi judul "Node.js - Cara debug Masalah CPU Node + Socket.io - Kesalahan Server" dan "Node.js - pelayan simpul Socket.io menggunakan cpu tinggi - Stack Overflow." Mata saya bercahaya. Saya diyakinkan bahawa ini adalah penyebab masalah saya. Tetapi saya mengklik artikel pertama dan penulis menyebut bahawa dia berurusan dengan ~ 1,500 sambungan soket serentak. Saya bukan jurusan matematik, tetapi 20 pemain kurang daripada 1,500 pemain.

Hanya untuk itu, saya menukar aplikasi Node sisi pelayan saya untuk menggunakan soket web kecil, kemudian menukar aplikasi Node sisi pelanggan untuk menggunakan sokongan soket web asli, tepat di dalam penyemak imbas. Saya mendorong perubahan ke server dev, dan memeriksa grafik CPU. Tiada penyelesaian.

Semangat saya sentiasa rendah. Saya mula merasa ngeri setiap kali saya perlu memeriksa grafik CPU darn. Saya fikir saya tidak akan mendapat garis biru untuk berhenti melarikan diri dari saya. Ini adalah satu-satunya masa yang saya rasakan tidak mampu menangani beberapa tugas teknikal. Tetapi kemudian ia berlaku ...

Saya duduk di depan grafik CPU yang berkubang dalam kesengsaraan saya ketika melihat sesuatu. Tidak kira berapa permainan penuh dijalankan atau seberapa dekat semuanya dimulakan. CPU meningkat dengan stabil pada kadar tetap. Saya tidak pernah cukup lama memerhatikan perkara ini. Kebocoran memori!

Saya mengimbas kod saya, baris demi baris, mencari pepijat (yang sepatutnya saya lakukan pada awalnya). Itu dia.

Dalam permainan saya, acara adalah objek yang menangkap maklumat mengenai perkara seperti kematian pemain, dorongan, dan perlanggaran. Oleh itu, satu peristiwa dibuat setiap kali perkara itu berlaku.

Saya mempunyai gelung ini yang melalui setiap acara dan mengemas kini. Ia dipanggil setiap 16 ms. Setelah acara memenuhi tugasnya, kejadian itu akan dihapuskan. Kata kunci: "sepatutnya."

Bingo. Saya mempunyai ingatan yang menumpuk serta peningkatan jumlah hantaran gelung yang tidak perlu. Saya memasukkan sebaris kod dan voila!

Lega lega.

Tugas saya seterusnya adalah melihat berapa banyak permainan (4 pemain per permainan) yang dapat disokong oleh satu pelayan dengan lancar. (Saya tahu sekurang-kurangnya 12 permainan, tetapi saya belum mencuba lagi). Sekarang saya tahu jumlah peristiwa memberi kesan besar pada CPU ... apa yang akan terjadi dalam produksi ketika semua pemain melepaskan acara peningkatan, perlanggaran, dan kematian setiap detik? Ujian saya tidak menjelaskan perkara itu.

Juga, setelah catatan ini menjadi viral, dan permainan saya mengikutinya, saya perlu dengan cepat meningkatkan jumlah pelayan yang ada. Saya akan menjadikan topik itu sebagai tajuk masa depan bersama dengan: "Bagaimana knckout.io berkembang menjadi berjuta-juta pemain." Ikuti saya di sini untuk maklumat terkini. :)