Я новичок в разработке игровых серверов, теперь мне поручено выполнить реорганизацию нашего лог-сервера. Я создаю класс Log для связи между игровым сервером и сервером регистрации.
class Log
{
public:
void encode(Encoder& encoder) const;
int decode(Decoder& decoder);
private:
std::string sql_cmd;
}
На игровом сервере есть класс для отправки запроса журнала на сервер регистрации.
class LogHelper
{
public:
static void LogItemChange(const GameShare::GameItem& item, const PackageChangeDetails& pcd);
{
Log log(get_item_change_sql(item,pcd);
send_to_log_server();
}private:
static std::string get_item_change_sql(const GameShare::GameItem& item, const PackageChangeDetails& pcd);
}
Вопрос в том:
Должен ли я генерировать sql текст на игровом сервере? Если генерировать sql текст на игровом сервере, это плохо сказывается на производительности игрового сервера?
Если не генерировать текст SQL на игровом сервере, то следует генерировать текст SQL на сервере журнала. Я должен отправить данные экземпляра GameItem и PackageChangeDetails на сервер журналов, это усложнит сервер журналов, у кого-нибудь есть хорошие идентификаторы?
Если SQL-файл журнала генерируется игровым сервером, то практически не требуется никакого кода Log-сервера, поскольку он становится промежуточным звеном для менеджера баз данных, о котором игровой сервер почти наверняка уже знает (хотя я думаю, что они потенциально могут быть разными базами данных) или могут легко взаимодействовать с.
Сервер регистрации должен быть отдельным компонентом, который регистрирует в любом удобном для вас формате (производительность, многословность, размер и т. Д.), И, пока API достаточно гибок, его можно записать так, чтобы базовая реализация могла быть заменена без ведома игрового сервера.
Объединяя полное знание базовой реализации с кодом Game Server, вы не только предотвращаете такое будущее, но и вкладываете потенциально много работы в код Game Server, что может быть выполнено отдельным потоком на Log Server. , Не говоря уже о том, что открывая API для SQL, вы помещаете потенциальные ошибки в код игрового сервера, которые в противном случае были бы централизованы.
Прогрессивный подход, основанный на замене, идеален при проектировании объектно-ориентированных систем. Если вы можете избежать связи с чем-либо, кроме API, то вы всегда можете заменить все, что находится под API, без влияния на внешний код (игнорируя ошибки), но это требует продуманной реализации API, чтобы обеспечить достаточную гибкость в будущем. ,
На этом замечании я настоятельно рекомендую вам реализовать API ведения журнала как чисто виртуальный интерфейс, а затем написать поверх него реализацию, которая взаимодействует с базой данных, возможно, с отдельной реализацией, которая регистрирует в текстовом файле (для удобства, локально тестирование без доступной базы данных, если это когда-либо возникает), а также реализация бездействия. Имея в виду первые два, это должно помочь вам улучшить дизайн и избежать связывания.
Это также может привести к некоторому базовому интерфейсу, который реализуют другие ваши классы (например, public: std::string to_log_string() const;
), который затем может быть использован Logger, чтобы ввести любой реализующий объект и быстро преобразовать его в зарегистрированное сообщение.
Все это означает, что SQL, связанный с журналированием, помещается на сервер журналов, а не на игровой сервер. Игровому серверу не нужно заботиться о том, что делает Log Server, кроме общего «ведения журнала».
Не генерируйте текст SQL на игровом сервере. Не делайте этого и на сервере журналов. SQL задним числом должен только подготовили заявления. Генерация запросов во время выполнения примерно такая же безумная, как генерация индексов во время выполнения. Итак, оставьте генерацию окончательного текста SQL в базе данных.
Поэтому API между игровым сервером и сервером журналов должен содержать только те переменные, которые вы хотите зарегистрировать, а не код для этого.
Тот факт, что это полностью избегает SQL-инъекций, является дополнительным преимуществом. Но это все еще реальная выгода. Если вы будете регистрировать столько же, сколько и имя пользователя, вы уже должны учитывать SQL-инъекцию.