Как не нужно писать большие сервера

    Те, кто мог видеть мою прошлую статью (а она довольно related к данной теме), знают, что вот уже больше полутора лет я разрабатываю собственную реализацию сервера Minecraft, рассчитанную, в первую очередь, на высокие нагрузки. Тем не менее, в своей работе мы используем так же и стандартный сервер (Bukkit) для нескольких мини-серверов, просто чтобы было разнообразие. И вот, столкнувшись с очередной версией сервера, которая стала раз в 5 хуже предыдущих, я уже не выдержала, и решила написать эту статью.

    Статья больше похожа на рассказ, чем на обучающий материал, так что вряд ли вы почерпнете из неё полезных навыков кодинга, но, надеюсь, кому-то она покажется интересной или даже полезной. Но если вы ходите увидеть кучу кода и примеров, то не открывайте статью, она не об этом. Об этом, надеюсь, будет следующая статья.

    Вам не нужно знать ничего о майнкрафте и особенно о его сервере, в данной статье я хочу просто рассказать, как работает оригинальный сервер Minecraft, а так же его «обвязка» — Bukkit, рассказать, почему такая система не работает и не должна. Я не претендую на идеальные знания о разработке серверов и не утверждаю, что мой сервер написан правильно и лучше всех. Я просто делюсь своим опытом, основанным на двух годах работы с сервером от всем известной Mojang и на полутора годах разработки своего сервера. Вся представленная здесь информация является моим личным мнением, а статья предназначена для расширения кругозора или даже обучения и может быть интересна как новичкам, так и продвинутым профессионалам.

    Начнём, пожалуй, с самого чистого («ванильного») сервера Minecraft, а точнее с того, чем же он вообще занимается. Данные вещи обрабатывает сервер:
    • Чанки — для тех, кто не знает, весь мир Minecraft разделён на куски площадью 16х16 кубов и высотой в зависимости от настроек. Все чанки в радиусе видимости игроков загружены в память сервера и находятся в HashMap-е, каждый «тик» сервера каждый чанк обрабатывается. В это время выполняется следующее: все активные чанки (те, которые находятся в определенном радиусе от игроков) перебираются по очереди. Для каждого чанка выполняется обработка погоды (насыпать снег, ударить молнией), а так же случайная обработка блоков — из всего чанка выбирается несколько десятков случайных блоков, проверяется, нужно ли эти блоки обновлять (по типу блока) и вызывается специальная функция на выбранном блоке.
    • Тайлы — это специальные блоки, которые обрабатываются каждый тик, а не случайно. К данным блокам относятся печи (обновление статуса пережигания материала, оставшегося топлива, это должно делаться равномерно, а не случайно, как тик остальных блоков), так же там находятся спавнеры мобов (блоки, которые спавнят мобов вокруг себя), котлы для зельеварения и подобные вещи. Они все хранятся в списке (List), который заполняется при загрузке чанка или при установке нового тайла во время работы, и перебираются каждый цикл по очереди.
    • Срочные блоки — они, конечно, так не называются, но тем не менее, это блоки, которые нужно обработать «срочно», то есть на следующем цикле или с небольшой задержкой (тоже в циклах, тут все считается в циклах, даже время, даже аллах), а не случайно, т.к. случайные блоки обрабатываются раз в несколько минут в среднем. Обрабатываются примерно как тайлы, только у них может быть указана задержка, через сколько циклов их нужно обработать. Задачи на обработку обычно генерируются во время работы сервера из-за действий игрока или других блоков. В частности, так обрабатывается редстоун, который должен очень быстро реагировать на внешние изменения, блоки огня, текущая вода и подобные.
    • Обновление света — Minecraft использует статическое освещение, разделенное на блоки. Каждый блок имеет свой уровень освещённости от 15 до 0. При изменении блоков их освещённость должна быть пересчитана, алгоритм не очень сложный, но рекурсивный, а так же есть два типа освещения — от блоков (факелов, огня и тп) и от неба, они должны рассчитываться независимо, то есть два раза на каждое изменение (если в мире есть небо, в Nether его нет).
    • Entity — это практически все объекты. Мобы, игроки, предметики, валяющиеся на полу, тележки, лодки, картины, молния, стрелы и прочее. Все они хранятся в одном большом списке и по очереди на них вызывается функция tick(), перед этим проверяется, не умерли ли они, если умерли, то они удаляются из списка и из памяти сервера, соответственно.
    • Спавн мобов — тоже отдельное действие. Мобы спавнятся в определенном радиусе от игрока, при этом выбирается случайная точка в чанке и на основе нескольких сдвигов в разные стороны выбирается, можно ли поставить туда моба, и он создаётся
    • Обработка игроков — все пакеты, которые прислали игроки необходимо обработать, очевидно.
    • Загрузка и генерация чанков — если происходит попытка доступа к блоку чанка, которого нет в памяти, чанк должен быть загружен с диска, если его нет на диске, он должен быть сгенерирован. Не надо объяснять, что жесткий диск почти всегда очень узкое место. Генерация чанка ещё сложнее, чем его загрузка.
    • Сохранение чанка — во время общего сохранения сервера или просто, когда чанк долго не использовался и может быть выгружен, чанки необходимо сохранить на диск — преобразовать в поток и записать в файл.
    Казалось бы, все нормально и тут нет ничего преступного, все сделано довольно хорошо и добавить нечего. Проблема тут такая: всё это обрабатывается в одном основном потоке. В последних версиях в Mojang почитали немного про многопоточные штуки и научились сохранять чанки на диск в отдельном потоке. Безусловно это прорыв, потому что это было чертовски узкое место, давным-давно сервер сохранялся по 15 минут и на это время полностью вис, теперь такого нет. Тем не менее, проблема не решена.

    Вы спросите, в чем же тут проблема? Так многие делают: основная логика приложения в одном потоке, это очень удобно программировать, не нужно заботиться о синхронизации и прочих проблемах параллельных приложений. Проблема тут в том, что если на сервере больше 40 человек, вместо стандартных 20 циклов он делает уже 15, если 70 человек, то 10, если 100 — то проседает до невероятных значений. Это при том, что у меня вообще-то мощный 6-ядерный Core i7 и 64Gb оперативной памяти! И куда мне теперь деть эти ресурсы, если из 12 потоков заняты от силы два?

    Не буду пустословить, приведу пример:
    На сервере 223 игрока, при этом радиус видимости выбран достаточно маленький, в памяти находится 46577 чанков, 524 «срочных» блока, 87 блоков редстоуна и поршней, 11240 Entity предметов, 4274 Entity животных, 19 тележек и лодок, 717 других Entity, игроки, которые тоже являются Entity и требуют соответствующей обработки.
    Количество тайлов и обновлений света мой сервер не выводит в информации (мне это не нужно), но можете поверить, их много.

    Одна лишь обработка животных ужасно тяжелый процесс — они регулярно выполняют поиск пути, поиск других Entity вокруг, у них есть AI (в последних версиях довольно продвинутый), поэтому обработать 4 тысячи животных — уже большая работа.

    Обойти 3 миллиона блоков (примерно столько обрабатывается случайных блоков при таком количестве чанков) — тоже не тривиальная задача.

    11 тысяч предметов надо сдвинуть, сделать некоторые другие действия, отправить обновления об их положении игрокам и прочее.

    И всё это нужно успеть сделать за 50 миллисекунд, иначе все начнет тормозить, ведь скорость рассчитывается в циклах. Если сервер делает меньше циклов в секунду, чем должен, то, например, мобы начинают ходить медленно и рывками. Плюс расчётов в циклах очевиден — если сервер подвиснет или произойдёт огромная сборка мусора (сервер ведь на Java), то не получится так, что тележка, едущая на полной скорости на следующем цикле превратится в быстро движущийся маленький объект, и придётся рассчитывать её движение по более сложным алгоритмам.

    При этом есть ещё и Bukkit!
    Bukkit — это такой «враппер» для ванильного сервера. Он добавляет API для создания плагинов, он супер-удобен для разработчиков плагинов и сделан действительно качественно. Но, грубо говоря, всё становится только хуже. Если игрок присылает пакет, что он немного сдвинулся или повернул голову… создаётся событие и посылается по всем плагинам, которые его обрабатывают. А при этом функция обработки движения и так довольно сложная. При ломании блока или установке происходит то же самое, а так же при около сотни других действий, которые создаёт игрок или сам сервер, включая махание рукой, смена состояния редстоуна, перетекание воды, спавн моба, AI, тысячи их… То есть, как бы система хорошая, но создаёт кучу дополнительных вызовов при обработке всего.

    К счастью, некоторые разработчики плагинов научились вытаскивать тяжелую логику своих плагинов в отдельный поток. Яркими и хорошими примерами служат плагины OreObfuscator и Dynmap. Первый «чистит» посылаемые игроку блоки от лишних данных, чтобы игрок не мог читами смотреть сквозь стены. Он делает это в отдельном потоке, складывая пакеты в очередь и обрабатывая их отдельно от логики сервера. Второй генерирует динамическую карту для браузера, тоже очень качественно сделан. В общем, хвала им, что не нагружают основной поток ещё сильнее.

    Так же есть плагин, который уменьшает количество вещей, которые обрабатывает сервер за цикл. Объединяет лежащие рядом предметы, выгружает мобов, ограничивает обработку чанков. Это очень круто, ни один сервер не обходится без этого плагина — NoLagg.

    Как делать правильно (по-моему)
    Мы долго мучились со всем этим, когда полтора года назад наш онлайн вырос до 100 человек, а скорость работы просела до 0.5-1 цикла в секунду. Мы пытались делать оптимизации сервера, правили код, пытались убрать как можно больше лишнего, изменили в некоторых местах работу не по циклам а по секундам (например, в печи. В Bukkit это потом тоже добавили… через несколько месяцев). В конце концов мы достигли ужасной нестабильности сервера и решили плюнуть на всё это.

    Единственным вариантом, который сможет обеспечить нам комфортный онлайн такого количества игроков, какой мы хотели, был масштабируемый сервер. Не думаю, что нужно объяснять, что поток у процесса сущность не масштабируемая, может работать только на одном ядре процессора одновременно и его производительность ограничена производительностью ядра. Ядра в процессорах сейчас довольно производительные, но и работы много, да и процессоры сейчас делают многоядерными, не то время, чтобы не делать что-то многопоточным.

    Разделить уже существующий сервер на несколько потоков не представляется возможным. Многопоточное программирование — штука тонкая, сложная, требующая большого знания кода, с которым работаешь, и в существующее приложение практически не встраиваемая. Код надо писать с нуля.

    Так родился сервер, в основе которого было заложено как можно больше потоков: мир делится на куски по 64х64 чанка и каждый такой кусок обрабатывает чанки в одном потоке, один поток для обработки срочных блоков, один поток для редстоуна и поршней, один поток для мобов, один поток для предметов, один поток для тележек, один поток обрабатывает другие Entity и прочую информацию о мире, один поток пересчитывает свет, четыре потока по разным частям света сохраняют мир на диск, один поток рендерит карту, один поток занимается обслуживанием сервера и команд консоли, обновляет статистику. Для игроков используется система, которая позволяет обработку пакетов ставить либо на отдельный поток для каждого игрока, либо на пул потоков, либо на отдельные потоки для каждого игрока. При этом всё можно разделить на ещё несколько потоков: обрабатывать один и тот же тип объектов хоть в 20 разных потоках. А так же Netty (NIO) в качестве сетевого движка, в отличии от стандартного I/O.

    Разработка стабильной версии такого сервера, не обладающего всем функционалом, стоило примерно 8 месяцев работы одной меня без обладания опытом. Весь код рассчитан на асинхронный доступ ко всем данным. Но оно того стоило — совсем недавно мы поставили рекорд в 559 человек, которые не просто стояли в одном месте, лагали и снимались на фрапс, а проходили очень большой ивент с редстоуном, и при этом чувствовали себя комфортно.

    Мораль сей басни такова: если вы рассчитываете на то, что ваш проект будет хоть сколько-нибудь популярным и думаете, что хоть чуть-чуть теоретически возможно, что на сервере будет хоть сколько-нибудь много человек… не поскупитесь на создание масштабируемой архитектуры.

    Жду ваши гнилые помидоры, предложения по улучшению этой статьи, а так же предложения по тому, что бы вы хотели увидеть в следующей статье, которая когда-нибудь будет.

    Поток мыслей может содержать орфографические ошибки, т.к. писалось на одном дыхании.
    Метки:
    Поделиться публикацией
    Комментарии 271
    • –17
      Так родился сервер

      Где исходники? Где примеры? Где GitHub? Где это всё?

      Зачем эта статья?
      • +26
        Ответ на ваши вопросы даже не под хабракатом.
        Исходников, очевидно, нет — проект коммерческий и с огромным уровнем конкуренции.
        • +8
          Расскажите пожалуйста, в чем доход, и почему такой уровень конкуренции? Если такие проекты, как вы описали в статье, настолько рентабельны, то я (и не только после вашей статьи) сейчас как зохаваю весь рынок…
          • –24
            Что уж там, может вам сразу мою квартиру отдать? На счёт конкуренции достаточно погуглить по рунету Minecraft и увидеть, какое количество серверов существует.
            • +6
              Я понимаю, что их много, но на чем же тут зарабатывать? Рекламой? Насколько я знаю внутри игры нечего продавать… Или вход платный?
              • –60
                Я не буду отвечать на этот вопрос.
                • +6
                  Да ладно, это что, секрет? Вы не рассказываете своим игрокам, за что они платят деньги? :) Может я интересуюсь, что я могу у вас купить?
                  • –34
                    В таком случае, вы прошли бы на сайт любого сервера и посмотрели. Да и мой сервер найти не так сложно даже простым поиском по нику в гугле.
                    • 0
                      Ок, доеду до дому, обязательно погуглю :)
                      • 0
                        greencubes.org/?cat=shop#t — оно?

                            При смерти инвентарь не опустошается
                            При входе на сервер нет надписи «Попробуйте через 3 секунды»
                            Вторая точка /home (Как пользоваться вторым домом?)
                            Нет задержки между телепортациями домой
                            Нет отключения по тайм-ауту
                            (Временно) Увеличенный радиус видимости на 3 чанка от стандартного
                        
                      • 0
                        обычно продают разные випки на игровых серверах.
                        • +2
                          Да там карьер-монтаж!
                          Удаление кубов(пластов породы, мусора): 4 рубля за каждую 1000 кубов. Учитываются только кубы, отличные от воздуха.
                          За +50% можно дать все ресурсы из очищаемой зоны в GreenBox. В GreenBox помещаются производные от кубов, получаемые при их выкапывании, например: булыжник из камня.
                          Перенос объектов: 8 рублей за каждую 1000 кубов.
                          При переносе сбиваются защиты сундуков и прочего, регионы, конечно же, остаются на старом месте. Содержимое сундуков остается в сундуках. Поворот не возможен.
                          Засыпание полостей не ценным кубом (земля, булыжник, камень): 5 рублей за 2048 кубов. 
                          Заполнение ценным кубом: 3 рубля за каждые 2048 кубов + цены кубов из магазина.
                          Осушение воды: 5 рублей за каждую 100 кубов воды
                          Заливание водой: 9 рублей за 128 кубов воды.
                          Заливание лавой: 26 рублей за 128 кубов лавы.
                          
                          • 0
                            Такая вещь есть на почти каждом Bukkit сервере, но не все продают её функции. А сама вещь называется WorldEdit'ом
                    • +4
                      А почему сразу нельзя было сказать? Не секретная информация же, и за рекламу никто не посчитает, если спросили.
              • +3
                Вход бесплатный. Но есть же премиум-услуги и предметы/блоки, которые трудновато получить в игре, но легко за донат. Данная схема в последнее время стала популярной во множестве многопользовательских игр.
                • +1
                  Стандартная схема микроплатежей. Не думал что она применима к Minecraft…
                  • +5
                    Практика показывает, что схема вполне применима. Чтобы удостовериться в этом, достаточно погуглить рейтинги серверов Minecraft и посетить несколько сайтов, входящих в «Toп-5», «Toп-10», «Toп-20». У некоторых ссылка на донат видна невооруженным глазом, у других функционал доната появляется только в личном профиле. Но практически везде донат есть. Ибо довольно накладно содержать сервера Minecraft на голом энтузиазме, на своём домашнем компьютере, надеясь на онлайн хотя бы в 30 человек. Ибо не каждый домашний компьютер выдержит то, что описано в данной обсуждаемой статье.
              • +1
                Продаются предметы (те же алмазы добывать достаточно трудоемко). Продаётся внутриигровой функционал, например возможность летать, «приватить» большие участки карты. Продаются статусы, например дающие другой цвет штановимени в чате, скина персонажа или доступ в особые места. Простор для микротранзакций в майнкрафте огромен.

                Честно говоря меня это и отпугнуло в нём. Причем популярный сервер без такой монетизации найти достаточно сложно. Это, конечно, понятно, игра требует очень хорошего серверного железа, а хороший хостинг недешев и на свои деньги его держать мало кто будет. Но в целом народу играет много и видимо им нравится.
                • +5
                  Некоторые сервера даже админку продают. При чем, как ни странно, даже за рубежом, я раньше думала, что это чисто русский уровень адекватности. Важен баланс же.
        • –18
          Ладно, без комментариев
          • +3
            Ну просто вы в каждой бочке затычка, а даже прочитать два первых абзаца не можете, прежде чем вставлять свои комментарии.
    • +16
      Есть такой эмулятор WoW — MaNGOS, и его форк TrinityCore (С++). Когда я начал свой OpenSource проект JMaNGOS на Java, некоторые личности на русскоязычном форуме комьюнити TrinityCore начали утверждать, что Java для таких целей ну никак не годится, и в пример приводили сервер Minecraft.
      Я не был знаком с Minecraft сервером, но теперь все стало на свои места %)
      • –6
        Я вас уверяю, Java одна из лучших платформ для разработки серверов, и это подтверждают множество крупнейших IT-компаний мира, которые делают огромные Enterprise проекты на Java.

        Java не лучшая платформа для создания клиентских графический приложений, т.к. большинство библиотек для 3D и физики, созданных игровой индустрией, на неё не портированы.
        • +5
          Я то это знаю, вы еще раз прочтите мой коммент %)
          Я — Java евангелист, если что.
          • +2
            Проблема в том, что нужно хоть немного уметь писать на Java. А то наберут хардкорных C-программистов (которые даже от C++ нос воротят всю жизнь) и заставят их писать код. А потом «у нас Garbage Collector тормозит» или ещё какая ерунда.

            В последнем таком проекте, который я видел, чуваки написали свой кэш — клали в HashMap объекты на 5-60 секунд, а потом клали туда новые на их место. Размер YoungGen маленький, survival ratio тоже. Такой ужас начался… Как будто специально писали чтобы «убить GC».
            • +2
              Кэш в яве уже давно не нужен. Ещё, кажется, с 1.5 отпала необходимость в подобного рода решениях, потому что быстроживущие объекты создаются на стеке… Короче да, надо знать что ты делаешь, и язык становится отличным.
              • +3
                Быстроживущие объекты создаются на стеке только с 1.6 или 1.7! И все равно ключевое слово struct не помешало, есть места где подтормаживает.
                • 0
                  Не могли бы пояснить, что вы имеете ввиду (я не смог нагуглить)? У нас стек не порвется, если мы создадим там огромный объект, пусть и быстроживущий?
                  • +1
                    1. Гуглите Escape analysis.
                    2, Не во всех версиях он включен. В 1.6 надо было включать, в 1.7, вроде бы, включен по-дефолту.
                    3. В описанном выше случае «чуваки написали свой кэш — клали в HashMap объекты», стек вряд ли поможет, т.к. кеш обычно используется в нескольких потоках.
            • +1
              Верно говоришь… А потом еще скажут переписать всё на С или на Эрланг :)
              • 0
                Да я не против. Просто я последнюю неделю читал код сам-знаешь-какого-проекта. И количество реальных facepalm'ов было ого-го. Самый большой я тебе ещё расскажу. Я думаю это даже тебя удивит.
        • +2
          Так всё-таки, насколько реальна проблема с GC? Лаги из-за него есть? Или никто даже не мерял?
          • +2
            Ни разу не встречалась с проблемой зависания из-за GC, при занятой памяти в 10GB он работает пару миллисекунд, при том у меня огромное количество объектов, которые быстро умирают…
          • +9
            Не верьте, тем кто вас минусует, проблема с GC очень даже реальна! Известно, что чем больше памяти вы отдаете Java процессу, тем дороже становится Full GC. Причем он может доходить аж до 5 секунд и больше. Конечно, проблема несколько преувеличена, потому что существуют JDK (Azul), которые справляются даже с ТБ памяти на ура. Но таких алгоритмов пока нету в OpenJDK. Была очень хорошая статья на хабре про JVM.

            Дам краткий совет: тестируйте приложение пока не достигните Full GC, например проверяйте большое количество юзеров и т.п. Вы всегда должны знать этот момент по результатам нагрузочного тестирования. Как только вы достигли этого предела (а он далеко не всегда равен OutOfMemory), думайте что вам делать с этим :)
            2 варианта: 1) оптимизировать память — не всегда возможно и часто дорого 2) Запустить еще одну jdk (конечно если приложение вертикально масштабируемо) — что дешево, но требует больше памяти
            • +2
              Full GC не нужен. Если вы дошли до Full GC, у вас память утекла, тут уже на лицо не шататная работа сервера.
              • 0
                Не всегда. Если у вас много потоков и они переключаются постоянно, то общей памяти может не хватать, хотя она будет освобождаться своевременно.

                Я наблюдал стабильную(!) работу системы с пиковыми нагрузками и со стабильным Full GC (каждые 15 секунд), но запросы обрабатывались и система работала, хоть и медленно.
                • +1
                  Не всегда. Если у вас много потоков и они переключаются постоянно, то общей памяти может не хватать, хотя она будет освобождаться своевременно.
                  Количество потоков тут роли не играет, я могу и одним потоком засрать так, что у меня будет каждые пару секунд память ворошится под yg и скапливатся все в og.
              • +1
                Full GC не нужен
                Full gc хоть и зло, но увы, практически не избежен. Даже если поиграться с настройками jvm, то мы можем многократно увеличить время до полной сборки (путем увеличения yg), но полностью его исключить — увы, я не верю в столь оптимистичный сценарий. Но правда это все бессмысленно потому что избавится от Minor gc в сотни раз сложнее (привет doEscapeAnalysis, который давно уже по дефолту включен), а в некоторых случах не возможно вовсе.

                Если вы дошли до Full GC, у вас память утекла, тут уже на лицо не шататная работа сервера.
                Когда вы станете чуточку более опытнее, к примеру поработаете с несколькими высоконагруженными серверами, которые архитектурно разные, то вы не будете делать такие громкие заявления*

                * да, на высоконагруженном игровом сервере full gc это ужас-ужас и может обернутся невероятными проблемами, но обычно стараются делать так, что бы время до full gc было гораздо больше нежели время работы сервера.

                * в не совсем высоконагруженном игровом проекте, с небольшим хипом (допустим ±2гб) и не совсем сложной разветвленной стуктурой классов full gc (если мы говорим о параллельной сборке мусора) может занимать совершенно небольшое время (я сейчас про STW), которым можно пренебречь.

            • +2
              Ну я поэтому и спрашиваю насчет лагов GC, что эти самые лаги как минимум квадратичны по количеству объектов (иначе не выяснить, где же мусор), а существенно улучшить алгоритм Дийкстры вроде как до сих пор не сумели. То есть грабли вылезают именно на хай-лоаде.
              Насчет минусующих как-то фиолетово, я тролль сотого уровня.
              • +1
                Проблема GC происходит только если у вас память кончилась. Но если у вас память кончилась, GC для вас не самая большая проблема.
                • +2
                  Если у меня кончилась память, я воткну еще памяти. Терабайт ОЗУ, если он обоснован — сегодня не проблема.

                  PS. И да, именно из-за GC я пишу (командую писать) серверные части строго на плюсах. Тотальный контроль над всем + столь не любимые авторшей этого топика очереди сообщений между потоками + неблокирующие структуры данных решают.
                  • +1
                    Если вы не забили память, то и о GC вам нечего волноваться. А вот поволноваться о том, что вы забыли в C++ удалить объект, а выясните вы это только через 3 недели работы сервера, когда 1TB памяти уже забьётся… вот это уже проблемка.

                    Очереди сообщений и неблокирующие структуры есть и Java. На счет структур, они там вообще почти все не блокирующие. А необходимость тотального контроля мнимая, но это уже срач ассемблер против высокоуровнего языка. На самом деле, компилятор и JIC гораздо умнее ваших программистов и знает как лучше делать вещи.

                    Кстати, на плюсах тоже реализуют сборку мусора, и не спроста.
                    • +11
                      В-общем, не буду холиварить насчет языков.
                      На старте моего проекта в 2006-2007 гг. пробовали и сишарп, и джаву. Обе версии стабильно держали порядка 500-1000 соединений, потом ой. Переписанная практически один-в-один прога на плюсах держала порядка 50000 соединений. На этом вопрос был закрыт.

                      Преимущество С++ в том, что сборку мусора можно организовать очень по-разному. И никакой компилятор/VM никогда не догадаются, какой способ самый правильный в данном конкретном случае.

                      Вопрос про утечки — не более чем вопрос квалификации программистов. Да, в случае ручной реализации сборки мусора эта самая квалификация должна быть очень высокой. Но, если у вас хотя бы стандартная серверная стойка, эта самая квалификация очень быстро окупается.

                      Автоматический GC не решает всех проблем и не позволяет «кодить не думая». Меня пугает тот факт, что в гугле ответов на вопрос «java memory leaks» в 10 раз больше, чем про «C++ memory leaks».

                      В-общем, еще раз, не хочу спорить. Я просто хотел узнать мнение тех, кто пишет нагруженные серверные части на джаве насчет проблем с GC, может за пять лет что-то изменилось.
                      • 0
                        можно поинтересоваться, на чем была сделана сетевая часть? boost.asio, libev, ..?
                        • +1
                          libev в те годы еще из пеленок не вышел, так что пришлось писать ручками на ::select
                      • +1
                        Пока вы будете писать свою сборку мусора в мире уже будет написан десяток серверов которые по скорости и стабильности работы будут работать так же как и ваша поделка с супер адаптивной сборкой мусора.

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

                        На старте моего проекта в 2006-2007 гг. пробовали и сишарп, и джаву. Обе версии стабильно держали порядка 500-1000 соединений, потом ой.
                        Два разных проекта (архитектура, геймплей) правда на одной платформе под популярным сетевым фреймворком в яве, один на 200 уже умирает выжирая все ресурсы до которых может дотянуться, другой 25 тысяч держит и жрет скромненько процессора и нормально так памяти (25 тыщ игроков, как никак в онлайне).

                    • +1
                      И да, насчет «почти всех неблокирующих структур данных в джаве» — можно пруфлинки?
                      • –5
                        Боюсь ошибиться, уж не говорим ли мы про разные вещи. Но из блокирующих структур я знаю только BlockingQueue, все стандартные и не стандартные списки, сеты, мапы и прочее не блокируемые.
                        • +6
                          «Стандартные» структуры не threadsafe.
                        • 0
                          Под «неблокирующими структурами» я имею в виду такие, что если два/три/десять потоков полезут одновременно скажем добавлять элемент в конец структуры, ни один из них не окажется заблокирован мутексом/семафором/WaitFor*Object/Synchronize/YouNameIt.

                          Подобные структуры в первую очередь нужны для организации очередей сообщений между потоками. Но все (известные мне) реализации работают сильно медленнее традиционных (блокирующих) структур (зато имеют константный worst-case и исключают дедлоки).
                          • 0
                            java.util.concurrent, да. Я не очень в нём разбираюсь, но вроде там используются атомарные синхронизации и работает это всё довольно быстро. Меня же пока полностью устраивают стандартные структуры… то есть не то чтобы стандартные, я их не использую потому что стдлиб почти всегда хуже альтернатив, но не threadsafe.

                            Я ж не харкорный бородатый программер, я меньше двух лет пишу на яве, а это мой самый серьёзный проект)
                          • +2
                            Что вы конкретно хотите? Добавление в конец какой структуры? Если очереди, то, например, вот. Вообще, concurrency framework на java предоставляет отличный базис для имплементации подавляющего большинства задач, связанных с многопоточностью.

                            Кроме того, если душа лежит к message-oriented программированию, то есть несколько реализаций Actors model на джаве.
                            • +2
                              Я хочу узнать, возможна ли на современной JVM реализация многопоточного сервера, который не будет уступать по производительности по порядку коэффициента перед О() аналогичному серверу на С++, работающего по модели конечного автомата (FSM).
                              Пять лет назад всё утыкалось в GC с его О(n2). Как сейчас — вот это я и хочу узнать.
                              • +1
                                Сейчас есть JIT, есть разные реализации GC, некоторые из них параллельные и неблокирующие. В целом можно сказать, что джава сейчас почти не отстает от си в производительности. Можно нагуглить уйму статей на эту тему.
                                Правда, я не совсем понимаю, что вы имеете в виду в данном случае под конечным автоматом. Насколько я понимаю, реализация простого конечного автомата не требует GC.
                                • +1
                                  Ну вы вообще представляете, что такое конечный автомат? Состояния, события и всё такое? Если нет, то вам курить учебник по формальным грамматикам.

                                  Если да, то вот пример по теме статьи:

                                  Юзерский клиент присылает пакет «я пошел налево».

                                  Полученный пакет автоматически попадает в первое состояние автомата: «пришел пакет».
                                  В этом состоянии проверяется, действительно ли это пакет, или какие-то хацкеры шлют всякий мусор.
                                  Во втором состоянии проверяется, что пакет пришел от залогиненного юзера, а не откуда-то еще.
                                  На третьем разбирается действие, которое сделал этот юзер — «пошел», «выстрелил» или «протупил».
                                  На четвертом разбирается, куда именно он пошел — «налево», «направо» или подпрыгнул.
                                  И т.д.
                                  Огромное преимущество в том, что каждое состояние очень легко и очевидно пишется.

                                  Теперь нарисуйте весь автомат для всех возможных состояний пакетов.

                                  И запустите обработчик каждого состояния в отдельном потоке. А переходы между состояниями оформите в виде очередей сообщений.

                                  Если у какого-то потока пустая очередь, то он просто передаёт управление другим потокам (т.е. запускает #ifndef _WIN32 || _WIN64 nanosleep (1); #else sleep(1); ).
                                  Скорее всего, потоков у вас будет сильно больше, чем процессорных ядер.
                                  Но это плюс, потому что ОС сама разбалансирует нагрузку между вашими потоками.

                                  Единственная проблема — та самая очередь, в которую попадают сообщения для потока. Для внутренних стадий (запрос базы, отправка ответа клиенту и т.п.) там возможна серьезная конкуренция.
                                  • +2
                                    Это — не конечный автомат, а конвейер. В конечных автоматах события обрабатываются только один раз.
                                  • +6
                                    по-моему вам стоит вместо плюсов брать эрланг.
                                • –3
                                  UPD: реализация FSM, описанног выше, как раз-таки требует изощренного GC, способного эффективно работать между потоками.
                                  • +2
                                    Я почитал ваши комментарии выше. В современных высоконагруженных системах горизонтальная масштабируемость идет перед вертикальной. Ок, ваш сервер на C будет держать 100000 коннекшнов против 20000 на джаве. А что если у вас завтра будет 10кк? И тут уже выплывают совершенно другие узкие места, такие, как взаимодействие с БД, синхронизация и транзакции между разными нодами в кластере. А тут уже необходимо писать максимально простой и высокоуровневый код. И чем больше задач ложится на «стандартные» хорошо протестированные фреймворки, тем лучше.
                                    Я считаю, что система, где с нагрузкой справляется один сервер, не является highload.
                              • 0
                                Если вы написали нормально откуда GC? Если вы поставили нормально памяти в чем проблема.

                                Приведу вам пару примеров из жизни:
                                — Тестирую программу 100 параллельных пользователей (запросы достаточно емкие), все работает Young GC каждые 5 секунд по 0.2- все ок. Работает часами
                                — 200 users — Young GC каждые 2 секунды по 0.1, работает часами.

                                — 1000 users — Young GC каждые 1 секунды по 0.2, Full GC каждые 15 секунд по 4 секун ды, работает часами.

                                Утечек памяти нету все работает стабильно :) Знайте как ведет ваша система и не допускайте Full GC и все будет линейно и предсказуемо.

                                P.S.: чем больше памяти вы дадите Java тем больше риск что она загнется от Full GC! И Young GC станет дороже. Так что не давайте более 8Гб и масштабируйтесь независимыми JDK.
                      • +2
                        Загуглите java.util.concurrent.
                        • +2
                          Пошла серьёзно загугливаться в эту тему, может почерпну что-нибудь очень полезное.
                        • +1
                          Кажется, я должна вам выразить свою признательность, в первом же мануале я нашла очень интересную для себя вещь, которую без условно должна попытаться использовать в сервере и вообще взять на заметку в дальнейшем.
                          • +1
                            Не за что. Советую прочесть книжку Java Concurrency in Practice (Brian Goetz & Kº). Если будут вопросы — обращайтесь.
                            • 0
                              Видела, но не нашла, где взять нормальную версию. По этому, в начале работы пришлось изобретать велосипед… в принципе, велосипед едет.
                          • +1
                            В таком случае купите/скачайте Java Concurrency in Practice
                            Там еще много интересного!

                            Повтор. Добавлю, что после прочтения книги, возможно появится желание переписать все с нуля. не сопротивляйтесь =)
                        • 0
                          а также java actor and dataflow library or framework

                          Это выше уровнем, чем java.util.concurrent.
                    • 0
                      >>На самом деле, компилятор и JIC гораздо умнее ваших программистов и знает как лучше делать вещи.
                      Как интересно, можете детальнее раскрыть свою мысль?
                      • +1
                        Я бы не сказал, что умнее, но JIT компилятор всегда ставит подсказки предсказания перехода. Он ведь компилирует не только код, у него ещё есть статистика по исполнению этого кода 10000 раз в интерпретируемом режиме. Предсказание переходов — это только пример, но уже только это позволяет CPU намного реже сбрасывать конвейер. И выдавать большую производительность.

                        Грубо говоря, чтобы написать код на C, который будет производить такой же по производительности машинный код, надо всегда-всегда ставить эти макросы LIKELY/UNLIKELY. Как в ядре Linux.

                        А на ASM ещё лучше оптимизировать можно. Вот только на Java (когда знаешь что делаешь) код такого качества пишется быстро и легко. Легче, чем на Asm, по крайней мере :)
                        • 0
                          Вы очень прямолинейно восприняли мой вопрос :-) он в прочем был адресован не Вам, но так как видимо «ответа» от автора статьи я уже не получу, можем подискутировать с Вами.
                          Я очень часто в юности слышал фразу: компилятор большой — ему видней. Так обычно оправдывались самые темные уголки кода или просто нежелание разбираться в вопросе. Иногда это оправдано, иногда — нет.
                          Грубо говоря, чтобы написать код на C, который будет производить такой же по производительности машинный код, надо всегда-всегда ставить эти макросы LIKELY/UNLIKELY. Как в ядре Linux.
                          Я правильно Вас понял что Ява обгонит по производительности аналогичный код написанный без LIKELY/UNLIKELY на С?
                          • –2
                            C — это понятие низкоуровневое. Его код по-умолчанию самый быстрый (условно), и управлять им можно очень хорошо. В C++ с этим гораздо хуже. Но тем не менее, я утверждаю, что ДА, с теми же трудозатратами большой и сложный код на Java будет скорее всего быстрее. Бенчмарки вам тут не помогут, потому что мерить производительность огромных проектов написанных на C++ и Java нельзя, потому что, хотя бы, никто не пишет большие проекты сразу на двух языках. В простых кусках кода скорее всего выиграет C/C++, но и то не всегда, отработав некоторое время, код в JVM может перекомпилиться в более эффективный.

                            На самом деле, срач о производительности бессмысленен. Можно спорить лишь о трудозатратах на написание качественного кода на Java и на C++ в соотношении к средней мифической производительности. Java выиграет.
                            • +2
                              Сравнить нельзя, но скорее всего быстрее :-)
                              Я всегда стремился отличать Веру от Знания, чего и Вам желаю.

                              • 0
                                Дело не в вере, а в коде. Rena4ka все верно говорит. Представьте себе разработку проекта на С++. Все шло хорошо, до какого-то момента… потом заказчик захотел вместо заднего колеса велосипеда гусеницу, а вместо переднего — лыжу. Представте себе, чего будут стоить подобные изменения в С++. Код начинает обрастать костылями. В джаве же подобные изменения относительно дешевы, и можно переписать все правильно, без костылей. Вот тут нас и спасает синтаксический сахар.
                                Если бы в конечном итоге С++ проект был бы написан так-же, как и джавовский, он был бы быстрее. Но в реальности так он написан никогда не будет, слишком много человекочасов нужно на постоянно изменяющиеся требования. Не рентабельно. Поэтому в большом энтерпрайзе сейчас рулят джава и C#.
                                • +3
                                  В С/С++ слишком просто выстрелить себе в ногу, а синтаксический сахар это лишь сахар. Профессионалы сделают все на ура и на том и на другом языке, только профи на С++ более редкое явление и стоят дорого, а не профи обходятся еще дороже, поэтому в больших системах бал и правят Ява и С# — порог вхождения низок, за тебя приберут где надо, позаботятся в меру сил, людей найти и оплатить проще.
                                  На счет изменений — вы в это верите или знаете? Хорошая архитектура что на Яве что на С++ это хорошая архитектура, а плохая… ее сахар не спасет :-)
                                  Вообще нет смысла сравнивать Си/Си++ и Яву это разные инструменты под разные задачи, и сравнения в скорости выполнения кода меня лишь умиляют, даже спорить нет смысла, только улыбаться, это разговор не о фактах, это разговор о вере.
                                  Но даже с Явой или C# не стоит лениться, не стоит надеятся на всемогущий компилятор, думать надо, познавать, проверять и не циклиться на одном инструменте, часть большого проекта можно сделать на яве, часть на Си, часть на асме, но говорить что мы сейчас весь дом одним молотком построим потому что он удобен в руке и вообще я его так люблю это наивно.
                                  Вы можете сделать GUI на яве, доступ к базам данных и прочее прочее, но ведь Вам и в дурном сне не привидится писать энкодер H.264 на яве, не будете Вы так же писать серьезный трехмерный движок на C#, не подходящие это инструменты.
                                  • +1
                                    Почему все меряют только скорость выполнения кода? Не забывайте, вас кормит не ваш код, а бизнес, для которого вы пишете ваш код. Поэтому, делая подобную оценку, необходимо учитывать «хотелки» этого бизнеса.
                                    Вы что, станете со мной спорить, если я скажу, что на Java выполнить глобальный рефакторинг или даже переписать отдельный модуль системы будет в сотни раз проще, чем сделать то-же самое на С++?
                                    Быстро работающий код на С++ получится только тогда, когда заранее известны все моменты, и все четко распланированно. Но в реалиях появляются изменения плана, сроки уменьшаются, и еще куча всего происходит. И оказывается, что переписать нет времени, но можно заткнуть костылем. Здесь костыль, там костыль… И вся система — уже костыль. Костыль на С++ не будет работать быстрее, чем нормально написанный код на Java.
                                    • +2
                                      Не воспринимайте на личный счет, я ничего не имею против Явы, хороший язык, делает свое дело, масса людей ни испытывают с ним сложностей и вовлечены в индустрию, с С/С++ такой фокус не прошел — за свою гибкость и скорость люди платят серьезными ошибками, а производители — высокими ЗП своим инженерам.
                                      Но нужно помнить что и С/С++, С#, Ява лишь инструменты со своими плюсами и минусами и принимаясь за дело нужно их выбирать правильно.
                                      Вы что, станете со мной спорить, если я скажу, что на Java выполнить глобальный рефакторинг или даже переписать отдельный модуль системы будет в сотни раз проще, чем сделать то-же самое на С++?
                                      Спорить не буду и уж тем более обсуждать цифры «в сотни раз» :-) Я работаю в компании которая разрабатывает свою электронику для кодирования видео, хранения и прочего прочего. В разработке задействованы и ява и C# и С и С++ и ассемблер, все на нужных местах, хорошее проектирование позволяет легко рефакторить код С++ модулей и проектов, плохое проектирование превращает рефакторинг в ужас на любом языке если это дело запустить.
                                      Предлагаю завершить эту ветку дискуссии, меньше всего я хочел поучавствовать в священной войне :-)
                                      Хотел лишь узнать мнение людей на счет заданных мной вопросов и я его узнал.
                                      • +1
                                        Мы друг друга не верно понял. Статься о server-side приложении на джаве, все вышесказанное мной я аттачил именно к такого рода приложениям. Боже упаси писать декодеры или драйверы на джаве %)
                                        • 0
                                          Фраза «драйверы на яве» звучит как «реалтайм сервер на PHP» =)
                                          • 0
                                            Похуже) Реалтайм на ПХП попробовать можно, но ничего не выйдет. А драйвер на джаве… насколько я знаю, невозможно)
                                            • +1
                                              Вообще, реализуемо. Вспомнить, Singularity от MS — драйвера там были вполне себе managed. Правда, для этого придутся втащить в ядро JVM, но это уже так, мелочи. =)
                                            • 0
                                              А, еще нагуглил JNode. Welcome писать дрова на Яве уже сейчас. =)
                                            • 0
                                              рилтайм на php — dune2d.com :)
                                              • 0
                                                Это не реалтайм в классификации «пакетная обработка/интерактивная обработка/реалтайм»
                          • 0
                            Я бы сказал, что некоторый код на Java на некоторых архитектурах обгонит аналогичный код на C без LIKELY/UNLIKELY на той же архитектуре. Чтобы это произошло, нужно достаточно много потоков, выполняющих разный код — чтобы кэша кода в CPU не хватало на всё. А ещё нужно чтобы на этом коде не очень хорошо срабатывала встроенная в CPU система предсказания переходов.

                            Полагаться на компилятор оправдано, когда знаешь как он работает. Ну то есть все же спокойно пишут MSECONDS_IN_HOUR = 1000 * 60 * 60; зная, что любой компилятор посчитает константу во время компиляции. Так же и с другими оптимизациями. На них можно полагаться, если видел их код.
                  • 0
                    В джаве можно использовать sun.misc.Unsafe для выделения памяти вне кучи. Как раз для тех, кто «знает, что он делает».
                    • +1
                      В джаве можно объявить byte[] heap, выделить туда столько гигабайт, сколько нужно сразу, а дальше все точно так же, как в C.
                      • –1
                        И то и другое совершенная бессмыслица на Java, применимая только в узких вещах и JNI.
                        • +4
                          Не стоит судить так категорично. Поищите java off heap storage
                          • +1
                            Все больше и больше новых для себя вещей открываю в данном обсуждении. Спасибо, для расширения кругозора полезно.
                        • +1
                          ehcache.org/documentation/bigmemory/index
                          это про бессмыслецу
                          BigMemory's in-process, off-heap cache is not subject to Java garbage collection, is 100x faster than DiskStore, and allows you to create very large caches. In fact, the size of the off-heap cache is limited only by address space and the amount of RAM on your hardware. In performance tests, we’ve achieved fast, predictable response times with terabyte caches on a single machine.
                    • +1
                      Да-да, и поверх этого написать свой C++ STL на Java.
                      Очень привлекательно.
              • +3
                При чем тут алгоритм Дейкстры? Выявить мусор можно и за линейное время.
          • 0
            В одной онлайн-игре с сервером на Java оные лаги раньше были обычным делом под конец суточного цикла, разработчики грешили именно на GC.
            Да и сейчас время от времени случается regression, когда в очередном релизе накосячат чего-нибудь.
        • +1
          Буду признателен если поясните в чем плюс явы для высоконагруженного игрового сервера?
          Не сточки зрения евангелизма, а с точки зрения здравого смысла. Почему был выбран этот инструмент?
          • +1
            Потому что это чертовски удобный язык. Ну а вообще выбор был прост — оригинал был написан на Java и я почерпнула очень много опыта из работы с первоисточником, а так же очень удобно писать свой код и видеть как работает то, что я пытаюсь сделать.
            • 0
              Спасибо, упустил из виду что Minecraft был разработан на яве.
        • 0
          А что можете сказать относительно питона — как у него с «большинство библиотек для 3D и физики, созданных игровой индустрией»?
          • 0
            Судя по минусам — питон совсем не предназначен для написания 3D-игр? Или что этим хотели сказать? Я просто никогда с ним не работал, но не на пхп же, который я знаю, писать игры :)

            Если питон вообще не подходит, то какой язык для быстрого вхождения в процесс можно использовать? С/С++ я вряд ли смогу быстро освоить, чтобы внятно писать задания программистам и проверять работу.
            • 0
              www.panda3d.org/

              а для 2д игр отлично подходит www.pygame.org
              • 0
                Спасибо!

                Теперь хоть есть от чего отталкиваться и куда смотреть! На пайгейм раньше наталкивался, а вот панды не видел :)
      • 0
        эмулятор WoW
        Почему проходят годы, но эмули вовки по-прежнему далеки от оффа?
        • 0
          Потому что иначе Blizzard было нечего кушать.
          • 0
            Думаете они саботируют процесс разработки эмулей?
            • +1
              Они делают обновления.
              • 0
                … которые нравятся не всем. Многие и сейчас с удовольствием поиграли бы на предыдущих дополнениях, особенно если админы их постоянно улучшали.
            • 0
              Именно! Давят опенсорс созданием качественного ПО серверов, с которыми невозможно конкурировать одиночкам-опенсорсникам.
              • +2
                TrinityCore отнюдь не один человек разрабатывает… и там ситуация сильно отличается в лучшую сторону от того-же проекта L2J, и тем не менее эмули не дотягивают по _содержанию_ мира, а не по прямоте и производительности кода, потому что опенсорсерам очень трудно конкурировать с армией людей, занимающихся наполнением такого богатого мира как WoW.
                Так что качество ПО и качество содержимого мира — это разные вещи
                • +1
                  Я вынужден с вами не согласиться. Контент комуниздится прямо у близов. А вто реализация сервера MaNGOS/TrinityCore мягко говоря оставляет желать лучшего. Абсолютно не масштабируемая архитектура, ни вертикально ни горизонтально, плюс куча пробелов в реализации, поскольку оригинального сервера ни у кого нету.
                  Алгоритмы работы скриптов, боссов, данжей, формул… всего этого нет в открытом доступе.
                  • +1
                    > Алгоритмы работы скриптов, боссов, данжей, формул…
                    Это и есть контент.
                    • +3
                      Подмена понятий.
                      synchrone говорил о армии людей, которые что то там выдумывают. Но тут нечего выдумывать, потому что сама идея — украсть контент у близов.
                      Остается только проблема архитектуры и отсутствие формул и алгоритмов.
                    • 0
                      Контент в данном случае — модели, текстуры.
                      А «алгоритмы и скрипты» по сути просто эмулируются «наугад».
        • +2
          Целая куча причин. Основная в том, что реверс-инжиниринг. Кроме снифов, кэша, и данных на вовхеде ничего нет.
          • 0
            Простите что вклиниваюсь. Тоже принимал некоторое участие в проекте MaNGOS, ещё когда был БК. Даже предложил ряд патчей, которые впоследствии приняли в ядро (обёртки для вещей, почта с фирменными подложками, формула опыта открытия территорий, имена и статы петов лока).

            Мне кажется, дело в том, что очень много всего необходимо заскриптовать. И да, сниффы. Их вполне можно собирать. Причём, пока реализуешь одно, близзы успеют выпустить новый патч, где всё уже по-другому (подмена опкодов или другой принцип авторизации).
            Кроме того проекты разделены на разные части (ядро сервера, базы данных, скрипты) и не очень хорошо друг с другом взаимодействуют. В итоге всё ещё больше вязнет.

            Так что получается что в этой гонке у близзов все козыри на руках. И им вовсе не обязательно закрывать неугодные проекты.
            • 0
              А что такое сниффы?
              • 0
                Результаты анализа трафика между клиентом и официальным сервером. Разбор пакетов и т.д.
                • 0
                  Не знаете, почему у той же Линейдж 2 с фришками ситуация лучше?
                  • 0
                    Извините, только WoW эмуляции касался, много лет назад.
                  • +1
                    Потому что периодически сливаются официальные сервера со всеми скриптами, конфигами, AI и прочим. Потому что есть официальная база знаний со многими раскрытыми параметрами.
                    • 0
                      Cливаются официально или воруются?
                      • 0
                        Тайна, покрытая мраком. Официально ничего не выкладывается, но как минимум 4 разные версии за все время появилось в паблике (практически по утечке в год). Сначала сервер есть у ограниченного числа лиц (они получают огромную прибыль за счет уникальности сервера на рынке фришардов), потом появляется еще у кого-то, потом начинаются продажи, потом цена падает с десятков тысяч долларов до сотен долларов, а в конце концов файлы становятся общедоступными. В промежутках между утечками идет разработка экстендеров.
                        • +1
                          А на чем зарабатывают владельцы серверов? Донат с рекламой?
                          • 0
                            Только донат. Реклама была бы каплей в море.
                  • 0
                    Как сказал Hint, офф сервер ла2 утекал в сеть. К тому же эмуль написан на джаве, что упрощает процесс фиксинга, рефакторинга и прочего в разы, когда становится доступна очередная порция информации…
                    У мангоса и тринити ситуация печальная, команде приходится вклиниватся в рамки, которые они сами себе создали и громоздить костыли, о глобальном рефакторинге уже никто и не задумывается — слишком сложно будет…
            • 0
              Дополню Ваше сообщение. Так же проблема рандомных опкодов, начиная с Каты.
              Писал немного об этом тут.
    • +3
      >> обсчет освещения на сервере
      Что за наркоман это придумал?..
      У меня слов, кроме «вон из профессии!» нет.
      • +4
        Нотч. Но тому есть веские причины, да и свет тут очень простой: от 0 до 15 на блок.
        • +1
          А можно чуть поподробнее про причины для человека, не игравшего в minecraft?
          • +7
            В темноте спавнятся мобы, на свету нет. Это первое, что на ум приходит.
          • +3
            От уровня освещения зависит скорость роста пшеницы, к примеру.
            • +7
              Ещё деревьев, травы, цветов, выцветание травы. А ещё таяние снега и льда…
        • 0
          Освещение обсчитывается в пределах чанка?

          И вообще — не подскажете толковое описание игровой механики?
      • +3
        Всё просто, монстры (мобы) появляются в зависимости от уровня освещения. Например, для большинства враждебных мобов должно быть очень темно. Поэтому требуется просчёт освещения на сервере.
        • 0
          А от освещенности чего это зависит? Блока, множества блоков etc.
    • +1
      Как вы решаете проблему синхронизации, если у вас отдельные потоки для мобов и для стрел?
      • 0
        С помощью synchronized при доступе к одним и тем же данным.
        • +2
          Почитайте о транзакциях. Начните с JMS, посмотрите в сторону Apache Camel, activeMQ, Hadoop
          • –47
            Я посмотрю, вы тоже самый умный. Я обо всё этом прекрасно знаю, но меня устраивает то, что я использую.
            • +21
              В таком случае, вы языком ошиблись :)
              Я ведь просто посоветовал, да и другим может полезно будет. Зачем же так грубо.
              • –55
                Это ваше мнение, и я рекомендую держать его при себе. Это мой выбор не использовать сообщения, а синхронизировать данные вручную, что бы вы не утверждали, а это гораздо эффективнее, но если у вас не хватает скилла, чтобы самостоятельно обеспечивать синхронизацию данных без дедлоков, долгого ожидания и прочего, то это ваша личная проблема.

                Можете весь свой рейтинг потратить на слив моей кармы, мне пофиг.
                • +25
                  Я принципиально воздерживаюсь от оценок, карм, и так далее, простите :)
                  С какой стати я должен держать свое мнение при себе? Да будет вам известно, комментарии придуманы, что бы выражать свое мнение.
                  А вопрос в скорости разработки и удобстве рефакторинга. Синтаксический сахар, есть такое понятие.
                  Выше вы же сами упоминали о корпорациях, которые гребут деньги на этих технологиях. Вы сами себе противоречите. Вы используете один язык с приемами, характерными для других языков.
                  • –17
                    Вам ниже ответили. Такой метод «синхронизации» потоков не применим на реал-тайм приложениях. Если буду делать что-нибудь, где это более к месту, обязательно не буду изобретать велосипед.
                • +7
                  А почему он должен держать его при себе? Вроде он никого не принуждал, а у нас официально свобода слова.
                  • –11
                    Потому что он предлагал синхронизировать потоки обменом сообщений. Я не обязана искать скрытый смысл и догадываться, что овтет был не на то сообщение.
                    • +1
                      Открою вам небольшой секрет — то как вы передаете сообщения («с помощью synchronized при доступе к одним и тем же данным») — тоже можно трактовать как передачу сообщений. Если вы при этом еще используете notify(All) — то наверняка.
                      • –1
                        Не похоже, по-моему. И нет, не использую.
          • +3
            При чем тут синхронизация данных между потоками и перечисленные вами продукты?
            • +2
              Потому что можно извращаться и обмениваться сообщениями между потоками… а можно нет.
              • +2
                А профайлер что на это говорит?
                Дедлоки бывают?
            • +1
              Пардонте, похоже я с телефона не заметил, что это два разных треда. Выше говорилось про кластеризацию…
              • –8
                Только ниже, а не выше. Принято.