PHP在金山游戏运营中的应用

2014 年 11 月 21 日3950

   

  大家好,现在我来跟大家分享的是PHP在金山游戏运营中的,包括团队开发,以及像系统结构,设计,运营平台这些信息。我议题主要有两个,一个是在金山游戏官方网站做的一些应用,还有在金山游戏运营系统Keyes中的应用。金山官方网站包括有客服,一些问问,知道等等,包括跟游戏相关的一些产品,这块主要采用Linux系统,64位,PHP是5.2版本。

  我们首先来看团队协作开发,我们肯定遇到过一个情况,在我们现在很多项目当中都是多个人从事开发一个项目,又涉及到开发环境和测试环境不一样。我们PHP全部利用在Windows上利用,但是很多人在Linux开发代码,我改完某一个功能,想马上看一下执行结果,这时在Windows上也可以配相应平台,但是我们还开发一些像PHP扩展去操作一些,假如分布式图片处理,一些缓存系统,这些是针对Linux下PHP进行一些PHP扩展开发。所以,在Windows平台是没法使用的。

  这块希望写一个程序能够马上看到,但是我们不需要写一个程序传到服务器上再测试,就太慢了。如果同一个服务器上有多少人同时开发,你传上去可能会覆盖别人的程序,就没有办法做到控制。我们可以看到,我们使用是程序员A的 Windows开发环境PC机模式,我们从上面可以看到,假如是程序员A和B都在Windows上开发代码,我们可以把Nginx装在Windows上,我们在Windows开发程序,每个程序员进行测试,测试完之后可以进行调试,这样执行的结果还是用Linux下进行执行。

  从这个流程可以看到,首先是一个程序员他获得一个项目版本,上来做一些修改,修改完之后可以在调试采用同一个Linux测试服务器。他测试完成之后,在本级测试没有问题,可以提交到我SVN版本库,可以做一个自动同步程序,包括Linux开发和测试服务器上。这个SVN同步,会自动通知Linux把最新代码进行更新。后来发现有问题,如果我们程序文件特别多的话,之前SVN非常慢,这样程序员在测试完之后,提交SVN等等。

  我们为了方便,因为我们需要做一个预测,我们每天一个虚拟主机,我们在左边添加一个虚拟主机,添加虚拟主机之后会把当前目录做到Linux上。这可以看到,在下面这是整个流程可以设置tosts为本机IP,在自己电脑上,修改完一个文件,本地调试没有问题之后就可以提交。在Windows编写代码PHP 代码文件,用Linux环境的PHP来调试,保证开发环境、测试环境生成环境统一。整个PHP开发环境、测试环境,即保证了程序员的快速修改,调式代码需求,又保证整个代码在SVN版本控制之中。

  开发环境这时候又会遇到这样一个问题,PHP代码统一性保证。我们在开发环境先到线下测试环境,线下测试完之后到线上测试环境,最终到正式环境,这有很多种环境。另外我们开发项目比较多,大概10多个项目,很多项目连接到MySQL、 Memcached、接口IP,发短信,查询下用户数据资料他们端口各不相同,程序员经常搞错,或者一团雾水,这样谁最了解服务器配器,肯定是系统工程师,这样需要把二者进行分开。让最熟悉这块业务去做,这样我们就开发了一个PHP扩展,还有一个kae-config管理后台,我们在每个服务器上通过个后台进行发布,需要做的只是系统工程师在不同环境,对不同服务器系统,配置不同参数,不同IP端口。

  每个PHP版本都进行统一之后,包括PHP文件进行统一之后,就涉及到PHP代码上线发布。不知道其他公司怎么做,我们把上线发布这一块,交给每个项目负责程序开发负责人去做,这块就可以把系统工程师从代码发布中解放出来。从上线发布版本,假如我们要发布一个1.0版本,这是2.1.46版本,可以进行对应起来,如果我要发用户中心2.1.46版本,就可以对应21901,两个版本之间和上个版本,假如2万版本之间有哪些修改,我们可以通过PHP获取出来。通过系统发布的时候,我们就只能发布这个文件。

  于是我们开发一个代码发布后台,从上面两个标红的地方可以看到,我们新增一个发布会新增一个版本号,有主版本,次要版本。这样的话对每个工程师会开发一个版本,包括一个项目,可以有不同负责人去进行商业发布,每个上线会提交相关信息。从右边按纽可以看到,我们要启动哪个版本的时候,我们可以进行版本发布,如果我们发现这个版本上线之后,如果有重大问题,假如需要很长时间解决,马上回到上一个版本,通过每次版本发布内容进行版本控制,这样整个版本发布一目了然。

  第三PHP与开源产品、C/C++程序组合。利用PHP客户端扩展,通过TCP协议与C/C++开源程序进行通讯,例如与Sphinx而搜索等等。方式二,我们是开发一些基于HTTP协议与C/C++开源程序进行通讯,例如与我们字形开发的开源简单消息队列软件,HTTPQS进行通讯。PHP Web程序,Web程序要求每次请求都要非常快,处理速度需要在毫秒级解决。我们也遇到一些服务,比如发手机短信,还有发送邮件也需要几十秒时间,这让用户在前端页面等待对用户体验不好。

  还有上传视频,我们需要视频格式转换,以及我们进行数据挖掘,需要记录用户的一些信息,记录一些日志,这样我们就需要异步处理。为了解决异步处理,我们也是分为两种情况。一个是短耗时异步处理,耗1、2秒时间,记录一些数字挖掘信息,这可能耗的时间比较短,这时候我们可以用PHP-FPM提供 fastcgi-finish-reques函数。从调入这个函数之后,下面执行结果用户不会去等待下面这个结果,这样可以实现一些异步。

  fastcgi-finish-reques函数缺点。PHPFastCGI进程数有限,正在处理异步操作的PHP-CGI进程,无法处理新请求。如果并发访问量较大,php-cgi进程数用满,新访问请求,将没有php-cgi额去处理。Nginx服务器会出现,502 Bad操作采取队列式进行解决,包括开源队列。这样的话,在我们产品应用中,我们应用到下面一些清我们发送短信,我们可以先入队列,最后从队列进行邮件发送,像刷新前面页面缓存,获益做上面视频页面转换都可以进行异步方式解决。

  我们采用一个PHP负载均衡方式,从这个架构图是我们一个大概游戏官网架构。可以看到有论坛,有普通一些PHP服务,最前端我们用两台服务器去进行均衡,下面比较大的业务像一些论坛,或者是游戏活动,单独画一组PHP外部服务器。这样通过负载均衡去分发到下面PHP进行义务处理,从PHP到后端又会连接一些,刚才我们提到一些像分布式图片处理,一些搜索引擎,像这些接口进行操作。

  当然我们在开发服务,因为我们有多台WEB服务器,我们在PHP开发的时候也需要注意。以前单机程序为了近来缓存,如果布置在多台服务器,可能在这台服务器生存了,在那台服务器上没有生存。另外每次访问会生成很多小文件,小文件会占用Linux大量浏览,有时候磁盘没有完,但是没有办法新建文件了,因为建了很多小缓存文件,导致整个应用满了。这样对数据对象缓存我用APC、Memcached代替。

  还有HTML输出网页缓存,我们用前端Nginx负载均衡来做一个缓存。Nginx负载均衡现在也可以支持缓存,把动态一些内容访问到后端WEB服务器进行缓存。如果是一些长期页面,像游戏官网,像一些图片不仅能改变。有一个优点,WEB服务器上,PHP文件能够通过代码发布系统统一管理,增,删WEB服务器,非常快捷,清除缓存,能够由系统工程师去统一管理。

  另外涉及到代码防篡改,万一有客户上传木马上去,也能够在我们PHP程序中开发一个预判断进行一个解决。因为我们PHP程序是通过代码系统发布,能够让它执行,如果不是通过我们代码发布系统发布的程序,假如他在上面创建一个PHP文件,或者上传一个PHP文件,这也是不经过代码发布系统生成,同时会发一个报警短信,报警文件给你相应系统工程师进行查看。多台服务器有Session会话,有一些登录操作。我们一个采用在负载均衡服务器上做IP哈希,不同用户根据IP不同分布到不同服务器。另外在PHPWeb服务器上做Session共享,必不可少。

  下面是PHP在金山游戏运营系统Keyes中应用。包括一个游戏,如何开活,发广播等这些信息需要通过一个平台来解决。这是我们设计的一个架构,主要是分为界面,接口和支撑,三层架构设计。从最早做三角是一个管理界面,现在很多项目也进行一些IPI开发,肯定IPI是单独一套,本站自己使用界面也是一套。但是我们会把它完全做成一个IPI,对数据一些功能操作全部分在IPI接口,管理界面只是实现管理界面的逻辑。我在这个运营管理系统当中可以进行查看,比如一些经营分析系统,也需要获取用户在线信息,可以调取PHP进行操作。

  在右边这个部分是属于游戏服务器,左边是运营服务器,右边是一些游戏服务器。游戏服务器上,涉及到每个游戏服务端架构都不一样,他也包括服务端架构也是跨服务器的,像网端服务器。我们运营每一台服务器上有一个守护进程,我们采用Knose开发,我们通过一个加密协议进行访问。我们通过多个游戏进程进行访问,包括开发一些指令,发送一些信号,在和他游戏通信,有我们可以监控进程存在,这个进程和通讯是否正常。

  可能有这样一种情况,一个是游戏进程存在,假如因为游戏内部僵死了,这时候我们通过一个PHP心跳,游戏服务端进程服务,就认为这个服务端进程是存活的。从外部去管理游戏服务器,这一块我们涉及到一个时间问题。因为我们外部程序需要时间非常快,我发布一个停滞指令,在游戏服务器需要从网端去建立用户一些连接,还有保存一些用户数据,他完成整个过程才能把整个游戏服务端停掉,如果引入比较多,保证数据可能是几十秒到1分钟,从前端外部用户去进行介入会发现超时情况,外部需要做一个操作马上能够完成。这样我们去设计接口的时候,我们从PHP管理界面,我们发起一个功能接口,这个功能接口就进行转发,这个请求完成,去通知各个游戏进程做一个评估操作,做完评估操作之后发起一个新的请求去回掉这边PHP功能接口,这样的话就变成一个异步过程。

  下面是一个数据交互过程,分为四项功能。一个是运营指令,涉及到修改经验倍数,踢人,发消息广播,启动游戏,停止游戏、更新游戏程序,更新配置文件、并服。第二个是服务器监控,包括CPU、磁盘、内存、进程数、系统负载、游戏服务端进程是否存在。游戏心跳检测,Ping包检测,确定游戏是否正常运行,还有游戏在线人数,查看游戏总在线人数。

  我们在开发这套平台的时候遇到这种情况,一套程序需要不同游戏服务端架构。现在我们还带领别的公司一些游戏,带领别的公司游戏服务端架构不一样,这样的话我们去怎样用一套平台去适应每一个游戏工作室,或者游戏开发公司架构呢。前期我们肯定是考虑这样一个方法,我们提供一个IPI接口,制定一个游戏,按照他们都要按照这个协议,按照这个IPI接口进行接入。到实际进行开发的时候会发现遇到一些问题,我们在各种游戏需要接入运营系统的时候,这个游戏基本上已经成型了,到绿色状态。他们每个游戏可能需要进行一些,他们也会利用一些框架进行开发,包括GSP协议框架,他们已经封装好了,马上可以按照我们这个协议去做。

  如果按照我们提供的接口来开发,可能从时间上,成本上都会存在一个问题。这就是我们进行一个举例,我们如果派大巴车去接,有些人说我喜欢自己开车过来,可能别的人喜欢骑摩托车过来,这就代表这封装一些框架,对协议的处理都不一样。可能也有比较愿意接受这套方案的,这样的话为了能够让每一个游戏研发公司都能够去适应我们这个平台进行快速接入,我们就需要对接口方案进行改造。

  这就有点像我们开车一样,我们来派大巴车去接方案,我们改了一个更开阔的方案,我们和各个游戏进行,你们只要使用PHP协议和我们通讯就可以了,我们去做一个道路设计。我们修一条公路,你们想开奥迪宝马都可以,想骑摩托车过来也都可以,我们会制定一个协议事例,你想按照这套事例来都可以。这样每个游戏需要遵循我们这个平台,但是这样的话也需要一些约束,比如我要开飞机过来肯定不行,虽然可以给他们更宽松的制约,但是也需要遵守一些规定,比如你开车过来不能闯红灯,需要遵守一些交通规则。我们会根据不同游戏,可以分为二进制协议,因为的话制定二进制协议,PHP是一个流媒体秀逸我们需要进行分包,有些游戏在一个协议包中间某两个字节表示游戏包长度。我们通过配置文件,去设定对二进制要求。

  最终每个协议不同,运行系统需要解析出来这部分过程,放到左边PHP功能结构。PHP开发非常迅速,我们同样去解析他一个歇息也会非常迅速。他通过一个 PHP流动协议,我们去进行一个转化,转化成一个IP请求,这样PHP只要能够对他游戏协议进行一个解析,这样就可以轻松地完成。可能解析代码非常简单,这块从开发层面来说非常快了。我们在3月份的介入三款游戏,同一时间同时介入,最后同一时期完成介入,这也是从结构设计来设定的。

  每个游戏服务端架构不同,最终分散起来只能定义为进程。游戏决策这部分可能有四个进程,上面这个服务器又分不同服务器,下面这个进程又分不同服务器。上面三个进程利用在Windows服务器上,剩下几个利用在Linux上,这样的话我们在PHP外部界面对进程进行一个组织。因为游戏服务端最终由每个进程进行组织,这些性能组织起来,我们可以跟不同架构服务器端进行通讯,不管架构怎么设计,是一个服务器上运营两种服务,或者多台服务器上运营多种服务,不管架构怎么变,只要最终定位进程上就可以解决,对不同游戏兼容性,这样就能做到一个通用平台,能做到一个架构之上的架构。

  我今天的演讲就到此,谢谢大家。(phpchina)

0 0