为什么go语言适合开发网游服务器?
个人认为golang非常适合网络游戏的服务器端开发。写这篇文章总结一下。从网络游戏的角度来看,一款网络游戏的成功运营,很大程度上取决于玩家自发形成的社群。只有玩家自发形成稳定的生态系统,游戏才能继续下去,避免鬼城的出现。这需要大量用户多次导入,同时在线人数达到某个临界点才可能完成。所以需要多人同时在线。我们来看看网络游戏的常见玩法。除了排行榜等统计和数据汇总功能外,基本没有需要大量CPU时间的应用。在之前的项目中,实时战斗造成的各种伤害的计算并没有消耗太多CPU。为了完成一个操作,玩家需要通过客户端-服务器-客户端来来回回。为了获得高响应速度,满足玩家体验,服务器端处理不能占用太多时间。所以每个请求对应的CPU占用比较少。网络游戏的IO主要分为两个方面,一个是网络IO,一个是磁盘IO。网络IO方面,可以分为美术资源的IO和游戏逻辑指令的IO。在这里,我主要分析游戏逻辑的IO。游戏逻辑的IO和CPU的IO差不多,每次请求的字节数很少,但是并发数相当高,因为很多人同时在线。此外,地图信息的广播也会带来更频繁的网络交流。在磁盘IO方面,主要是游戏数据的存储。使用不同的数据库会有很大的不同。在之前的项目中,我经历了从MySQL到MongoDB的转变过程,磁盘IO不再是瓶颈。总的来说,利用内存作为一级缓冲,避免大量小数据块的读写,还是一种方案。鉴于网络游戏的这些特点,golang的语言特点非常适合开发游戏服务器。首先,go语言提供了goroutine机制作为原生并发机制。每个goroutine需要的内存非常少,在实际应用中可以启动大量的go routine来响应并发连接。Goroutine和gevent里的greenlet很像。当IO阻塞时,调度器会自动切换到另一个goroutine,保证CPU不会因为IO而等待。与gevent相比,goroutine在python底层没有GIL限制,因此不需要使用多个进程来提取多核机器的性能。通过设置最大线程数,可以控制go启动的线程,每个线程执行一个goroutine,使CPU运行在全负荷。同时,go语言为goroutine提供了独特的通信机制通道。通道读写的时候也会挂起当前操作通道的goroutine,这是一种同步阻塞通信。这样既达到了通信的目的,又实现了同步。从CSP模型来看,并发模型是通过一组流程和流程之间的事件来触发解决任务的。虽然主流编程语言只要图灵完整就能实现同样的功能。而go语言提供的程序间通信机制,非常优雅地揭示了程序间通信的本质,避免了过去显式使用锁给程序员带来的心理负担,这确实是一个很大的优势。开发网络游戏的程序员可以用单线程阻塞的方式编写游戏逻辑,不需要额外考虑线程调度和线程间的数据依赖。因为线程间的通道通信已经表达了线程间的数据依赖,而go的调度器会妥善处理。此外,go语言提供的gc机制和指针的保护性使用,可以大大减轻程序员的开发压力,提高开发效率。展望未来,我期待go语言社区能提供更多goroutine之间的隔离机制。我个人非常推崇erlang社区的脆弱哲学,推动应用在意外行为发生时尽快崩溃,然后分叉出一个新的进程来处理新的请求。对于协程机制,程序员需要保证执行的函数不会出现无限循环,导致线程卡住。