目前代码比较粗糙,欢迎各种改进建议。 最近一直想学习一些关于游戏服务器的知识,显示看了一下云风的skynet框架,从而对于一个游戏服务器框架有了一个基本概要了解。先来说说我对于skynet的一些理解吧。
skynet只完成了服务器最核心的一部分功能,必须消息分发,必须服务的创建、销毁以及服务间的通信。 skynet中最核心的两个部分,网络和消息分发。
skynet中有一个消息队列的队列,这个队列保存了每一个服务的消息队列,当发送消息的时候,将消息放入指定服务器的消息队列中,然后有1-N个工作线程,负责从队列中取出一个服务器的消息,然后在这个线程中对这些消息进行处理,当处理完毕之后又放回到消息队列中,这样就保证一个服务的消息,每次分发都只会在一个线程中执行,从而避免了一些不必要的资源竞争(因为一个服务的逻辑只会同时在一个线程中执行,所以在一个服务逻辑内部不需要考虑资源竞争)。 当然这里进行消息分发还有一些其他原则来保证一个服务不会太长时间占用工作线程。 当然,针对服务器,云风还在lua层做了很多重要的处理,这里就不细说了。
所有的网络操作,最终都统一到了一个网络线程中,在这个线程中使用了epoll模式来实现高并发的网络模型,在socket中,每一个fd都会和一个服务相关联,当该fd上有消息到来的时候,对应的消息会被转发到fd对应的服务的消息队列中,这样服务就可以对网络消息进行处理了,同时对fd的写操作也会被分发到该线程,并在fd可写的时候,进行消息发送。
然后在基于上述消息分发和网络的基础上,skynet还构建了一个基于master-slave的多节点系统,通过服务的全局名字和节点ID|服务ID,将消息从一个节点分发到另外一个节点对应的服务中。
在看完skynet之后,当然也只是一知半解,不过基本还是达到了可以使用的程度了。但是当准备开始用它来写一个游戏服务器的时候,还是发现有点力不从心,一是skynet只是一个核心,真要用他来实现功能,其实还需要很多其他的东西,比如数据库,比如http,通信协议…等等,当然这些都是可以解决的,也已经有很多人用skynet写了游戏服务器,但是中最要的一点还是我不太习惯动态语言,使用lua来写代码,让我很没有底气。一个简单的大小写都要等到运行时才能检测得到。 就是在这样一种心态下,我开始接触了go语言,一个静态类型、编译、类C的语言,并且支持高并发和一样很好的封装了通信和网络接口。 通过几天的go语言学习,我决定用它来实现自己的第一个游戏服务器框架,因为以前没有怎么接触过游戏服务器编程,所以就只好模拟一下skynet的行为了。