配色: 字号:
计算机编程总结
2017-03-17 | 阅:  转:  |  分享 
  
1服务架构做过几年的网络游戏、垂直搜索业务,它们与地图导航业务架构也有类似之处,感觉服务端大同小异。服务最讲究的是稳定、安全。当然性能也很
重要(例如搜索、导航业务)。架构图1.1.1TLBB架构Client与Server直连,共享内存,Server多进程多线程,Wo
rld单进程单线程。简单介绍一下:Login:登录服务除了负责登录流程外,还参与管理用户的游戏角色(如:创建、删除、请求角色列表等
)。World上的在线用户数会通知给Login,如用户数超过限定值,Login让玩家排队,所以Login上面通常有排队机制(可能不
止一种排队)。Login负责从gamedb取角色完整数据,并发送到World临时保存,World将目的场景所在Server的ip信
息以及随机key发给Login,之后Login转交给客户端,客户端收到Login响应后,断开与Login的连接,转而去连接对应的
Server。由于Login本身的压力比较大,逻辑较复杂,所以可设计成多线程方式:处理客户端连接的接入可以单独放在一个线程中。完成
接入以后,用户的其他请求处理也可以单独放在一个线程中。(3)与World、Billing等服务做网络通信也可单独做成一个线程。(
4)与Database的交互也可以做单独成一个线程。Billing:计费服务连接账号数据库,负责用户登录验证,负责计费功能。Wo
rld:世界服务管理全局性的游戏数据和逻辑(组队,帮派城市,在线玩家,邮件),Server之间通信的桥梁(如:跨服切场景等)。Se
rver:游戏逻辑服务承载游戏场景Scene和游戏逻辑,比如放技能,做任务,摆摊,聊天,交易等。打个比喻,World相当于世界,S
erver相当于大洲(如:Server1相当于亚洲,Server2相当于欧洲),一个大洲又有多个国家,则这里说的Scene就相当于
国家。Scene通过配置文件指定到对应Server,一个SceneThread跑多个Scene,也是通过配置文件来指定。Serve
r本身的逻辑较复杂,承担了用户的绝大多数玩法。因此,也可以设计成多线程:接入线程:负责接受客户端网络连接请求。场景线程:负责驱动场
景,管理多个场景。当玩家接入完毕进而切入场景后的逻辑处理都由该线程完成。服务线程:与World等服务器之间的通信靠此线程完成。主(
守护)线程:负责处理日志刷新,性能检测、检查其他线程是否死锁等常规操作。ShareMemory:存档服务与Server、Worl
d服务之间共享存储,把Server、World的存档数据写入Database,共享内存是进程间通信方式中的较高效方式,可把其视为游
戏数据库的代理。有两个特点:(1)安全:因为逻辑非常单一,只做存盘加载,所以即使逻辑服务挂了,由于存盘数据内存已被共享,也可用S
hareMemory安全的保存到Database。(2)高效:如果有数据变化了,需要存盘,那么Server、World服务只需
将数据拷贝到SMU单元片,则认为存盘完成,内存拷贝比数据库写操作快。1.1.2YS架构Client通过Gateway与Serve
r相连,负载均衡,Gateway多进程多线程,Server多进程单线程。此种模型,与TLBB模型比较起来:(1)存盘服务由Sh
areMemory换成了Record服务,逻辑服务Server、世界服务World把存盘数据通过网络发给Record,不再局限于
“逻辑服务与存盘服务必须部署在同一台机器上”,但性能上有损失。(2)增加了网关服务Gateway,它只做逻辑服务与客户端之间的转
发,也分担了原本Server上的网络压力。(3)此外,Login会连接所有的Gateway服务,Login会选出一个负载较小的G
ateway,返回给Client,此后Client只与该Gateway交互。再稍微简单介绍一下以上服务:Login:登录服务登陆信
息验证,角色管理,维护各Gateway的空闲连接数,用于多Gateway间的负载均衡。玩家登陆游戏前会首先连接Login服务,进行
玩家身份认证,并且完成角色创建、删除、选择等操作,最终由Login服务选择合适的Gateway服务,通知客户端连接Gateway,
开始进行正常游戏逻辑。流程如下:客户端连接Login,连接成功后,发送账号密码信息,放入验证队列中等待验证。如果验证失败,通知客户
端错误信息;反之,返回客户端角色信息,等待客户端操作。客户端完成角色操作后,将玩家放入排队队列。等待Gateway有空闲数。如果G
ateway没有空闲连接,发送等待信息到客户端;如果有空闲连接,生成校验Key,发送到Gateway,等待Gateway通知已经收
到校验信息。在Gateway通知Login已经收到了校验信息后,Login服务发送目标Gateway的IP、port和校验Key给
客户端。客户端收到上述信息后发送关闭包,通知Login关闭,并连接Gateway服务开始正常游戏逻辑。Gateway:网关服务用于
中转用户与逻辑服务之间的的数据包。可以对玩家数据检查,防止恶意或者非法用户,另一方面,保护逻辑服务不被直接访问,提高安全性。此外,
辅助场景切换等逻辑。World服务与tlbb模型中基本一致。Server服务与tlbb模型中基本一致。Record服务用于把存盘数
据,写入Database。1.1.3Search架构多层server,webserver+渲染server+业务server,数
据分片,文件存储映射,分布式检索,负载均衡、容灾。简单介绍一下以上服务:QA:query分析服务。DA:query纠错服务。Lse
arch-pc:负责作品特型(作品、人物、人物+作品)的搜索Lsearch-com:提供短特型(pm定制、机器挖掘时效性、站点提交
时效性、亲子、教育、体育、广场舞、普通短特型等)检索AS+BS:提供普通搜索结果,BS实现数据的分片、冗余。同时,还包括小时库
(HBS)以及优质库(GBS)的检索。ASP:广告接入服务。RS:提供相关搜索结果。App-UI:中间层服务,负责把所有业务返回的
搜索结果汇总。PHP-UI:渲染层。1.2服务部署(1)一般大型后端服务都是分多运营商(电信、网通、移动等),多机房(北京、南
京、杭州等)。(2)其次,预估单台机器上的平均qps,峰值qps,以及服务网络流量与机房带宽的关系。实际部署服务时,要考虑到qp
s突然达到峰值后,是否还能正常稳定地服务。如不能,需要考虑是否增加机器,还是服务降级。若增加机器,要考虑到操作成本,例如:是否支持
动态随时添加(借助类似zookeeper的东西);以及增加了新服务后,是否保证hash还是均匀的(一致性hash)。对于减服也是同
样道理。(3)再一个是数据的可靠性容灾了。有时候数据需要做多个冗余备份。例如百度搜索的bs就是这样,一个bs挂了,那么自动切换到
同层其它列bs上。其最大的特点就是,分而治之的思想。例如:倒排表索引数据先分层(比如分3层,就相当于把数据分成3份,每份的数据占全
量的1/3);之后再在每一层上分列(比如分2列,就相当于给这层做了2个备份)。当然,最终as会把所有层的查询结果汇总到一起。通过层
与列的划分,实现了负载均衡(as选择同一层中负载小的bs),与数据容灾(同层中多个备份bs)。层与列的划分取决于实际业务情况,每列
的机器通常部署在不同的机器上,这样起到容灾作用。层与列划分的多少是个辩证关系,层划分的越细致,实际物理机一旦真坏了的时候(同一层的
所有bs都挂掉了),损失则越少,然而列就越多。反之同理。2服务开发程序运行时内存结构(代码段,数据段)。Cpu执行代码段的指令,
不断地在数据段上产生数据。2.1编码选择为了国际化以及多版本兼容,在ansi,utf-16,utf-8编码的选择上,通常选择ut
f-8编码(代码、资源等)。除了技术角度,编码风格要统一规范,让所有人写出来的代码看起来像是同一个人写的。2.2资源管理使用C+
+的对象原理,来管理这些资源,实现资源的自动回收,譬如:智能指针,自动锁等。比如:Ogre里面大量的智能指针(Ogre自己实现的)
使用,来避免内存的泄露。2.2.1内存之前做网游时,有个原则是:服务从启动到正常停服期间,服务的内存使用曲线应该是一条比较平滑的
曲线,也就是说服务启动后,尽量避免申请大内存,尽量减少内存泄露与碎片的产生。避免碎片的方法:尽量少用stl或者定制自己的stl内存
空间配置器。使用自己的内存或者对象池。避免泄露的方法:智能指针。一些特殊场合,为提升效率,可以考虑使用jemalloc/tcmal
loc来代替ptmalloc。2.2.2锁读写锁。互斥锁。条件变量+互斥锁。2.2.3网络句柄2.3性能效率2.3.1Ca
che为提升效率,开发中经常考虑使用cache,包括缓冲区(用于写)以及缓存(用于读),然而我们要面对cache与时效性问题(也就
是缓存一致性问题)。从另一层面上,cache又分为内部cache、旁路cache。cache与时效性之间是辩证关系。有时候为了减轻
服务压力,我们会做一些cache,但给时效性造成了影响。通常我们采用不同粒度的cache,按照时效性要求,对各级粒度的cache设
置不同的生效时间。例如:百度搜索的热门query的搜索结果做cache。高德地图导航CBR算法,对地图分块cell,cell内预先
算好,做cache。(3)游戏中玩家下线后立即上线,如果存盘不及时,那么也是对玩家的存盘数据做了一块缓存,玩家再次上线时,从此缓
存中读取玩家数据。2.3.2大文件读写文件存储映射(读取大文件的有效方式)。例如:百度搜索时,索引倒排表数据时,读取时使用的就是
文件映射方式。2.3.3hash表hash效率较高,google’sdense_hash_map以及boost’sunord
ered_map。google::dense_hash_map在内存占用上非常出色。查找速度极快。插入速度比boost::unor
dered_map慢。2.3.4并发服务端经常离不开那些线程池、内存池、网络IO模型。并发包括多进程、多线程,其目的都是一个,就
是充分利用机器上的CPU资源。当然,也会经常用到共享存储(进程间通信的高效方式)。2.3.5同步与阻塞同步与异步,阻塞与非阻塞是
服务开发中很常见的一个概念。同步与异步说的通常指网络操作,例如网络IO异步完成后,回调给当前线程;而阻塞与非阻塞,通常说的是线程。
线程被阻塞了,则线程不能再继续运行,进入等待。2.4设计模式2.4.1策略模式开发中经常涉及的一类问题是:策略与架构。有时需要
增加一个策略,有时需要修改一个策略,有时需要下线一个策略。做到策略与框架的分离、互不影响,也是一个常见的选择。做到策略的更新最快,
把其代价降到最小,常用做法是策略做成so方式,动态加载(热更新)。如同php扩展一般。当然也可以到策略做到脚本中,实现热更新。2.
4.2状态模式编译原理中词法分析,最常使用的就是状态机。线程状态的切换、TCP中socket状态的切换,靠的也是状态机。游戏里面
玩家状态的切换,靠的也是状态机。3服务组件3.1开源库&服务boostlibcurllibeventMySQL&redis
3.2服务支撑系统3.2.1实时干预机制例如:百度视频搜索的miss系统,干预排序结果,作品打分;高德地图的快改平台;网络游戏
中的GM工具、GM指令等。3.2.2服务版本识别例如:XLongSrv6.4.6_r112
20170112
751717Q117012500ata>2017-01-2504:06:53
3.2.3服务监
控对线上服务的监控是必不可少的,我们之前的监控主要是两个方面:(1)我们会埋点,即在服务的日志中打印各个请求的响应时间,关键点处的各项指标等。监控系统扫描日志(支持正则),通过计算获取具体指标,如qps,pv等等。同时服务日志分级,debug,info,warning,error,fatal的,如扫描出一定数量的fatal,则报警。(2)其次,监控系统会监控线上服务的资源使用情况,例如:内存、网络句柄使用、服务探活、是否发生core等情况。(3)再次,监控线上服务所在机器的资源使用情况,例如:磁盘是否占满、达到临界值、网络带宽,内存/CPU使用率,以及其他异常情况等。遇严重情况,报警。czfdlut@163.com8/8
献花(0)
+1
(本文系czfdlut123首藏)