为什么写这篇文章
- 上篇文章是用 makefile 进行编译的。感觉 makefile 也算是个老东西了,这次准备用 CMake 工具。
- 上次的代码过于简单,也没有包含实际的头文件,库文件。
- 不久前在 Windows 下写了一个并发服务器,作为一个并发服务器怎么没有 Linux 版本呢
- 上篇文章对 gdb 的使用还不够
这个服务器的构成
- 这个服务器的网络模型是 IOCP/epoll,
- 有一个定时器
- 用到协程 boost::coroutine2
- 数据库使用 MySQL
MySQL安装
为了和 Windows 版本统一,我这里安装的是 8.1 版本
下载的文件
mysql-server:
mysql-community-server-8.1.0-1.el8.x86_64.rpm
mysql-community-client-8.1.0-1.el8.x86_64.rpm
mysql-community-icu-data-files-8.1.0-1.el8.x86_64.rpm
mysql-community-common-8.1.0-1.el8.x86_64.rpm
mysql-community-client-plugins-8.1.0-1.el8.x86_64.rpm
mysql-community-libs-8.1.0-1.el8.x86_64.rpm
注:server 下面的都是它依赖,得先安装它们,注意顺序
mysql-connect-C++:
mysql-connector-c++-8.1.0-1.el8.x86_64.rpm
配置
注:字符串用单引号 ' 包围起来
解决 mysql 密码认证失败:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '12345678';
MySQL设计
由于是多个 Game 同时连 DB,所以对 MySQL 部分表的操作需要同步。但同步工作MySQL替我完成了。因为 MySQL 对于插入带有自增字段的一行时,MySQL保证每次 insert 操作同步进行。包括这个服务器中创建用户,创建角色操作。
表
t_user: 用户
t_role: 游戏角色
t_rank: 游戏角色排行
t_system_mail: 系统邮件
t_role_system_mail
t_role_mail:
安装 boost 库
为了统一,我再次使用和 Windows 一样的 1.77 版本。另外boost是个很大的库,我这次只用到其中一小部分,所以我也只编译这一步库。它们是:context、coroutine、thread
./bootstrap.sh --show-libraries //查看 boost 包含的库内容
./bootstrap.sh --with-libraries=context,coroutine,thread //限定编译库
服务器架构
项目目录
目录说明
msg: 消息定义,为适应 C#客户端,以及中文,使用 Unicode
mysql: 一些封装,对 MySQL api 的封装 可以参考我之前的文章
server: 基础的服务器类
util: 工具函数,包含定时器,调度器,字符串处理
gameserver:
gateserver:
dbserver:
其他文件
main 就是启动服务器的,没什么可说的
stdafx 预编译文文件
cross_platform 包含了一些特定系统的头文件,为了便于使用 Socket ,
抽象定 Socket 以及相关操作函数
Gate
连接所有 Game
用于平衡各个 Game 玩家人数的
一个 Gate Server 负责平均将客户端连接分配到不同 Game Server
n 个 Game Server,在硬件性能足够的情况下,每增加一个Game Server,同样的客户端连接数量下,相比单个Game Server,相应延迟可以预期降低为 1/n
找出最小负载 Game
方式1:
创建 N 个协程(N为 Game 个数),每个协程暂停1次,继续 1次
for (auto& [_, sock] : sd_Games)
{
shared_ptr<sReqMsg_Gate_To_Game_Get_Online_Count> msg =
make_shared<sReqMsg_Gate_To_Game_Get_Online_Count>();
shared_ptr<Co_Req> req = make_shared<Co_Req>(msg);
auto tmp_socket = sock;