设为首页 收藏本站
查看: 480|回复: 0

[经验分享] Python 于 webgame 的应用(上)

[复制链接]
累计签到:5 天
连续签到:1 天
发表于 2017-5-2 09:24:07 | 显示全部楼层 |阅读模式
  赖勇浩(http://laiyonghao.com
  注:本文根据2011124日我在上海PyConChina上的报告的录像整理而来,有较多口语,但废话不多。
  原录像:http://e.gensee.com/v_3df867_14
  (前面约四分半钟的暖场与自我介绍,略)今天的主题演讲其实受到两个人的很大的启发,一个是洪强宁洪教授,他在2010的时候做过一个叫《Python于web2.0网站的应用》,大家可以看到我今天这个标题就是直接从他那里借鉴过来的,连微创新都没有。这个slide是很好的,所以我有给出网址,大家可以去看一下。然后还有沈崴,沈崴在2010年的时候也写了一个slide,就是《Python编程艺术》。这个slide对我的Python代码的风格影响非常大,他主要是讲到了应用Python时应该遵循怎样的编程哲学,也就是说怎样更加Pythonic。这两个slide我曾经在珠三角技术沙龙的某次活动上说是我在2010年遇到的最好的两个幻灯片。

  今天我以我经历的项目为蓝本,向大家介绍一下webgame服务器端开发这一块的技术和工具。大部分内容都是我在过去或现在的项目中使用的,有小部分内容是我以后才会在项目中用的,大家可以只当我是在做一个介绍,不要当我在做一个推广。如果你选择了这些技术,我不负责任,风险自担。所以这是一个源于项目、高于项目的(分享),因为我在做项目的过程当中会做一些思考和实验,然后这些思考和实验的结果就反映在这个演讲里面。

  (开始项目介绍)嗯,这是刚才跟大家提到过的《天下盛境》,它是一个横版卷轴的动作类网页游戏,可以看到它的地图是从左到右移动的,可以在主城里交友、跟网友互动,或是在副本打怪。它现在host在0505u.com这个运营平台,服务器端完全使用Python开发,没有一行C代码,从去年(2010年)的8月份开发到现在(2011年12月初)。这是我最近做的一个项目,因为演讲主题会讲到前做的一些东西,所以再介绍另一个项目——web版的棋牌。它其实就是QQ游戏的一个仿制品,在我自己的网站上有提供给大家访问,它的服务器端也是完全用Python来开发的,时间大概是用了两三个月的时间来开发,然后后面有一些零星的维护。它是一个半成品,不是一个可以商用的成品。

  接下来从库,也就是library的角度来介绍一下相关的开发。首先,对于Python在项目中的“位置”大家是怎么看的呢?游戏里面,经常用到脚本语言,比如最常用的一个脚本语言LUA,一般来说网游会用C++写一个host,由它调用多个LUA脚本来完成一个项目(的业务逻辑)。这就是LUA项目常见的(脚本)存在形式,而Python的话稍有不同,Python本身就是主体来的,有一些C/C++写的扩展来解决某些特定的问题,也有一些用Python来写的业务逻辑,通常Python的网游就是这样的一个结构(见下图)。
DSC0000.jpg

  大型的Python项目大家看看是不是这样的:首先有一个入口的主文件main.py,然后有几个业务逻辑的文件(file1.py、file2.py),然后同层有一些自制或公司用的库(lib1/lib2/lib3),大家的项目是否都是这样的结构?
DSC0001.png

  这样做是不对的。但是我之前经历的几个项目、包括我之前看到过的几个项目,都是这样做。然后我认为,大中型的Python项目的结构应该是这样的:
DSC0002.png

  它就是一个入口文件,然后写了一些业务逻辑(file1.py/file2.py),就是这样。大家可能会觉得有一些奇怪,那不是更小了吗?是的,其实我主张lib要放在site-packages里面,也就是做的时候,库就是库,你要分开,不要跟业务逻辑混在一起。但是大家觉得有必要搞那么复杂吗?用刚才的方式也赚到钱了呀。项目也上线了。其实呢,这么做是有一些好处的,而且最重要的是它不复杂。
DSC0003.jpg

  其实就只是写一个setup.py,就是用distutils写一个setup.py然后你再把它打包、安装过去就可以了。setup.py有两个比较关键的地方,第一个就是如何避免手写setup.py,第二个就是怎么建立命名空间包。所谓命名空间包就就是类似这种先有一个abu的前缀,后面才是rpc的包名,这样我们就可以建立专门用来做数据库的abu.db,包括我们自己的业务逻辑,比如abu.qipai。这个在zope项目是比较常见的。为了构建这样的结构,我给大家介绍一个东西——paster。因为它已经放上pypi所以大家可以使用pip/easy_install来安装它。它提供了创建项目、安装、测试、部署和运行的全栈式的支持。
   DSC0004.jpg

  大家可以帮看一下它的帮助,它后面可以加很多命令,比如创建项目、运行项目,还有产生配置文件之类的。有很多项目都使用它来构建自己的功能,比如说像pylonsturbogearszopeskel等。如果要通过paster来运行服务的话,像今天大妈(ZoomQuiet)说到supervisor是吧,其实是我比较鄙视的一个东西来的,它不好用,可以试一下这个,另外我也比较推崇start-stop-daemon,无论如何,我觉得不需要再手写守护进程,没有必要。通过pastedeploy可以把自己的应用以守护进程的方式或其它方式运行起来。以上是对paster的简单介绍,接下来看一下它的基本用法。
  要创建一个应用或一个库,首先要有一个模板。可以通过(create子命令的--list-template参数来查看当前环境可用的模板,比如在这里有一安装就有的basic_package,然后可以用-t参数指定模板,后续可跟项目名,即可创建(项目)包。paster会询问一些问题,比如版本,只需要填入或采用默认值即可,等询问完成,就获得了setup.py和相应的目录结构及相关文件了,马上即可使用,无需手写,因为setup.py里的setup函数调用有许多参数,而且这些参数还支持多种形式,要了解清楚也是非常困难的事情(,所以能不手写就不手写吧)。以上讲述的是如何避免手写setup.py,接下来聊一下如何创建命名空间包。创建命名空间包,可以先通过pypi安装pbp.skelspbp.skels带有许多模板,可以加速创建命名空间包之类的应用,节省宝贵时间。安装以后,可以看到多了一个pbp_package
   DSC0005.jpg

  然后可以通过-t参数指定使用这个模板来创建带点的命名空间包了。通过命名空间,可以有效地把自己的代码与别人的代码分隔开来。接下来是一个深入的主题,我不在此展开,有兴趣的朋友可以去读一下这篇wikihttp://lucasmanual.com/mywiki/PythonPaste),它讲述的是怎么样针对paster编写自己的横板、扩展它的命令,因为paster甚至可以让你自己添加扩展自己的命令。
  (再回到setup.py上来),通过它可以做到项目生命周期的全系列支持。比如在开发时使用develop子命名,可以避免每一次改动都要install一次。还可以用test进行测试,bdist/sdist打发布包,registerpypiserver注册,用upload把发布包上传到pypiserver等。
  所以通过这些工具的支持,大家可以很方便地把代码以库的形式分隔开来,放到库应该在的地方,而不是跟业务逻辑代码混在一起,这也有利于在产生服务器上部署代码。甚至可以自建cheeseshop,也就是pypiserver,可以建立一个公司内部使用cheeseshop,就能方便同事使用你的项目。特别是像我前东家网易这样的大公司,有时候想推广一些东西给同事用,同事说我很难用上你的东西啊,比如要穿越内网隔离之类的很麻烦,那就可以通过自建cheeseshop来解决。
  (还有一个最佳实践就是)每一次开发软件包的时候,都应该有一个干净的、纯洁的环境。virtualenv可以帮助大家建立一个纯净的环境。在项目发布的时候,不要使用系统的那个python环境,而是应该针对每一个项目建立相应的virtualenv的目录,用virtualenv里的python来运行它。去年洪教授已经在它的幻灯片里介绍过了,大家可以找来看一下,他的幻灯片写的非常详尽、严谨,而且把一个pythoner应该要了解的东西他基本都有介绍到,我从他那里学习到很多。
  接下来讲一下插件,首先,插件跟库有什么不同呢?为了讲好这个话题,我曾特意搜索了一下,结果看到stackoverflow上有一个很好的解释(http://stackoverflow.com/a/2792342):插件扩展了大性应用的能力;而库则是一系列的子程序或class来帮助你的开发。所以库和插件是两个有较大区别的概念,所以我今天是分开来介绍的。(举个生活中的例子),伞就是一个插件,当手握一把伞的时候,人就有了“防雨”的能力了。(回到软件开发中),我们以棋牌项目为例,如图,大家可以看到有多种游戏在其中:
   DSC0006.jpg

  有斗地主、五子棋和象棋等,这些可以看作是(软件的)“功能”。接下来转到后台看一下,可能会稍有不同的感觉:
DSC0007.jpg

  这个棋牌的项目是每一张桌子是一条独立的进程来运行的,比如我和另一个人下棋,那们就会有一条单独的进程为服务我们。进程以desk/main.py作为入口点,它后面可以跟不同的参数,如果跟的是xiangqi,那么它就会加载象棋业务逻辑的插件,成为一个象棋服务器;参数是doudizhu,则会加载斗地主的插件,成为一个斗地主服务器。这就给开发业务逻辑程序员提供了很好的扩展性,而且可以匹配权限隔离,也可以通过封装降低业务逻辑的开发技术,可以让相对初级的程序去开发业务逻辑,甚至干脆外包也不会暴露太多细节。以这个棋牌项目为例,开发业务逻辑(游戏玩法)的人不需要了解网络编辑,不需要了解数据库,不需要了解多线程,因为它开发的时候不需要调用原始的网络、数据库、多线程的接口,因为它们都是host提供的功能,他们只是实现host定义好的接口(或协议)。这其中也是通过setuptools来做的:
   DSC0008.jpg

  大家看这个doudizhu目录,它里面有个setup.py,还有一个很重要的是game_impl.py文件。在game_impl.py文件中,它实现了业务逻辑,也就是实现了host定义的接口。接下来我们先看看setup.py文件,大家可以看到其中最重的是这两行:可以看到定义了一个qipaionweb.games的节,节里面有个叫doudizhu的配置项,它的值是doudizhu.game_impl:GameImpl。这个值是一个class,它也可以是一个function
   DSC0009.jpg

  接下来讲一下如何加载插件,大家可以看以下代码:
DSC00010.jpg

  大家可以看到get_game_impl_class函数接受一个game_name参数,这个game_name参数其实就是前面讲到的命令行传入的参数,比如xiangqidoudizhu之类的。然后通过pkg_resources.load_entry_pointsetup.py里通过entry_points参数定义的内容取出来,在这里也就是classGameImpl啦,所以接下来把它实例化后就可用了。在host中,我们除却定义接口,还做了一些业务封装和通用功能,比如与上一级进程(也就是房间进程通信),比如每一个小游戏都有的踢人,统一管理业务相关的计时器等。游戏的实现首先是根据定义实现接口,也就是实现业务逻辑。业务程序员不接触网络、不接触数据库、面对的也是单线程的编程环境,可以大大地降低开发难度。对于插件的话题,大家还可以参考一下trac的组件架构,喜欢OOD的朋友应该能从中借鉴不少东西,我自己也从中学习到许多,比如它的组件管理器、组件和扩展点,以及接口的声明等。trac的架构与我刚才讲的稍有不同,我讲的是一个很简单的版本,因为棋牌并不需要像trac项目那么高的扩展性。
   DSC00011.jpg

  这是trac文档里的两张图,可以看到trac.core里面有一个组件管理器,它对应很多个组件,而组件就有很多个扩展点,每一个扩展点都会实现某一个接口,大概就是这样的架构。它的wiki里面有详细的文档,大家可以在线访问。插件机制不只有这一种,甚至可以自己设计和实现,比如今天上午演讲的limodou写的ulipad里面就自己实现了一套插件机制。它是一套借助mixin来实现的插件机制。
  游戏(服务器)是一件CPU密集、I/O密集的应用……(待续)
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-371915-1-1.html 上篇帖子: python一些重要但不熟悉的语法 下篇帖子: 扩展和嵌入Python解释器 Extending and Embedding the Python Interpreter
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表