воскресенье, 4 сентября 2011 г.

Запуск нескольких экземпляров сервера Reddwarf на одной машине

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

понедельник, 28 февраля 2011 г.

Reddwarf Periodic Profiler 0.1

Для игровой платформы Reddwarf (бывший Darkstar) существует собственный профайлер.
Он работает таким образом: записывает информацию обо всех выполненных задачах в бинарный лог собственного формата. Этот лог можно открыть с помощью специальной программы, благодаря которой можно будет посмотреть, что за задачи были выполнены, как долго, сколько задач завершились неудачей. Недостаток данного профайлера в том, что необходимо записывать всю информацию о задачах в большой бинарный лог: на боевом сервере это быстро заполнит диск, к тому же файлы лога надо будет передавать на локальную машину для анализа и просмотра.

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

Страничка проекта: http://code.google.com/p/reddwarf-periodic-profiler/

среда, 16 февраля 2011 г.

Этот безумный JMX, jconsole и 127.0.1.1

В моем сервере на платформе Reddwarf для мониторинга производительности сервера используется JMX.
Для этого добавляю в параметры запуска java-машины -Dcom.sun.management.jmxremote.port=3333 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false . В результате сервер запускается с JMX-агентом, к которому можно подключиться с помощью JConsole.

После успешных экспериментов с JConsole я настроил выгрузку данных в cacti. Для этого использовал jmxtrans. Он делает запрос к серверу, получает данные и сохраняет и в архив. Всё замечательно...

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

JConsole подключаться не хочет:

Connection failed: Retry?
The connection to mygameserver.ath.cx:3333 did not succeed.
Would you like to try again?

Без объяснения причин.

пятница, 21 мая 2010 г.

Нестабильность Enum.hashCode() и HashMap

На днях обнаружилась любопытная особенность enum'ов. В коде сервера я использовал ScalableHashMap для хранения некоторых данных, где ключом является enum. ScalableHashMap - это специальная реализация хешмапа для сервера Reddwarf.

После первого запуска сервера и инициализации карты всё работало замечательно.
Потом ScalableHashMap был сериализован и сохранен на диск.
Дальше сервер был перезагружен, и ScalableHashMap десериализован с диска.
Делаю ScalableHashMap.get(key) и... получаю null!
Вывожу ScalableHashMap на экран с помощью toString() - там всё есть! Но почему-то он не хочет доставать записанные данные.

Оказалось загвоздка вот в чем:
Enum использует hashCode(), унаследованный от Object(). Следовательно, при перезапуске сервера меняются адреса ссылок, соответственно меняются хеш-коды объектов. И из карты невозможно вытащить объект с новым хеш-кодом, сохраненный по старому хеш-коду!

вторник, 20 апреля 2010 г.

Sun Tech Days 2010

"Как жаль, что эта конференция проходит не в Москве" - думал я в прошлом году, когда понял, что не получится внезапно поехать на Sun Tech Days 2009.
"Как хорошо, что эта конференция проходит не в Москве" - думал я в этом году, прогуливаясь по северной столице по прекрасной погоде, любуясь красотами этого замечательного города и предвкушая много нового и интересного на конференции.

пятница, 19 марта 2010 г.

Как получить Unix PID в Java-приложении

Для контроля работоспособности сервера я использовал monit. Очень удобная штука, единственной сложностью оказалось то, что monit требовал, чтобы приложение писало свой PID в файл.

В результате недолгих поисков был найден способ узнать PID: Java-приложение должно запустить процесс, который выведет PID родителя. Один из самых простых вариантов - выполнить команду "echo $PPID" командного интерпретатора bash ($PPID - переменная, хранящая PID родительского процесса).

import java.io.*;

public class UnixUtils {

public static String getPid() throws IOException, InterruptedException {

// Запускаем bash с параметром -c, что означает "выполнить команду"
// Командой будет "echo $PPID" - вывести PID родительского процесса
ProcessBuilder pb=new ProcessBuilder("/bin/bash", "-c", "echo $PPID");

Process pr=pb.start();
pr.waitFor();
// Если процесс завершился успешно, вернул код 0, считаем, что он нам вывел
if (pr.exitValue() == 0) {
BufferedReader outReader=new BufferedReader(new InputStreamReader(pr.getInputStream()));
return outReader.readLine().trim();
} else {
return null;
}
}
}

понедельник, 15 февраля 2010 г.

Цветное логирование

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

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