Сервер для онлайн - игры

 
0
 
Java
ava
Temdegon | 23.01.2009, 16:13
Мой друг пишет браузерную онлайн-игру. Сам движок игры написан на флеше. Сервер для его игры на данный момент написан на PHP. Точнее сервер не один, а их несколько. Один для синхронизации действий игроков, другой управляет ботами и т.д. Но производительность ПХП оставляет желать лучшего, да к тому же в нем нет поддержки многопоточности, что сильно сказывется в таких задачах. Вот и встал вопрос переписать всю серверную часть на чем-то лучшем, чем PHP. Вопрос, какой язык выбрать? Эффективно ли будет здесь использование java? Стоит вопрос писать на C++ или на Java. Если выберут java (опыта в таких делах у меня нет), то писать буду я. Если С++, то начинающий программист на Си. Не у кого на фирме нет опыта в написании такого рода кода. Все убеждены, что Java - медленный и жрущий память язык. Вопрос не в том, как склонить всех к Java. Нужно взвесить все за и против (время разработки на Си\java, сложность реализации, эффективность). Какие есть аргументы в пльзу Си или Java? На чем чаще пишут серверы и почему?
Мои аргументы такие: в Java хорошо реализована многопоточность, все что будет нужно для реализации уже есть в стандартных библиотеках, скорость исполнения за счет jit будет сравнима с Си и врядли будет медленнее более чем в 2 раза. Памяти будет есть больше, но это не критично. Времени на разработку уйдет намного меньше.
Может я не знаю каких-то веских плюсов\минусов? подскажите плиз.
Другой вопрос, как это будет выглядеть на Java? это долежн быть просто обычный jar, который можно запустить под линуксом без установки Tomcat? Или это делается как-то по другому? Нужен ли Tomcat или достаточно просто jvm?
Насколько это сложно и какую литературу предварительно почитать?
Ответы (26)
ava
golubsv | 23.01.2009, 16:28 #
http://www.electro-server.com/
http://www.smartfoxserver.com/
http://www.projectdarkstar.com/ https://games-darkstar.dev.java.net/ (open source но вроде сыроват пока ещё)
ну и подобное поискать можно
ava
SoulKeeper | 23.01.2009, 16:50 #
Если писать будет начинающий программист на C++, то вы замучаетесь его писать и отлаживать.
Берите сразу джаву и не парьтесь.

Как будет выглядесть: Нет никакого смысла гонять HTTP траффик, откройте пару портов и делайте прямое соединение.
Как следствие, можно (да и нужно) обойтись без томката. В результате - обычный .jar работающий под windows\linux\solaris\etc...

P.S. Постыдились бы после Flash"а и PHP говорить о скорости и прожорливости smile
ava
Temdegon | 23.01.2009, 17:03 #
Насчет прямых соединений - так оно и будет. Та часть, которую нужно переписать работает через сокет. А насчет
Цитата


Постыдились бы после Flash"а и PHP говорить о скорости и прожорливости


ну просто как бы хотят сделать качественно, т.сказать на века. Боятся, что если написать на java, то через некоторое время начнутся проблемы и придется еще раз переписывать на Си. Я конечно пытаюсь защищать позиции java, но я в меншинстве.
ava
vdweller | 23.01.2009, 17:22 #
Цитата


Если писать будет начинающий программист на C++, то вы замучаетесь его писать и отлаживать.

Берите сразу джаву и не парьтесь.



Абсолютно согласен, если нет человека который хорошо знает C/C++ то лучше не смотреть в ту сторону.

Цитата


ну просто как бы хотят сделать качественно, т.сказать на века. Боятся, что если написать на java, то через некоторое время начнутся проблемы и придется еще раз переписывать на Си. Я конечно пытаюсь защищать позиции java, но я в меншинстве.



Если опыта нет, то все равно придется переписывать значительную часть системы в случае если игра станет популярна. Насчет того что начнутся проблемы - вон линейковские сервера на яве и ничего, работают себе.
ava
SoulKeeper | 23.01.2009, 17:25 #
На какую нагрузку расчитываете?
ava
Temdegon | 23.01.2009, 17:29 #
Ну, я думаю 1000 игроков онлайн это вполне реально. Но дополнительная нагрузка на сервер это боты. Их АИ тоже реализован на сервере. Сам по себе алгоритм ботов не сложный, но их может быть много.
ava
SoulKeeper | 23.01.2009, 17:37 #
1000 игроков потянет довольно легко. Главное в коде на начудить smile
ava
Temdegon | 23.01.2009, 17:53 #
Ну до того как я начну "чудить", надо сначала детально разобраться, как это уже реализовано на ПХП. Пока я смотрю в код этих серверов, как будто пытаюсь читать книгу на китайском.
ava
vdweller | 23.01.2009, 17:54 #
Цитата (SoulKeeper @ 23.1.2009, 17:37)
1000 игроков потянет довольно легко. Главное в коде на начудить smile

И с базой тоже. С ней даже проще начудить чем с кодом по моему.
ava
chand0s | 23.01.2009, 18:20 #
Вы же вообще ничего не сказали - ни какое железо у вас, ни насколько тяжелая функциональность и т.д.

Напишите прототип на Java, разверните его на предполагаемом железе, нагрузите "ожидаемой" нагрузкой и посмотрите, устраивает вас производительность или нет.
ava
Temdegon | 23.01.2009, 18:34 #
Цитата


Вы же вообще ничего не сказали - ни какое железо у вас, ни насколько тяжелая функциональность и т.д.


Я ничего не сказал, ибо это пока не известно. В существующем ПХП-коде я только начал ковыряться, и пока нифига там не понимаю. Железо тоже пока не известно. Все тестируется на чужом сервере, на котором висят кроме этого несколько других сайтов. Но естественно потом все это будет переноситься на нормальный сервер.
Цитата


Напишите прототип на Java.....


А как мне это сделать? клиенты - флеш. У меня нету парка машин, чтоб посадить туда сотню тестеров и тестировать под нагрузкой.

Проблема в том, что я не знаю как мне так переписать только сервер, чтоб не пришлось весь проект, который уже вполне нормально работает, ставить с ног на голову.

Вот еще какой вопрос:
Есть массив (точнее, это скорее коллекция), который загружается из БД. Там ключ - это команда (грубо - действие игрока), а значение - имя функции, которую нужно вызвать для этой команды.
Но сами функции не просто лежат в php-файле, а тоже грузятся из базы. Получается, если девелопер добавляет новую функцию, он просо добавляет в базу текст функции, добавляет в клиент действие, которое будет использовать новую функцию, и посылает серверу команду перечитать список функций. Получается что можно обновить функционал сервера без перезагрузки самого сервера. Как мне реализовать что-то похожее на Java?
ava
SoulKeeper | 23.01.2009, 18:58 #
Копать в сторону Groovy\BeanShell\Java Compiler API + tools.jar и класслоадеров.

А вообще держать код в базе мега глупо... Дебаггеры не будут работать, читабельность на нуле... IDE тоже не получится использовать.
ava
ivg | 23.01.2009, 19:31 #
Цитата (Temdegon @ 23.1.2009, 20:34 findReferencedText)
Получается что можно обновить функционал сервера без перезагрузки самого сервера. Как мне реализовать что-то похожее на Java?

Можно воспользоваться скриптовыми возможностями Java. Если производительность во главе угла - то "hot redeploy"(замена/добавление классов без остановки приложения). Это практически стандартная фича всех серверов приложений. Пишете свой класслоадер, который можно, кстати, научить грузить классы, в том числе, прямо из базы. При получении команды на перезагрузку классов, удаляете все ссылки на объект класслоадера, на загруженные им классы и на объекты этих классов. Лучше, конечно, вообще не позволять получать подобные ссылки в коде классов загруженных другими класслоадерами (за исключением того кода, в котором вы внимательно эти ссылки подчистите). Далее создаете новый объект вашего класслоадера, грузите им необходимые классы, обновляете Map<команда, действие>. Старые классы вместе с объектом класслоадера будут удалены JVM, поскольку на них не останется ссылок, типа как в GC (правда я не уверен, что в случае с классами, этим GC занимается).

Цитата (SoulKeeper @ 23.1.2009, 19:37 findReferencedText)
1000 игроков потянет довольно легко.
Зуб даёте? :biggrin
Цитата (SoulKeeper @ 23.1.2009, 20:58 findReferencedText)
А вообще держать код в базе мега глупо... Дебаггеры не будут работать, читабельность на нуле... IDE тоже не получится использовать.
Вспоминаем отладку из под IDE для серверов приложений... :wink

ava
Temdegon | 23.01.2009, 19:52 #
Млин, нигде не могу найти примеров серверов. Все что попадается это однотипные примерчики, где клиент посылает пару байт, сервер их читает и посылает ответ.

Ума не приложу, как это красиво перевести на многопоточтоность. Оригинальный код работает в общих чертах так:
в цикле опрашивается порт. Если есть новые запросы, то идентефикатор ищется в массиве уже имеющихся идентефикаторов что бы узнать новое это соединение или нет. Если новое то оно акцептится и добавляется в массив. Если старое, то читается его сообщение, парсится и выполняется нужная команда. Когда команда выполниалсь, результат рассылается всем, кто находится на той же локации.
На пример на локации 5 человек. А бьет Б. он посылает серверу команду, сервер проверяет все условия, вычиляет сколько надо снять здоровья, прочности вещи и т.п, по идентефикатору определяет кто еще находится на этой же локации, и рассылает всем флеш-клиентам команду, что нужно проанимировать удар.
Вопрос по многопоточности.
Изначально я представлял себе так: для каждого нового соединения (пользователя) создается отдельный поток, в котором уже обрабатываются все его команды. Но насколько это хорошее решение? Может все-таки делать так же как уже сделано, т.е. все в одном потоке?
ava
SoulKeeper | 23.01.2009, 20:21 #
Цитата (ivg @ 23.1.2009, 19:31 findReferencedText)


Можно воспользоваться скриптовыми возможностями Java. Если производительность во главе угла - то "hot redeploy"(замена/добавление классов без остановки приложения). Это практически стандартная фича всех серверов приложений.


Не покатит для онлайн игры. Там надо 24\7, а редеплой, вроде как, убивает полносттью приложение, потом снова развертывает. Разве что где-то в родительском уровне оставлять критические данные, в общем не разбирался с этим вопросом, тут спорить не буду.

Но сервер приложений просто не нужен тут...
Цитата (ivg @ 23.1.2009, 19:31 findReferencedText)
Зуб даёте? smile

Если бы я писал сервер, то дал бы smile Не первый год копаюсь в игровых серверах.


Цитата (ivg @ 23.1.2009, 19:31 findReferencedText)
Вспоминаем отладку из под IDE для серверов приложений...

Что дебажить то? Искходники которые в базе данных? Не получится :)



Цитата (Temdegon @ 23.1.2009, 19:52 findReferencedText)
Млин, нигде не могу найти примеров серверов. Все что попадается это однотипные примерчики, где клиент посылает пару байт, сервер их читает и посылает ответ.



l2jserver.com
aion-emu.com


Цитата (Temdegon @ 23.1.2009, 19:52 findReferencedText)
Вопрос по многопоточности.

Изначально я представлял себе так: для каждого нового соединения (пользователя) создается отдельный поток, в котором уже обрабатываются все его команды. Но насколько это хорошее решение? Может все-таки делать так же как уже сделано, т.е. все в одном потоке?


Что первое что второе - ничего хорошего.


В кратце:
Есть пакет java.nio. Смотрите туториалы по нему
Тальше есть пакет java.util.concurrent, в нем смотрите на ThreadPoolExecutor и прочее.

Грубо говря:

Поток(и) с Selector"ом смотрят следят за ServerSocketChannel в неблокирующемся режиме, принимают, отсылают данные.

Данные формируются в некоторые структуры, которые передаются на выполнение трид пулу.
После выполнения нужные данные передаются на отправку потоку(ам) Selector"а, который(е) уже непосредственно отсылает данные.

Главное помнить что поток(и) Selector"а не должны делать ничего кроме чтения\записи клиентских данных. Все задания по любым действиям передаются на выполнение пулу потоков.
ava
Temdegon | 23.01.2009, 20:27 #
SoulKeeper, в целом схема понятна. Не понятно в каком случае нужен один поток с селектором а в каком несколько? Или несколько потоков как раз нужны что бы можно было параллельно слать команды клиента (как в примере с командой анимации удара)?
ava
ivg | 23.01.2009, 21:08 #
Цитата (SoulKeeper @ 23.1.2009, 22:21 findReferencedText)
Если бы я писал сервер, то дал бы smile Не первый год копаюсь в игровых серверах.

Но ведь вы не знаете ни требований, ни игровой сложности, ни мощности железа ну и т.д.
Цитата (SoulKeeper @ 23.1.2009, 22:21 findReferencedText)
Что дебажить то? Искходники которые в базе данных? Не получится

Исходники у вас в IDE, скомпилированные классы деплоите в БД, ну а в остальном всё аналогично отладке приложений на Application серверах, с учётом того что сервер умеет грузить классы из БД.
Temdegon, возьмите готовый движок игрового сервера, ссылок накидали, там в исходниках вы найдёте ответы на эти вопросы. Да и быстрее получится и постабильнее будет, чем если вы с нуля начнёте свой велосипедсервер ваять. smile
ava
SoulKeeper | 23.01.2009, 21:08 #
В теории, больше потоков селекторов ускорят запись\чтение в канал. На практике не скажу, не проверял smile Одного потока селектора на тысячу пользователей, при правильной реализации, хватит с запасом.

Добавлено позднее:
Цитата (ivg @ 23.1.2009, 21:08 findReferencedText)
Исходники у вас в IDE, скомпилированные классы деплоите в БД, ну а в остальном всё аналогично отладке приложений на Application серверах, с учётом того что сервер умеет грузить классы из БД.


Я предпологал что исходники в БД smile
Мы же вроде функционал аналогичный php обсуждаем. Естественно что если исходники в IDE то проблем нет :)

Добавлено позднее:
Цитата (ivg @ 23.1.2009, 21:08 findReferencedText)
Но ведь вы не знаете ни требований, ни игровой сложности, ни мощности железа ну и т.д.


Судя по тому что это игра - траффика будет кушать не много, до 5 мегабайт за час.
На железе под серьйозные проекты не жлобятся. Ну а если "потыкать", то даже не стоит рыпаться.
Игровая сложность - если php справлялся, то java и подавно :)

Хотя по хорошему надо было бы посмотреть со всех сторон.
ava
Temdegon | 23.01.2009, 21:36 #
Попробую полистать книжку по nio, вдруг пойму что-то... С пул ThreadPoolExecutor-ом я с недавнего времени знаком. Хочется написать так, что бы в корне поменять отношение фирмы к Java... Хочется верить, что все получится. Насчет производительности - ПХП-сервер мы тестировали, запустив его на обычной рабочей машие, 3 человека - реальных людей с других компов и 50 ботов на одной локации. В общем сервер показал себя в лучшем свете, производительность уперлась в клиент а не в сервер. Но тут реальных клиентов всего 3, все это в локальной сети. Так что это получился скорее тест флеш-движка, а не сервера. На большом кол-ве клиентов, коннектящихся через медленные каналы я думаю все выглядело бы не так здорово. Но проверить это нет возможности. Надо придумать какой-то способ тестирования, но мыслей по этому поводу нет. Не нанимать же сотню тестеров для этих целей.
Всем спасибо за дельные советы. Буду читать, разбираться и пробовать.
ava
Temdegon | 23.01.2009, 22:11 #
Возник такой спор. Есть ли смысл использовать многопоточность вобще?
Опишу ситуацию более конкретно.
есть 20 клиентов, которым нужно послать сообщение.
в сервере это реализуетя так:
для этого прогоняется цилк по массиву пользователей и для каждого выполняется команда

$result = socket_write(сокет, строка)

ВОпрос в следующем: ждет ли цикл, пока данные передадутся и вернется результат, или оно просто послало и все?
Если ждет, то многопоточность имеет большой смысл, а если нет, то вроди как это даст не очень много.
Опишите плиз плюсы и минусы использования многопоточности в данной ситуации
ava
COVD | 24.01.2009, 04:05 #
Цитата


ВОпрос в следующем: ждет ли цикл, пока данные передадутся и вернется результат



Врядли. Пишут обычно во внутренний буфер, т.е. в отличие от чтения нет смысла эту операцию блокировать.

Однопоточная реализация на nio наверняка имеет преимущество, когда много постоянных соединений, но активных среди них мало. Если все постоянно соединенные активны ( все смотрят видеотрансляцию с сервера ), то злые языки шепчут, что один поток на клиента ( io ), возможно, поэффективней будет.

Начинать проще на Java, чем на С++.
ava
Temdegon | 24.01.2009, 04:39 #
Цитата


ВОпрос в следующем: ждет ли цикл, пока данные передадутся и вернется результат

Цитата



Врядли. Пишут обычно во внутренний буфер, т.е. в отличие от чтения нет смысла эту операцию блокировать.





Придется каким-то боком проверить экспериментально. Есть мысль попробовать запустить локально сервер и несколько клиентов, но заставить клиентов работать через внешний прокси, что бы внести задержки. Тогда будет возможно сравнить однопоточный и многопоточный способ в разных вариациях, с разными задержками и различным кол-вом клиентов.
ava
COVD | 24.01.2009, 05:21 #
блокирующая ли операция socket_write (если в этом вопрос) наверное проще из документации,
ava
Temdegon | 24.01.2009, 05:46 #
Пытался читать документацию, гуглил - ответа на этот вопрос не нашел.
ava
53x7u5 | 26.05.2010, 15:53 #
Temdegon, позвольте полюбопытствовать, чем закончилось ваша работа над данной задачей? Надеюсь что спустя год вы все еще тут smile
Судя по всему я иду по вашим стопам. Ваш опыт был бы ценен!
ava
Temdegon | 26.05.2010, 19:27 #
Цитата


Temdegon, позвольте полюбопытствовать, чем закончилось ваша работа над данной задачей? Надеюсь что спустя год вы все еще тут smile

Судя по всему я иду по вашим стопам. Ваш опыт был бы ценен!


К сожалению, все заглохло даже не начавшись. Не потому что джава не подходит для этого =) Просто появились более интересные проекты. Сервер по сей день на пхп, игра продолжает делаться. Решили, что когда проблемы возникнут, тогда и начнут их решать. Вот есть такая штука http://developers.facebook.com/blog/post/358. Преобразует PHP-код в C++ и компилит его. Вполне может решить проблемы производительности.
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить