37. 服务器管理Part 5: 运行中更改设置

iFun引擎提供了可在服务器运行时调整部分设置的功能。

37.1. Run-time时可设置的旗标

可调整的功能有下面提到的iFun引擎旗标,以及服务器程序员直接定义的旗标。 (有关添加旗标的具体内容,请参考 编程Part 3: 程序运行参数 。)

Important

本功能不更改 MANIFEST.json 的值。 若更改flag值,仅在服务器运行的期间内保持更改后的值, 而服务器重启后,则会恢复到原值。

37.1.1. iFun引擎旗标

日志相关功能:

  • minloglevel: 可更改输出的最低日志级别。

  • v: 可输出verbose日志。

  • alsologtostderr: 除了log file以外,还可在console中输出日志。

  • session_message_logging_level: 修改客户端-服务器之间session消息的日志级别。0为不保存日志,1为仅保存消息类型和长度,2为保存所有消息。 具体内容请参考 网络功能设置参数

  • rpc_message_logging_level: 更改跨服RPC通信消息的日志级别。0为不保存日志,1为仅保存消息类型和长度,2为保存所有消息。具体内容请参考 分布式处理功能的设置参数

服务器性能相关功能:

客户端管理相关功能:

37.1.2. 服务器程序员添加的旗标

根据 编程Part 3: 程序运行参数 中介绍的内容为服务器添加完旗标后,须在MANIFEST.json指定相关旗标为可在run-time进行修改的旗标。

...
"RuntimeConfiguration": {
  "enable_runtime_configuration": true,
  "additional_configurations": ["flag1", "flag2", ... ]
}
...

例如,我们假设按如下所示,通过google flag指定登录后发放金币的事件是否正在进行。

DEFINE_bool(enable_gold_event,   // flag 의 이름을 입력합니다.
            false,               // flag 의 기본값을 입력합니다.
            "gold event flag");  // flag 의 설명을 입력합니다.

如此定义的flag如下所示,在MANIFEST.json中将其指定为可在run-time时修改的旗标。

...
"RuntimeConfiguration": {
  "enable_runtime_configuration": true,
  "additional_configurations": ["enable_gold_event"]
}
...

37.2. 激活Run-time设置变更功能

在MANIFEST.json的 RuntimeConfiguration 中将 enable_runtime_configuration 更改为true。

...
"RuntimeConfiguration": {
  "enable_runtime_configuration": true,
  "additional_configurations": []
}
...

Important

由于 RuntimeConfiguration 是以 ApiService 为基础运行的,所以须要按照 ApiService功能设置参数 中介绍的方法激活 ApiService

37.3. 用于更改Run-time设置的RESTful APIs

37.3.1. 查询所有可设置的flag

GET /v1/configurations/

请求示例:

GET /v1/configurations/ HTTP/1.1

响应示例:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "minloglevel": {
    "type": "int32",
    "desc": "Messages logged at a lower level than this don't actually get logged anywhere",
    "value": "0"
  },
  ...
}

37.3.2. 查询特定flag值

GET /v1/configurations/<flag_name>
Parameters
  • flag_name – 要查询的flag名字。

示例1: 存在flag时:

请求:

GET /v1/configurations/minloglevel HTTP/1.1

响应:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "minloglevel": {
    "type": "int32",
    "desc": "Messages logged at a lower level than this don't actually get logged anywhere",
    "value": "0"
  }
}

示例2: 不存在flag时:

请求:

GET /v1/configurations/no_flag HTTP/1.1

响应:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "no_flag": {
        "message": "This is not available",
        "available_configurations": {
            "minloglevel": {
                "type": "int32",
                "desc": "Messages logged at a lower level than this don't actually get logged anywhere"
            },
            ...
        }
    }
}

37.3.3. 变更特定flag值

PUT /v1/configurations/<flag_name>/<value>
Parameters
  • flag_name – 要变更的flag名字。

  • value – 要变更的值。

示例1: value为valid时:

请求:

PUT /v1/configurations/minloglevel/1 HTTP/1.1

响应:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "minloglevel": {
    "result": "minloglevel set to 1\n"
  }
}

示例2: value不valid时:

请求:

PUT /v1/configurations/minloglevel/one HTTP/1.1

响应:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "minloglevel": {
    "result": "The 'one' is not a valid value"
  }
}

37.3.4. 管理客户端版本

37.3.4.1. 查询可兼容的客户端版本信息

调用如下API后,可调取已在 MANIFEST.jsonAppInfo 组件中设置的 client_compatible_versions

GET /v1/configurations/compatible_client_versions

示例:

请求:

GET /v1/configurations/compatible_client_versions HTTP/1.1

响应:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "current_compatible_versions": ["0.0.1","0.0.2"]
}

37.3.4.2. 变更可兼容的客户端版本信息

如下所示,调用API,即可变更compatible client version。

POST /v1/configurations/compatible_client_versions

示例:

请求:

POST /v1/configurations/compatible_client_versions HTTP/1.1

["0.0.3", "0.0.4"]

响应:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "current_compatible_versions": ["0.0.3", "0.0.4"]
}

Important

不更改MANIFEST.json文件的AppInfo内容。 服务器重启后,已更改的内容均恢复到原值。

37.4. 使用可设置Run-time旗标时的注意事项

iFun引擎的run-time设置变更功能通过更改Gflag值的方式运行。 因此,对于可更改设置的旗标,须要在使用相应旗标的代码中直接调用gflag。

下面的示例按照 服务器程序员添加的旗标 中所介绍的内容,将 enable_glod_event 指定为可设置run-time的旗标,但并不是直接读取相应值,而是通过在全局变量中保存值来使用,因此产生了漏洞。

错误的使用示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
DEFINE_bool(enable_gold_event, false, "gold event flag");

bool the_is_gold_event_enabled = false;

void EventManager::Initialize() {
  the_is_gold_event_enabled = FLAGS_enable_gold_event;
}

bool EventManager::IsGoldEventEnabled() {
  return the_is_gold_event_enabled;
}


void OnLogin() {
  Ptr<User> user = User::Fetch(...);

  if (EventManager::IsGoldEventEnabled()) {
    user->SetGold(user->GetGold() + 100);
  }
}

上述示例须要按如下方法修改。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
DEFINE_bool(enable_gold_event, false, "gold event flag");

bool EventManager::IsGoldEventEnabled() {
  return FLAGS_enable_gold_event;
}

void OnLogin() {
  Ptr<User> user = User::Fetch(...);

  if (EventManager::IsGoldEventEnabled()) {
    user->SetGold(user->GetGold() + 100);
  }
}