两年多里自己都干了什么?

       2016年7月份毕业,算上实习的几个月时间,工作两年多快三年了,自己都干了什么,回顾自己的职业生涯,大部分的工作都在在从事游戏服务器的开发。虽说有时候加班会很严重,但是熬过来了。但是想想过去的加班大部分的时间不过是在陪别人加班而已,作为一个初入职场的学生,自己解决为题的能力实在有限。但是说句心里话,不喜欢加班,如果非特殊情况,白天的时间完全可以完成工作任务,加班根本没必要(以上只是自己的个人观点,不代表所有)。

       先说说这段时间里看过的书吧,我觉得作为职场菜鸟,通过看书来稳固自己的基础是很有必要的。c++primer第五版(大学时候基本上看完了,只是回过头看了一下之前没看懂的),你必须知道的222个c++问题,effective c++,深度探索c++对象模型,c++11新标准的并发和多线程编程深度指南,提高c++性能编程技术,tcp/ip详解和socket套接字编程(这两本没看完实在太厚偷笑),libevent源码详解,stl c++11,算法导论(实在太高深看不下去啊,驾驭不了),Unix环境高级编程,大型网站架构设计原理等等,还有一些关于java和golang的东东。

      工作之余自己搭了一套c++游戏服务器的架子,首先说明并不是从零开始写的,是基于一套比较成熟的框架的基础上改的,只是里面的所用到的东西太过时,并且是单线程的不能充分发挥多核cpu的优势,所以自己动手把整个框架改了一下。

      首先说下老的框架,我猜这套框架应该是一套用来mmo或者rpg的一套东西,基本上是多进程单线程的技术方案(下面提到的服务器基本上是单线程模型)。首先一个网管服务器接受客户端的数据(手写的epoll网络模型,现在应该很少人自己写这种东西了),然后是gameserver,dbserver,sceneserver,logserver等,这几个server都作为客户端连接一个叫做proxyerver的服务器,负责gameserver,dbserver,sceneserver,logserver这些服务器之间相互通信,看起来很简单,但是我觉得你如果能写出这一套东西,并且处理好每个服务器之间的通信,解决开发工程服务器出现的各种个问题,并且能扛得住并发压力,至少你离高级工程师不远了。

      接下来说我对这套看起来很老旧但是很实用的东西做了什么(所谓的一招鲜吃遍天,大多数的游戏服务器大同小异都差不多)。    首先网络部分,改用libevent简单易用。

     其次是网管服务器gateserver,这里负责大量的客户端连接,改为两个三个线程,线程1:libevent事件循环线程,线程2:负责处理libevent事件,包括消息的加密和解密等,线程1只负责派发事件,不处理,线程3负责监听是否有下发gameserver客户端的数据,这里说一下,gateserver和gameserver通过两个共享内存管道相互通信,a==>b,b==>a即a写b读,和b写a读,从而加快两者的通信速度,当然这里也可以用socket,如果你的通信量大,共享内存可以提升服务器的消息吞吐量,不过共享内存也限制了gateserver和gameserver进程必须在同一台物理机上。当然这里的通信方式可以有其他的选择,比如socket,虽然传输效率上没有共享内存快,但是没有了必须同物理机部署的限制,不过socket还有另外的问题就是需要处理两个进程之socket断开的问题,在上行和下行数据时,如何保证数据的完整性和正确性。当然还有另外一个更简单的处理方法,就是把两个进程合并为一个进程,但是这和第一个选择没有根本的区别,虽然编程方面相对简单,但是相对于第一种框架的整体扩展性和维护差,比如我们在后期处理gameserver崩溃或者增加其他类型的服务进程的时候,我们可以通过gateserver做很多工作,但是如果gate和其他进程耦合到一起就没有发挥的空间了。

      接下来是gamesever,这里负责百分之90的游戏逻辑处理,首先有一个逻辑线程线程1负责处理游戏逻辑,线程2:libevent事件循环线程(这里主要负责和proxyerver通信,前面已经说过和客户端的通信通过共享内存管道),同样这个线程只负责派发事件(timer事件和io事件)。线程3:io线程负责收发消息,接收和发送proxyserver之间的消息。比如线程2接收到来自proxyserve的消息时间后先push到io线程进行消息解包,如果需要处理逻辑接着push到线程1。不管是发送给client或者proxyserver的消息都push到io线程。最后一个线程线程4:主要是监听gateserver的写共享内存管道是否有数据可读,如果有读数据,解包后push到逻辑线程,处理逻辑。

   这里说下逻辑线程,可能有人会说为什么不把逻辑线程线程一个线程池多线程处理逻辑,我并不否认这样做会增加服务器的处理能力,对于一些逻辑简单,玩家之间没有数据共享或者共享少的情境下这样处理完全可以,但是对于有大量数据共享的场景,并且玩家可以离线操作另外一个玩家的数据的情况下,我们需要大量的精力和工作来保证数据的一致性。最粗暴的就是加锁,但是大量的加锁会极大的降低服务器的处理速度。还有一个就是开发过程中可能会出现很多奇怪的问题,都是由于多线程处理逻辑不当造成的。所以逻辑线程采用单线程还是线程池视情况而定吧。

  其次是dbserver,logserver等这些主要处理来自proxyserver转发而来的数据,基本上没有复杂的设计,都是一个libevent事件线程处理所有的逻辑,要不要改成多线程视情况而定吧。

  架构图:

  

      当然目前只是一个基本的架构,很多细节仍在完善,比如说意外宕机事故处理,如果是滚服式的游戏类型,到这里工作基本上差不多完成了。但是如果要做全球同服,这样肯定是不行的,必须通过负载均衡或者分布式来支撑,这也是接下来我主要研究和完善的内容。

     闲暇之余会了解下go和java(目前的项目是用java写的,不得不承认如果你的项目不是大型重度游戏项目,c++用的越来越少了),不得不说作为企业应用的首选java的源码实现非常值得研究,不管你写什么语言,它都会给你很大的帮助,可以在实现方法和编程技巧上给你很大的启发。但是作为一个业余的java开发我不想过于深的去了解java,毕竟c++才是我的第一语言,说句多余的话,如果要选择一门第二语言,我觉得go比java更有价值(如果主程看见我写这篇文章,我会不会死的很惨偷笑)。

猜你喜欢

转载自blog.csdn.net/d_guco/article/details/79515219