35. 服务器管理Part 3: 服务器打包¶
35.1. Flavor: 按不同作用来区分服务器¶
根据情况的不同,有时须要按照不同的作用来设置服务器。 对于iFun引擎,可以这种目的来指定服务器的Flaver。
35.1.1. 什么是Flavor?¶
Flavor表示虽然共享source code,但却负责不同作用的服务器类型。 例如,即使使用同一source code,类型也有可能不同,如lobby服务器和game服务器。iFun引擎中将它们分成lobby flavor和game flavor。
35.1.2. 设置Flavor¶
如果想要区分lobby类型的游戏服务器和game type的游戏服务器,在最上级的CMakeLists.txt中,按如下所示指定flavor。
1 2 3 4 | ...
set(APP_FLAVORS lobby game)
...
include(Funapi)
|
Note
flavor 지정 시, default
는 엔진 내부에서 예약어(reserved keyword)로 사용하기 때문에 default
이외의 다른 이름을 사용해야 합니다.
35.1.3. 各Flavor自动生成的文件¶
待这样设置并构建好之后,iFun引擎会自动生成如下所示文件。
35.1.3.1. MANIFEST.json¶
复制所包含的默认 src/MANIFEST.json
,在source directory上创建 src/MANIFEST.lobby.json
和 src/MANIFEST.game.json
。现在适当修改各flavor的MANIFEST.json。
35.1.3.2. Launcher script¶
在Build directory中创建各flavor的launcher script。上述示例中创建了以 .lobby-local
、 .lobby-launcher
、 .game-local
、 game-launcher
结尾的脚本。
35.1.3.3. Daemon script¶
在 CMakeLists.txt
中通过 set(WANT_SYSTEMD true)
或 set(WANT_UPSTART true)
设置时,也同时生成用于通过daemon运行游戏服务器的script文件。此时,各个flavor专用文件和在MANIFEST.json中一样,复制默认包含的文件,并进行创建。
set(WANT_SYSTEMD true)时:
在source directory的etc/systemd/目录下,以
.chat.service
、.lobby.service
等形式生成文件。
set(WANT_UPSTART true)时:
在source directory的etc/upstart/default/目录下,生成
.chat
,.lobby
等文件。在source directory的etc/upstart/init/目录下,生成
.chat.conf
,.lobby.conf
等文件。
Note
这样生成的文件在 make install
或 make package
时,会同时包含进去,从而进行安装或发布。
35.1.4. 在代码中查看当前flavor¶
为了对各flavor的服务器动作进行不同处理,须要在代码中查看当前服务器的flavor。
此时,使用名为 app_flavor
的Google flag。下面是使用示例。
1 2 3 4 5 6 7 8 9 10 11 12 | DECLARE_string(app_flavor)
class MyGameServer : public Component {
public:
static bool Install(const ArgumentMap &arguments) {
if (FLAGS_app_flavor == "lobby") {
// Configure as a lobby server.
} else if (FLAGS_app_flavor == "game") {
// Configure as a game server.
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class Server
{
public static void Install(ArgumentMap arguments)
{
if (Flags.GetString ("app_flavor") == "lobby")
{
// Configure as a lobby server.
}
else if (Flags.GetString ("app_flavor") == "game")
{
// Configure as a game server.
}
}
}
|
Tip
如果使用Flavor,那么相关服务器的RPC标签中会自动包含该flavor名称。据此可轻松调取同一flavor的服务器列表。具体内容请参考 用标签来区分分布式服务器 。
35.2. 用于发布到实际执行服务器中的游戏服务器packaging¶
iFun引擎提供了可轻松对已开发的游戏服务器进行打包的功能。使用该功能,可以避免为了将游戏服务器 复制到实际服务器而复制所有代码的不安全的行为。
35.2.1. 可创建的包类型¶
包文件可通过以下3种格式创建,分别在项目最上级的CMakeLists.txt文件中设置如下变量即可。
TGZ: 通过gzi打包的tar文件。设置为
set(WANT_TGZ_PACKAGE true)
,即可创建。在不将游戏服务器安装到/usr/bin等OS的常规路径下,而是安装到特定用户的home directory时所使用。DEB: Debian package文件。设置为
set(WANT_DEB_PACKAGE true)
,即可创建。仅在Ubuntu中有效。根据Ubuntu的convention来安装执行文件,并同时包含daemon script。RPM: Redhat package文件。设置为
set(WANT_RPM_PACKAGE true)
,即可创建。仅在CentOS中有效。按照CentOs的convention来安装执行文件,并同时还包含daemon script。
35.2.2. 为已创建的包赋予版本号¶
包的文件名以 “{{project}}_{{version}}_install.tgz” 的形式生成,version string则按如下所示说明,由在major version string和source储存库中提取的code revision ID组成。
35.2.2.1. Major版本号¶
为了提高服务器包的版本,可修改 Source 디렉터리 구조 中记述的 VERSION
文件内容并创建包,即可自动提高服务器包的版本。
35.2.2.2. Minor版本号(code revision ID)¶
如果除了须要手动更新的VERSION以外,还想要 自动 添加GIT的commit id或SVN的revision number到版本字符串中作为Build编号,只需在最上级的CMakeLists.txt文件中设置如下变量即可。
GIT: 设置成
set(PACKAGE_WITH_BUILD_NUMBER_FROM_GIT true)`
,即可将GIT commit ID设置为minor version string。Tip
若source tree为dirty状态,在commit id后面添加
~dirty
字符串。由此可知,是在有仍未commit的内容的source tree中所构建的。SVN: 设置成
set(PACKAGE_WITH_BUILD_NUMBER_FROM_SVN true)`
,即可将svn info
中提取的reversion ID设置为minor version string。Warning
svn如在commit后未执行update命令,
svn info
将返回commit之前的revision号。为了避免该问题,请在创建包之前执行svn update
。
35.2.3. 包的创建方法¶
35.2.3.1. 在命令行中操作时¶
在终端内输入 make package
,即可创建包文件。
35.2.3.2. 通过CLion操作时¶
选择右侧 target
的子菜单,即可选择名为 package
的target。双击,即可创建包文件。
35.2.4. 查看包的内容¶
35.2.4.1. TGZ¶
可通过 tar ztvf
查看包的内容,如下所示。
$ tar ztvf example_0.0.1_install.tar.gz
drwxrwxr-x dkmoon/dkmoon 0 2017-05-18 14:24 etc/
drwxrwxr-x dkmoon/dkmoon 0 2017-05-18 14:24 etc/default/
-rw-r--r-- dkmoon/dkmoon 72 2017-05-18 14:23 etc/default/example
drwxrwxr-x dkmoon/dkmoon 0 2017-05-18 14:24 etc/init/
-rw-r--r-- dkmoon/dkmoon 1304 2017-05-18 14:23 etc/init/example.conf
drwxrwxr-x dkmoon/dkmoon 0 2017-05-18 14:24 usr/
drwxrwxr-x dkmoon/dkmoon 0 2017-05-18 14:24 usr/lib/
drwxrwxr-x dkmoon/dkmoon 0 2017-05-18 14:24 usr/lib/example/
drwxrwxr-x dkmoon/dkmoon 0 2017-05-18 14:24 usr/lib/example/default/
-rw-r--r-- dkmoon/dkmoon 5723064 2017-05-18 14:23 usr/lib/example/default/libexample.so
...
-rwxr-xr-x dkmoon/dkmoon 3288 2017-05-18 14:23 usr/bin/example-launcher
35.2.4.2. DEB¶
可通过 dpkg-deb --contents
命令查看包的内容,如下所示。
$ dpkg-deb --contents example_0.0.1_install.deb
drwxrwxr-x root/root 0 2017-05-18 14:24 ./etc/
drwxrwxr-x root/root 0 2017-05-18 14:24 ./etc/default/
-rw-r--r-- root/root 72 2017-05-18 14:23 ./etc/default/example
drwxrwxr-x root/root 0 2017-05-18 14:24 ./etc/init/
-rw-r--r-- root/root 1304 2017-05-18 14:23 ./etc/init/example.conf
drwxrwxr-x root/root 0 2017-05-18 14:24 ./usr/
drwxrwxr-x root/root 0 2017-05-18 14:24 ./usr/bin/
-rwxr-xr-x root/root 3288 2017-05-18 14:23 ./usr/bin/example-launcher
drwxrwxr-x root/root 0 2017-05-18 14:24 ./usr/lib/
drwxrwxr-x root/root 0 2017-05-18 14:24 ./usr/lib/example/
drwxrwxr-x root/root 0 2017-05-18 14:24 ./usr/lib/example/default/
-rw-r--r-- root/root 5723064 2017-05-18 14:23 ./usr/lib/example/default/libexample.so
drwxrwxr-x root/root 0 2017-05-18 14:24 ./usr/share/
...
35.2.4.3. RPM¶
可通过 rpm --qpl
命令查看包的内容,如下所示。
$ rpm -qpl example_0.0.1_install.rpm
/lib/systemd/system/example.service
/usr/bin/example-launcher
/usr/lib/example/default/libexample.so
/usr/share/example/default/DEBIAN
/usr/share/example/default/LICENSE
/usr/share/example/default/README
/usr/share/example/default/VERSION
/usr/share/example/default/manifests/MANIFEST.json
/usr/share/example/default/resources/.stamp
/usr/share/example/default/resources/client_data/.stamp
/usr/share/example/default/resources/client_data/README
/usr/share/example/default/resources/game_data/.stamp
/usr/share/example/default/resources/game_data/README
/usr/share/example/default/resources/json_protocols/.stamp
/usr/share/example/default/resources/json_protocols/README
/usr/share/example/default/symbols/libexample.so/62BD5D7D261EC43AFCBABB208919AD480/libexample.so.sym
35.2.5. 将iFun引擎许可证文件包含在package中¶
当已按照 应用许可证文件 中介绍的方法安装好 account.ilf
进行使用时,最好在package中也包含该文件。
如果已通过source directory中的 etc/ifunfactory/account.ilf
保存了 account.ilf
,那么在通过DEB或RPM 创建包时, account.ilf
也会被同时安装。
35.2.6. 将游戏资源文件包含在package中¶
像 内容支持Part4: 策划数据 这种情况,有时可能存在为了实现服务器端逻辑而需要参考的资源文件。
这种资源文件,须要在开发时及在实际服务运行时,可在游戏服务器中均能够被访问到。 为此,大多情况下会将资源文件复制到固定位置进行使用,但这会引起须要和用户ID保持一致,或在更新游戏服务器时须要单独更新资源等诸多问题。
iFun引擎为了解决这些问题,使游戏开发人员可以将特定目录指定为资源目录。 这样已指定好的目录在对游戏服务器进行打包时,会同时包含到包中,并在游戏服务器上也能通过一贯的方法访问文件。
35.2.6.1. 指定资源目录¶
在最上级目录的 CMakeLists.txt
的 RESOURCE_DIRS
变量中列出资源目录。
1 2 3 4 5 | ...
set(RESOURCE_DIRS game_data)
...
include(Funapi)
|
35.2.6.2. 在代码中访问资源文件¶
资源文件在开发服务器时,会位于当前的源目录中,而在服务中时,则根据包的不同,将安装在特定位置。
因此,为了访问资源文件,源代码中须要将 GetResRoot()
函数的结果值作为prefix来使用。该函数确保了无论游戏服务器是处于开发中还是处于服务中,均能访问资源文件。
例如,上面的示例中,已将名为 game_data
目录指定为资源,而为了访问 game_data/my_file1
,按如下所示进行使用。
1 | string path = GetResRoot() + "/game_data/my_file1";
|
35.3. 作为实际执行服务发布¶
与包的发布和安装有关的内容请参考 服务器管理Part 4: 发布服务器 。