C++架构优化

背景介绍

公司是一家小的游戏公司,日活百万左右,同时最高在线人数30w左右。公司的核心服务使用C++开发,生产环境是windows.
游戏基础服务主要职责就是承载公司游戏的登陆、业务逻辑、通知、游戏数据结算、玩家信息统计等功能,而具体的游戏逻辑在各个游戏团队的游戏服务中负责。

游戏基础服务一旦出现问题,玩家就无法游戏,因为无法登陆、无法结算…. 所以是需要高可靠的服务。

我的主要职责就是维护基础服务的稳定运行。

以上是职责介绍,下面是刚入职时基础服务的架构。

早期的架构

架构基本是按照业务单元进行分服务开发,但也不像微服务那么细微。

大致讲解:

整个架构是比较清晰的,而且按照功能进行划分,所有服务都支持横向扩展,db使用分库分表设计。所以在性能上、横向扩展都没有太大问题。

但实际在维护的过程中,还是会发现很多不合理的地方。

  • 升级一个简单的功能,需要重启很多重要的服务。每次升级都很纠结
  • 版本发布、代码编写很不方便
  • 出现问题定位很费时间
  • 问题随机、随时出现,没任何预兆
    …………

大量的非工作时间被白白浪费!!!!!!!!

不合理的地方

1
自己的备忘录里面记录了服务大致需要整改的点有100多处

生产工具落后

使用的还是VC6 编译器。
无法使用c++1x的语法、写代码不方便、开源库不好支持等等

没有持续集成环境

版本发布依赖领导的时间。(生产环境的版本必须由领导的机器编译),有次出现问题,问题定位5分钟,版本发布却花了3个小时。

服务无法灰度升级

服务升级都要在凌晨6点升级,而且升级过程中整体服务无法使用

单个服务异常影响整体

整个架构里面服务相互链接构成网状,当某个服务异常时,常常会关联其他服务出现异常

整体服务容错性不足

单台block、check异常,就会导致这个节点上的所有玩家和游戏出现异常

没有健康监控功能

出现问题都是玩家反馈,研发自己都不知道服务是否出现异常;

没有预警机制

当性能、内存、io等不足时没有提早告知进行准备

定位方法落后

采用原始的vistual stdio 调试,没有分析dump的能力

msmq 功能扩展、维护、定位麻烦

服务的管理、配置落后

整体架构缺陷

这个涉及点比较多,后续慢慢展开。

整改原因

就是想做!!

优化点

升级开发工具到vs2013

服务性能监控

服务消息堆积数量、进程cpu、磁盘容量、提交内存大小 数据到大数据平台。
出现问题时,基本都是第一时间就能够在钉钉收到预警通知。

使用jenkins进行持续集成

windbg分析的持续培训

C++的优化

原来都采用的MFC的CMap、CString、线程、锁等都需要替换为stl、boost类型

调整架构,支持灰度发布

1
目前还在持续优化中

设计的方法:

  • 模块设计“幂等性”

  • 服务尽量无状态
    这样游戏、玩家可以随机指定链接,然后引入负载均衡+域名管理,就可以方便地地给服务器导流,支持灰度升级

  • 重试次数控制 + 熔断

  • redis缓存、MQ 异步

  • 隔离设计

  • 将影响玩家的业务和统计业务,中间搭建 actik中转服务隔离开来
    所有下游统计业务都需要经过actik服务进行清洗,然后才能到具体的业务服务中去

  • 玩家隔离
    比如将pc、移动、微信玩家连接的服务进行隔离,减少影响面。

  • 使用rabbitmq替换msmq
    rabbitmq支持AMQP协议,扩展、管理、维护都非常方便

  • 数据库的优化
    分库、分表;购买新硬件、数据备份、导入导出
    使用mqsql 替换sql server

总结

无意间看到一篇服务弹力设计的文章,总结的比我好,自己就是朝这个方向在调整!

upload successful

后续计划

  • 引入稳定的gate服务

  • 统一配置中心

  • linux化

  • 服务go语言化

效果

  • 基础服务稳定性提高非常明显,两年就没出现过重大事故。
  • 升级也方便了很多,大部分都可以灰度升级。
  • 线上出现问题也能快速定位,出现问题心不慌。