游戏服务器端开发要点
一 专业基础
1.1 网络
1.1.1 理解TCP/IP协议
网络传输模型
滑动窗口技术
建立连接的三次握手与断开连接的四次握手
连接建立与断开过程中的各种状态
TCP/IP协议的传输效率
思考
1)请解释DOS攻击与DRDOS攻击的基本原理
2)一个100Byte数据包,精简到50Byte, 其传输效率提高了50%
3)TIMEWAIT状态怎么解释?
1.1.2 掌握常用的网络通信模型
Select
Epoll,边缘触发与平台出发点区别与应用
Select与Epoll的区别及应用
1.2 存储
计算机系统存储体系
程序运行时的内存结构
计算机文件系统,页表结构
内存池与对象池的实现原理,应用场景与区别
关系数据库MySQL的使用
共享内存
1.3 程序
对C/C++语言有较深的理解
深刻理解接口,封装与多态,并且有实践经验
深刻理解常用的数据结构:数组,链表,二叉树,哈希表
熟悉常用的算法及相关复杂度:冒泡排序,快速排序
二 游戏开发入门
2.1防御式编程
不要相信客户端数据,一定要检验。作为服务器端你无法确定你的客户端是谁,你也不能假定它是善意的,请做好自我保护。(这是判断一个服务器端程序员是否入门的基本标准)
务必对于函数的传人参数和返回值进行合法性判断,内部子系统,功能模块之间不要太过信任,要求低耦合,高内聚
插件式的模块设计,模块功能的健壮性应该是内建的,尽量减少模块间耦合
2.2 设计模式
道法自然。不要迷信,迷恋设计模式,更不要生搬硬套
简化,简化,再简化,用最简单的办法解决问题
借大宝一句话:设计本天成,妙手偶得之
2.3 网络模型
自造轮子: Select, Epoll, Epoll一定比Select高效吗?
开源框架: Libevent, libev, ACE
2.4 数据持久化
自定义文件存储,如《梦幻西游》
关系数据库: MySQL
NO-SQL数据库: MongoDB
选择存储系统要考虑到因素:稳定性,性能,可扩展性
2.5 内存管理
使用内存池和对象池,禁止运行期间动态分配内存
对于输入输出的指针参数,严格检查,宁滥勿缺
写内存保护。使用带内存保护的函数(strncpy, memcpy, snprintf, vsnprintf等),严防数组下标越界
防止读内存溢出,确保字符串以’ ’结束
2.6 日志系统
简单高效,大量日志操作不应该影响程序性能
稳定,做到服务器崩溃是日志不丢失
完备,玩家关键操作一定要记日志,理想的情况是通过日志能重建任何时刻的玩家数据
开关,开发日志的要加级别开关控制
2.7 通信协议
采用PDL(Protocol Design Language), 如Protobuf,可以同时生成前后端代码,减少前后端协议联调成本, 扩展性好
JSON,文本协议,简单,自解释,无联调成本,扩展性好,也很方便进行包过滤以及写日志
自定义二进制协议,精简,有高效的传输性能,完全可控,几乎无扩展性
2.8 全局唯一Key(GUID)
为合服做准备
方便追踪道具,装备流向
每个角色,装备,道具都应对应有全局唯一Key
2.9 多线程与同步
消息队列进行同步化处理
2.10 状态机
强化角色的状态
前置状态的检查校验
2.11 数据包操作
合并, 同一帧内的数据包进行合并,减少IO操作次数
单副本, 用一个包尽量只保存一份,减少内存复制次数
AOI同步中减少中间过程无用数据包
2.12 状态监控
随时监控服务器内部状态
内存池,对象池使用情况
帧处理时间
网络IO
包处理性能
各种业务逻辑的处理次数
2.13 包频率控制
基于每个玩家每条协议的包频率控制,瘫痪变速齿轮
2.14 开关控制
每个模块都有开关,可以紧急关闭任何出问题的功能模块
- 2.15 反外挂反作弊
包频率控制可以消灭变速齿轮
包id自增校验,可以消灭WPE
包校验码可以消灭包拦截篡改
图形识别吗,可以踢掉99%非人的操作
魔高一尺,道高一丈
2.16 热更新
核心配置逻辑的热更新,如防沉迷系统,包频率控制,开关控制等
代码基本热更新,如Erlang,Lua等
2.17 防刷
关键系统资源(如元宝,精力值,道具,装备等)的产出记日志
资源的产出和消耗尽量依赖两个或以上的独立条件的检测
严格检查各项操作的前置条件
校验参数合法性
2.18 防崩溃
系统底层与具体业务逻辑无关,可以用大量的机器人压力测试暴露各种bug,确保稳定
业务逻辑建议使用脚本
系统性的保证游戏不会崩溃
2.19 性能优化
IO操作异步化
IO操作合并缓写 (事务性的提交db操作,包合并,文件日志缓写)
Cache机制
减少竞态条件 (避免频繁进出切换,尽量减少锁定使用,多线程不一定由于单线程) 多线程不一定比单线程快
减少内存复制
自己测试,用数据说话,别猜
2.20 运营支持
接口支持:实时查询,控制指令,数据监控,客服处理等
实现考虑提供Http接口
2.21 容灾与故障预案
略
三 服务器端架构
3.1 什么是好的架构?
满足业务要求
能迅速的实现策划需求,响应需求变更
系统级的稳定性保障
简化开发。将复杂性控制在架构底层,降低对开发人员的技术要求,逻辑开发不依赖于开发人员本身强大的技术实力,提高开发效率
完善的运营支撑体系
3.2 架构实践的思考
简单,满足需求的架构就是好架构
设计性能,抓住重要的20%, 没必要从程序代码里面去抠性能
热更新是必须的
人难免会犯错,尽可能的用一套机制去保障逻辑的健壮性