百万在线_大型游戏服务端开发

进入手游时代,服务端技术也在向前演进。现代游戏服务端既要承载数以万计的在线玩家,又要适应快速变化的市场需求,因此,如何设计合适的架构就成了重中之重。服务端技术并不简单,作为服务端新人,全面掌握服务端技术可能需要数年时间;作为游戏公司,培养员工的成本也不低。新人或许有这样的经历,在请教资深技术人应该看什么资料学习C++服务端知识时,可能得到的答案是先把《TCP/IP详解》《UNIX环境高级编程》《数据库系统》这些大部头啃一遍,或者是把Redis、Skynet的源码过一遍,再看点Linux源码就都会了。虽说啃大部头、看源码是服务端从业者的必经之路,但人的时间是有限的,因此,在入门阶段,在有限的时间里学到最实用的知识很关键。游戏服务端的知识体系既包含系统底层知识,也包含具体游戏业务的设计,内容很多,学习不易。这里介绍一本新书《百万在线:大型游戏服务端开发》,一本既实用又深入浅出的游戏服务端教程。扫码了解 ↑

读者对象

职场新人:本书很适合刚入行的服务端工程师,书中所介绍的知识和问题,是每个游戏从业人员都会遇到或必须解决的。本书可作为提升技术水平的学习资料,也适合用作游戏公司服务端新人的培训材料,书中既涵盖了该岗位的必备知识,也包含了《球球大作战》、Sunnet(C++仿写Skynet底层)等实践项目。我们希望职场新人读完本书之后,不仅能够更快更好地完成手头工作,还能够为下一阶段的职业发展做好积累。

开发类岗位的求职者:本书也适合游戏公司开发岗位的求职者。书中对服务端岗位所需知识、商业游戏常遇到的问题等进行了讲解,覆盖了常见的面试内容。我们希望本书能够帮助读者获得C++服务端开发工程师的岗位。

高校学生:本书可作为高校教科书。书中内容是按照游戏公司的需求设计的,内容循序渐进,且包含诸多示例。我们希望本书可以帮助学生掌握实用的知识,帮助他们构建完整的知识体系,也为未来的进一步进修或职业发展提供助力。

游戏开发爱好者:在本书中,“学以致用”的理念贯穿全书,对于想要自己制作一款网络游戏的业余开发者来说,本书很适合作为自学的参考书。我们希望本书可以帮助读者“先把游戏做出来”,让读者能够先快速使用现成的Skynet框架,再逐步深入底层,为梦想助力。

目录

上拉下滑查看目录 ↓

前 言

第一部分 学以致用

第1章 从角色走路说起   2

1.1 每走一步都有事情发生  2

1.1.1 走路的五个步骤  3

1.1.2 服务端视角的游戏流程  3

1.2 从网络编程着手   4

1.2.1 用打电话做比喻  4

1.2.2 最少要掌握的三个概念  5

1.2.3 搭一个简单的服务器  6

1.2.4 让角色走起来  8

1.3 能够承载多少玩家  9

1.3.1 单线事件模型  9

1.3.2 承载量估算  9

1.4 用分布式扩能  10

1.4.1 多个程序协同工作  11

1.4.2 三个层次的交互  11

1.4.3 搭个简单的分布式服务端  12

1.4.4 一致性问题  14

1.5 回头看操作系统  15

1.5.1 多进程为什么能提升性能  15

1.5.2 阻塞为什么不占CPU  16

1.5.3 线程会占用多少资源  17

1.6 一张地图的极限  18

1.6.1 难以分割的业务  19

1.6.2 在延迟和容量间权衡  19

1.7 万物皆Actor  19

1.7.1 灵感来自Erlang  20

1.7.2 对世界的抽象  20

1.7.3 为何适用  22

第2章 Skynet入门精要  25

2.1 下载、编译、运行  26

2.1.1 下载和编译  26

2.1.2 运行范例  27

2.2 理解Skynet  28

2.2.1 节点和服务  28

2.2.2 配置文件  29

2.2.3 目录结构  30

2.2.4 启动流程  31

2.3 第一个程序PingPong  32

2.3.1 功能需求  32

2.3.2 学习服务模块  32

2.3.3 代码实现  33

2.3.4 运行结果  35

2.4 写Echo,练习网络编程  35

2.4.1 功能需求  36

2.4.2 学习网络模块  36

2.4.3 代码实现  37

2.4.4 运行结果  37

2.5 做聊天室,学习多人交互  38

2.5.1 功能需求  38

2.5.2 代码实现  38

2.6 做留言板,使用数据库  39

2.6.1 功能需求  39

2.6.2 学习数据库模块  40

2.6.3 准备数据库  40

2.6.4 代码实现  43

2.6.5 运行结果  45

2.7 监控服务状态  45

2.7.1 启用调试控制台  45

2.7.2 监控指令  46

2.8 使用节点集群建立分布式系统  48

2.8.1 功能需求  48

2.8.2 学习集群模块  48

2.8.3 节点配置  49

2.8.4 代码实现  49

2.8.5 运行结果  51

2.8.6 使用代理  52

2.9 使用Skynet的注意事项  52

2.9.1 协程的作用  52

2.9.2 扣除金币的Bug  52

第3章 案例:《球球大作战》  54

3.1 功能需求  54

3.2 方案设计  55

3.2.1 拓扑结构  55

3.2.2 各服务功能  56

3.2.3 消息流程  57

3.2.4 设计要点  57

3.3 搭架子:目录结构和配置  58

3.3.1 目录结构  58

3.3.2 配置文件  58

3.3.3 第1版主服务  59

3.3.4 启动脚本  60

3.3.5 服务配置  60

3.4 磨刀工:封装易用的API  62

3.4.1 定义属性  63

3.4.2 启动逻辑  63

3.4.3 消息分发  64

3.4.4 辅助方法  65

3.4.5 编写空服务  66

3.5 分布式登录流程  67

3.5.1 完整的登录流程  67

3.5.2 掉线登出流程  69

3.5.3 协议格式  69

3.6 代码实现:gateway  70

3.6.1 连接类和玩家类  70

3.6.2 接收客户端连接  71

3.6.3 处理客户端协议  74

3.6.4 编码和解码  75

3.6.5 消息分发  76

3.6.6 发送消息接口  78

3.6.7 确认登录接口  79

3.6.8 登出流程  80

3.7 代码实现:login  81

3.7.1 登录协议  81

3.7.2 客户端消息分发  81

3.7.3 登录流程处理  82

3.8 代码实现:agentmgr  83

3.8.1 玩家类  83

3.8.2 请求登录接口  84

3.8.3 请求登出接口  86

3.9 代码实现:nodemgr  86

3.10 代码实现:agent(单机版)  87

3.10.1 消息分发  87

3.10.2 数据加载  87

3.10.3 保存和退出  88

3.10.4 单机测试  88

3.11 测试登录流程  89

3.11.1 第2版主服务  89

3.11.2 单节点测试  90

3.11.3 跨节点测试  90

3.12 战斗流程梳理  91

3.12.1 战斗流程  91

3.12.2 协议  91

3.13 代码实现:场景服务  93

3.13.1 Ball类  93

3.13.2 Food类  94

3.13.3 进入战斗  95

3.13.4 退出战斗  97

3.13.5 操作移动  97

3.13.6 主循环  97

3.13.7 移动逻辑  99

3.13.8 生成食物  99

3.13.9 吞下食物  100

3.13.10 第3版主服务  101

3.14 代码实现:agent(跨服务器版)  101

3.14.1 多个模块  101

3.14.2 进入战斗  101

3.14.3 退出战斗  103

3.14.4 最后的辅助方法  103

3.14.5 运行结果  104

3.15 改进  104

第4章 Skynet进阶技法  106

4.1 用“长度信息”解TCP包  107

4.1.1 长度信息法  107

4.1.2 使用netpack模块解析网络包  107

4.1.3 测试小案例  110

4.1.4 阻塞方法的时序  113

4.2 用Json序列化协议  114

4.2.1 安装lua-cjson模块  115

4.2.2 使用lua-cjson模块  115

4.2.3 设计完整协议格式  117

4.2.4 编码Json协议  117

4.2.5 解码Json协议  118

4.2.6 测试  118

4.3 用Protobuf高效传输  119

4.3.1 什么是Protobuf  120

4.3.2 安装Protobuf和pbc  120

4.3.3 编译proto文件  121

4.3.4 编码和解码  121

4.4 如何设计游戏数据库  122

4.4.1 传统设计方法  123

4.4.2 传统的数据库难以应对版本更新  124

4.4.3 Key-Value表结构  125

4.4.4 用Protobuf描述玩家数据  126

4.4.5 创建角色  126

4.4.6 读取角色数据  127

4.4.7 应对游戏版本更新  128

4.4.8 拆分数据表  129

4.5 如何关闭服务器  130

4.5.1 管理控制台  130

4.5.2 关闭服务器的流程  131

4.5.3 阻止新玩家连入  132

4.5.4 缓缓踢下线  133

4.5.5 测试关闭服务器的功能  135

4.6 怎样做定时系统  136

4.6.1 每天第一次登录  136

4.6.2 定时唤醒  137

4.7 断线重连  138

4.7.1 原理解析  139

4.7.2 身份标识  139

4.7.3 消息缓存  140

4.7.4 处理重连请求  141

4.7.5 断线处理  142

4.7.6 测试  143

第二部分 入木三分

第5章 你好,C++并发世界  146

5.1 从HelloWorld开始  147

5.1.1 HelloWorld  147

5.1.2 用CMake构建工程  147

5.1.3 “学猫叫”小例子  149

5.1.4 各文件的依赖关系  151

5.1.5 模仿Skynet写底层  151

5.2 多核多线程  153

5.2.1 操作系统调度原理  153

5.2.2 创建线程对象  154

5.2.3 模仿Skynet开启线程  155

5.2.4 等待线程退出  158

5.2.5 Worker设计模式  159

5.3 探索C++对象模型  160

5.3.1 Actor模型的消息类  160

5.3.2 栈、堆、智能指针  161

5.3.3 对象的内存分布  162

5.4 队列与锁  162

5.4.1 模仿Skynet写服务类  163

5.4.2 锁的初始化  164

5.4.3 多线程队列插入  166

5.4.4 在多线程队列取出元素  166

5.4.5 三个回调方法  168

5.4.6 分析临界区  168

5.5 多线程下的对象管理  170

5.5.1 使用哈希表  170

5.5.2 浅析读写锁  171

5.5.3 新建服务  172

5.5.4 查找服务  172

5.5.5 删除服务  173

5.5.6 程序终于能运行了  174

5.6 充分利用CPU  175

5.6.1 全局消息队列  175

5.6.2 插入和弹出  177

5.6.3 标志位  178

5.6.4 模仿Skynet发送消息  179

5.6.5 工作线程调度  180

5.7 演示程序PingPong  183

5.7.1 辅助函数  183

5.7.2 编写ping服务  183

5.7.3 测试  184

5.8 条件变量与唤醒机制  185

5.8.1 改进版线程调度  185

5.8.2 如何使用条件变量  186

5.8.3 工作线程的等待与唤醒  188

5.8.4 测试  189

5.9 后台运行  189

第6章 图解TCP网络模块  191

6.1 启动网络线程  192

6.1.1 方案设计  192

6.1.2 新增两种消息  192

6.1.3 套接字到底是什么  193

6.1.4 模仿Skynet的网络线程  195

6.1.5 自定义连接类  197

6.2 半小时搞懂Epoll的用法  201

6.2.1 从轮询说起  202

6.2.2 创建epoll对象  203

6.2.3 直观理解监听列表  204

6.2.4 最重要的步骤:等待  207

6.2.5 监听对象的生命周期  210

6.2.6 水平触发和边缘触发  211

6.3 打开监听端口  212

6.3.1 三个API:socket、bind和listen  212

6.3.2 如何保障线程安全  215

6.3.3 关闭连接  215

6.3.4 测试:感知新连接  216

6.4 网络事件分发  216

6.4.1 拆分事件  217

6.4.2 接收新客户端  218

6.4.3 传递可读写事件  220

6.4.4 测试:Echo程序  220

6.5 如何安全读写数据  222

6.5.1 消息分支  222

6.5.2 可读、可写、关闭  224

6.5.3 处理莫名其妙退出的问题  226

6.5.4 PIPE信号处理  228

6.6 写缓冲区满  229

6.6.1 实验:发送大数据  229

6.6.2 解决方法1:设置SNDBUFFORCE  230

6.6.3 解决方法2:自写缓冲区  230

第7章 嵌入Lua脚本语言  234

7.1 方案设计  234

7.1.1 隔离数千个服务  235

7.1.2 目录结构  235

7.1.3 启动流程  235

7.2 嵌入Lua虚拟机  236

7.2.1 下载、编译源码  236

7.2.2 理解静态库  237

7.2.3 最重要的结构:lua_State  238

7.2.4 从创建到销毁  239

7.2.5 编译指令  240

7.3 C++调用Lua方法  241

7.3.1 代码示例  241

7.3.2 涉及4个API  242

7.3.3 直观理解Lua栈  243

7.3.4 再回顾调用方法  244

7.4 Lua调用C++函数  245

7.4.1 Sunnet的脚本模块  245

7.4.2 写接口  246

7.4.3 分析4个API  246

7.4.4 还需注册函数  248

7.4.5 思考题  250

7.5 Lua版的PingPong  251

7.5.1 封装两个新接口  251

7.5.2 Lua版的ping服务  253

7.5.3 运行结果  254

7.5.4 参数序列化  255

7.6 Lua版聊天室  256

7.6.1 继续封装  256

7.6.2 Lua版的聊天服务  258

7.6.3 运行结果  258

7.6.4 拓展说明  259

第三部分 各个击破

第8章 同步算法  262

8.1 同步难题  263

8.1.1 一种移动方法  263

8.1.2 瞬移、顿挫、打不中  264

8.1.3 抖动和延迟  265

8.2 客户端障眼法  267

8.2.1 插值算法  267

8.2.2 缓存队列  268

8.2.3 主动方优先  269

8.3 各类同步方案及适用场景  269

8.3.1 三种同步方案  270

8.3.2 适用场景  271

8.3.3 案例:《天涯明月刀》  271

8.3.4 案例:《王者荣耀》  272

8.3.5 案例:《绝地求生大逃杀》  273

8.4 帧同步  273

8.4.1 帧同步究竟是什么  274

8.4.2 代码范例  275

8.4.3 确定性计算  279

8.4.4 乐观帧同步  280

8.5 AOI算法  282

8.5.1 感兴趣区域  282

8.5.2 实体模型  283

8.5.3 九宫格法  284

8.6 可靠UDP  287

8.6.1 三角制约  287

8.6.2 几种现成方案  288

第9章 热更新  289

9.1 Skynet热更新  290

9.1.1 业务范例  290

9.1.2 利用独立虚拟机热更新  292

9.1.3 注入补丁  294

9.2 切换进程  296

9.2.1 从冷更新说起  296

9.2.2 《跳一跳》游戏案例  297

9.2.3 优雅的进程切换  298

9.2.4 fork和exec  298

9.2.5 Nginx的热更新方法  299

9.2.6 利用网关实现热更新  300

9.2.7 数据与逻辑分离  300

9.2.8 微服务  301

9.3 动态库  302

9.3.1 模拟案例  302

9.3.2 实现动态库热更新  303

9.3.3 动态库的限制  305

9.3.4 动态库在游戏中的应用  306

9.3.5 多线程与版本管理  306

9.4 脚本语言  308

9.4.1 业务需求  308

9.4.2 实现Lua热更新  310

9.4.3 尽量做正确的热更新  310

9.4.4 没有“万能药”的根源  311

9.4.5 工程实践  313

9.4.6 选择合适的热更新范围  316

第10章 防外挂  318

10.1 不信任客户端  319

10.1.1 刷金币案例  319

10.1.2 连发技能案例  320

10.1.3 透视外挂案例  322

10.2 尽可能多的校验  324

10.2.1 小游戏防刷榜  324

10.2.2 篮球游戏案例  327

10.2.3 部署校验服务  328

10.3 反外挂常用措施  329

10.3.1 防变速器  329

10.3.2 防封包工具  331

10.3.3 帧同步投票  332

第11章 未尽之路  333

11.1 高并发  333

11.1.1 Actor模型  333

11.1.2 One Loop Per Thread  334

11.2 服务端架构  334

11.2.1 大世界架构  334

11.2.2 BigWorld  334

11.2.3 无缝大地图  335

11.2.4 滚服架构  336

11.3 工程管理  337

11.3.1 分层架构  337

11.3.2 人员分工  337

11.3.3 版本管理  338

11.4 结语  339

扫码关注【华章计算机】视频号

每天来听华章哥讲书

更多精彩回顾

干货 |C++都有哪些就业方向?是否应该学习C++?

书单 | 成为优秀Java开发者,我看了这几本书

上新 |《Core Java》作者亲授视频免费看,学习Java更轻松

资讯 |提升研发效能:抵制无效加班文化

资讯 | 又又叒更新,Win 12要来了?

干货 |一文带你掌握计算机体系结构核心内容

干货 | 一文带你理解算法策略

书讯 | 2月书讯(下)| 新年到,新书到!

书讯 | 2月书讯 (上)| 新年到,新书到!【赠书】【第96期】夯实基础,突破内卷,不被优化点击阅读全文购买