网络基础知识
先简单的介绍一下计算网络的一些基础知识 :)
首先说一下 tcp:tcp的好处就是“可靠”,会将体积大的数据包进行分片,保证不会让ip协议进行分片。会检测数据包是否丢包,丢包重传,有序地发送数据包等等,坏处就是数据包头比较臃肿,至少有20+的字节(不要小看这20+字节),在丢包重传时,会阻塞后面的数据包,而且tcp需要保持连接状态才能进行通讯,在连接数较多时,服务器光在handle这些连接状态上就要消耗不少的性能。题主所说的“长连接”应该指的是tcp socket,tcp socket是操作系统为tcp协议的实现(说白了就是操作系统为tcp提供的api)
http: http处于应用层,是基于tcp的实现。它继承了tcp的所有优点。跟tcp有些不同,http不会一直的保持连接状态,在早期的http 1.0时期,http请求在得到响应后会立即断开连接,这样就导致了每次的http请求都必须去进行tcp握手(在数据报文很小时,握手时间甚至会超过数据传送时间),在1.1版本后使用同一个连接进行多次的http请求,在一段时间内没有再次进行http请求时,会自动断开,这样就减轻了服务器维护大量链接所产生的开销问题,但是http是应用层,它会产生新的数据报头,在数据包的容量上会更大。
在说一下题主这里没有提到的udp: udp 是“不可靠”的:不会丢包重传,会导致ip分片从而丢包,数据包不会按序送达,只保证到达的包数据是完整的,它的好处就是,不会产生tcp丢包时的队列阻塞,数据报头较小,只有8个字节,是一个无连接协议。
手游用什么协议?有啥优缺点?
tcp:优点就是tcp的功能太强大了,基本上没有tcp做不了的事,而且基于tcp的第三方库也非常多而且稳定,开发起来比较顺心。但tcp的缺点也很多,数据报头有20+字节,在一些动作类游戏中,需要非常频繁地与服务器进行交互,而且通常一个操作指令会很小(基本上都小于20个字节 :P),这就代表一半的带宽开销被用在了数据报头上。其次就是tcp需要保持连接状态,这个在pc上可能不是问题,在手机上问题就大了。手机信号不稳定,ios操作系统会将后台非特殊进程挂起,导致游戏断线需要断线重连,也就是重新登陆一次,做过网游的同学都知道,游戏登陆操作对服务器的开销往往是最大的。再一个就是tcp丢包重传的特性引起的,每次发送数据包需要check是否包已到达,队列后的数据包需要等待前一个数据包成功发送后才能进行发送,这样会导致严重的lag,在手机信号不好时尤为明显。由于大量的tcp连接会带来开销,基于tcp的游戏通常在线人数会有limit,当然,使用分布式架构或者游戏滚服会解决掉这个问题(tcp分布式架构人人都会做,做的好不好,这个得看功力)。
http:因为http不需要持续地保持连接,是一个无状态的连接,不会产生tcp所产生的断线重连的问题,服务器也不需要维护过多的连接。缺点就是需要经常的进行tcp握手操作(不会影响玩家体验),而且由于http的无状态性,通常游戏数据需要实时保存,不过现在的内存数据库 nosql的兴起和计算机性能的提升,这块劣势已经不存在,而且越来越多的游戏都采用实时数据保存,防止游戏服务器宕机数据回档的风险。再一个就是服务器无法主动向客户端推送数据,导致在某些功能上会无法实现。由于http的无状态性,需要做心跳处理,基于http的游戏服务器可以横向扩展(每一个游戏服务器进程就是一个单纯的逻辑计算器),数据库架构设计的好的话,一个游戏服很容易实现1亿+的玩家同服的情况。
udp:优点就是“快”和“小”,udp不会产生tcp的数据包队列阻塞的问题,而且报头数据量很小,在某些对速度和网络io量有较大要求的玩法时,这2个优点显得尤为重要,而且udp是无连接的,不会产生断线问题,也可以横向扩展。缺点就是udp的不可靠性,一些实现可靠的udp协议的第三方库很少,而且往往满足不了自己项目的需求,所以要实现可靠的udp要自己动手造一遍轮子,需要一定的网络基础知识和敢于踩坑的精神 :P
推荐方案1 :完全使用udp,几个项目下来,我觉得使用udp做手游服务端真的是perfect match。没有断线问题,流量小,响应速度快。无奈手游环境开发商们心态比较浮躁,都以稳定来追求利益最大化,市面上完全使用udp的游戏非常少。
方案2 :http+udp,这种相对保守一些,逻辑相关的使用http协议,保证游戏逻辑不会出通讯上的问题,推送类的使用udp,比如聊天,世界公告等等,这些就算你的udp协议写的烂,也不会产生严重问题。如果实时性要求非常高的战斗功能,请使用udp。