概述 :本文尝试从开发者角度梳理开发实时联网游戏后盾服务过程中可能面临的挑战,并针对性地提供相应解决思路,冀望帮忙开发者根据本身游戏特点做出正当的技术选型。维基百科对于网络游戏的定义:通过计算机网络,将专用服务器和用户的客户端设施(手机、PC、游戏主机等) 相连,让多名玩家同时联机进行游戏的娱乐模式,由此可知网络游戏波及三个角色:客户端、网络、服务器,从网络架构上来讲网络游戏可分为 C /S 架构和 P2P 架构(特指客户端间直连通信),在理论开发中还有一种 C / S 和 P2P 架构混合:C/ M 架构。
P2P 架构不在本文探讨范畴,C/ M 架构和 C / S 架构相似,和经典的 LAMP 网站架构相似个别 C / S 架构的游戏后盾也可划分为如下三层:(1)网络接入层;(2)游戏逻辑层;(3)数据存储层。
网络接入、游戏逻辑、数据存储层各自所面临的问题域及对应技术栈都大为不同,做此划分不仅有助于模块解耦、技术分工、组件复用,也可不便服务的运维部署。本文也着重从这三个方面来论述游戏服务器的开发。
1、网络接入层
网络接入层的次要工作是建设客户端和后盾服务以及客户端之间的信道,接管来自客户端大量并发申请,考核该层的次要性能指标是:高吞吐、低提早。因此网络接入层开发考验的是开发者高性能网络编程的功底,即解决 C10K 甚至 C10M 的能力。
1.1 协定抉择
依据 OSI 的七层网络参考模型,咱们可将网游网络也做如下 7 层划分:
其中 4 层以下都由操作系统来负责,开发者无需为此操心,在理论的开发过程中开发者首要面临的问题便是传输层是采纳 TCP 还是 UDP,下表简要比照了两者的优劣。综合两者优劣,简略来说除非对提早有极致要求 (例如 FPS、MOBA 类游戏) 需采纳 UDP 外,TCP 可应答大部分游戏。在理论游戏开发中不论是采纳 TCP 还是 UDP 形式,都很少间接通过 Socket 编程形式来进行,一来因为开发工作量大,品质性能难以保障;二来平台兼容性不好(比方 H5 并没有提供 socket 编程能力),而是基于更下层的通信协定比方基于 TCP 的 HTTP、Websocket 协定,GRPC,以及基于 UDP 实现的 QUIC,WebRTC 协定等。
值得注意的是基于安全性思考,浏览器规范未提供 UDP 收发能力,QUIC 协定也只在 chrome 失去了反对,WebRTC 也还不是浏览器事实标准且协定初始目标是用于实现点对点的音视频通信,协定内容过于庞杂不容易提炼利用于游戏开发中,因此现阶段 H5 游戏还只能采纳 HTTP 或 Websocket 形式通信。
通信协定确定后,随后要思考的便是游戏对象的序列化,序列化次要有基于文本、基于二进制两种,其优劣如下表所示。在开发过程中个别会先采纳文本序列化形式,便于前后端开发联调,在游戏正式上线前切换至二进制序列化形式以缩小传输流量、晋升编解码效率。
至于数据安全性问题,为了爱护敏感数据平安开发者能够抉择平安的 https 或 WSS 通信协定,而对于间接基于 TCP 协定通信,可采纳先用 RSA 协商加密秘钥,而后应用对称加密形式将数据加密后发送。
通过以上剖析,对于游戏协定类型的抉择咱们给出有以下准则:
1、弱联网类游戏:诸如休闲、卡牌类游戏可间接 HTTP 协定,对安全性有要求的话就应用 HTTPS;
2、实时性,交互性要求较高:这类游戏个别须要放弃长连贯,优先选择规范的 ws 协定(同时应用二进制序列化形式),如思考安全性可应用 wss 协定。而对于提供 socket 接口的 native 平台也可应用 TCP 协定,同时对数据做对称加密加强安全性;
3、实时性要求极高:不仅须要和服务器放弃长连贯,且提早和网络抖动都要求极高(如 FPS,赛车类游戏),可应用基于 UDP 的实现流传输协定如 QUIC,KCP 等。
1.2 并发模型
为了解决来自客户端的并发申请,服务端有 4 种常见的并发模型。
1.2.1 过程
过程是最早采纳的并发模型,过程作为操作资源分配、调度的单位,领有独立的运行空间。过程并发模型中每个申请由独立的过程来解决,过程一次只能解决一个申请,该模型最大的长处就是简略。如果解决申请的过程因为零碎调用而阻塞或过程的工夫片用完,抢占式的过程调度器就会暂停旧过程执行,调度执行新的过程,这个过程波及大开销的上下文切换,过程并发模型的毛病是比拟低效。最典型的采纳过程模型的服务有 Apache。
1.2.2 线程
线程并发模型是过程模型的改良,线程从属于过程,是零碎更小粒度的执行调度单元。不同申请可由过程内多个并发执行的线程来解决,这些线程由操作系统内核主动调度。线程绝对过程的次要劣势在于,调度上下文切换开销更小,但因为多个线程共享地址空间,须要额定的线程间互斥、同步机制来保障程序性正确性。典型的采纳线程模型的服务有 Tomcat。
1.2.3 IO 多路复用
利用操作系统提供的 epoll 等 IO 多路复用机制,能同时监控多个连贯上读、写事件,IO 多路复用也称事件驱动模型,网络程序执行逻辑可形象为事件驱动的状态机。IO 多路复用防止了读写阻塞,缩小了上下文切换,晋升了 CPU 利用率和零碎吞吐率。但 IO 多路复用它将本来“同步”、线性的解决逻辑变成事件驱动的状态机,解决逻辑扩散于大量的事件回调函数。这种异步、非线性的模型,极大地减少了编程难度,如 nodeJs 的常见的回调天堂问题。典型的采纳 IO 复用模型的服务有 Nginx,netty。
1.2.4 协程
协程也称为轻量级线程,是一种协同的、非抢占式的多任务并发模型。协程运行在用户空间,当遇到阻塞或特定入口时,通过显式调用切换办法被动让出 CPU,由任务调度器选取另一个协程执行。
协程切换只是简略地扭转执行函数栈,不波及内核态与用户态转化,也波及上下文切换,开销远小于过程 / 线程切换。协程的概念虽早已提出,随着近些年年越来越多的语言(go、Haskell)内置对协程反对才被开发者所熟知,协程极大的优化了开发者编程体验,在同步、程序编程格调能疾速实现程序逻辑,还领有 IO 多路复用异步编程的性能。典型的采纳协程模型的服务有 openresty(Lua), gevent(Python), golang。
以上总结了目前 4 种罕用的并发模型,它们在工作原理、运行效率、编程难度等方面有显著区别,各自有实用场景,在理论应用时应该依据需要认真评估。在理论开发过程中如果没有可复用的现成网络组件或历史包袱咱们倡议应用协程并发模式开发网络接入层服务。
图片起源:http://www.hp91.cn/ h5 游戏