Posts 第五课:分布式系统设计
Post
Cancel

第五课:分布式系统设计

分布式系统概览

分布式系统指分布在硬件设备上的多个软件组件,彼此通过网络来通信和协作的系统。

分布式系统需要考虑的问题包括:业务模块划分、负载均衡、融在容错、网络通信等

消息队列:专门负责消息传递的通用中间件。特点:解耦发送方和接收方、稳定可靠

感性认识分布式系统:

Screen Shot 2021-04-08 at 20.52.21

腾讯游戏通信方案-TBUS(进程间通信)

  • TBUS地址
    • World.Zone.Func.Instance
    • 微信.一区.pvp战斗进程.1号
  • 例子
    • 进程A:1.1.2.1;进程B:1.1.3.1;
    • TBUSD A:1.1.1.1;TBUSD B:1.1.1.2;

Screen Shot 2021-04-08 at 20.31.53

通过GCIM(全局的路由配置信息)/GRM两套配置管理工具,tbusd(A)就可以知道tbusd(B)在哪台机器上。

Screen Shot 2021-04-08 at 20.39.26

TBUS Channel是共享内存做的。是进程和tbusd之间进行交流方式。

Screen Shot 2021-04-08 at 20.44.14

TBUS特点:

  • 屏蔽部署细节
    • 通过TBUS ID替代IP地址和Port
    • TBUS ID作为抽象,覆盖了下层细节
    • IP地址变更也不会修改TBUS ID
  • 程序重启影响小
    • 网络层被托管
      • 无需建立连接
      • 不会丢失网络上的消息
    • 快速回复
      • 重启后从TBUS共享内存中继续接收消息。
  • 性能强大
    • 无锁化实现
    • 纯内存操作

通信格式

  • 关键点
    • 序列化(发送前按照一定规则进行编码格式,写成二进制流发出去)/反序列化(按照相同的规则把数据还原回原有的消息格式)
    • 版本兼容:接收方要能同时处理不同版本的消息
    • 打包解包性能一定要高
  • 解决方法
    • Protocol Buffers - Google
    • TDR - Tencent

Protocol Buffer

Screen Shot 2021-04-08 at 20.55.46

proto文件是一个xml文件,内部定义一个结构、结构体是如何表示的,通过proto文件表述,proto文件通过代码生成器转换成代码(如C++),编译后会集成到发送方的消息里面,序列化后会通过网络发送出去。接收方解码器解码后还原成原始消息。

并发模型

并发模型解决的:如何提升CPU的利用率

需要等待的:数据库、磁盘IO、RPC服务

目标:高吞吐、低延迟、开发效率

多进程模型

  • Nginx:多进程的到底模型
    • Master进程-Worker进程组
  • Java线程池
    • 应用侧不断提交任务task给任务队列:

Screen Shot 2021-04-08 at 21.09.50

协程模型

  • 特点
    • 用户级CPU调度(线程一般是操作系统决定),开发者能够控制协程之间的调度。可控力度更强一些。
    • 非抢占
    • 主动出让
    • 同步变异步

Screen Shot 2021-04-08 at 21.11.34

  • 调度算法
    • 编译器实现
    • 开发者实现
  • 代表
    • Golang - goroutine(语言层面)
    • Lua - coroutine
    • LibCo - tencent WeChat(开发者实现,开源的)

超时问题

需要的数据一直都不来的情况

服务器可能需要处理许多定时器,比如一个角色身上挂了很多倒计时(技能冷却等),当用户多了的时候,如何管理分布式系统中的定时器呢?

红黑树、转轮等方式实现

大系统小做

经典三层架构

接入层(业务接入连接管理)、逻辑层(业务逻辑)、数据层(数据存储)

分区分服的架构举例如下:

Screen Shot 2021-04-08 at 21.32.09

TGW:网关,起初为了做ip收敛,ipv4很少,腾讯业务过多,不能拿到很多ipv4地址。以及负载均衡工作。

Tonned:连接管理,tcp、udp组件,以及运维的相关轮子。

World:是一个大的主进程

Service proxy:如外部关系链等等

很多的服务不可能放在一个服务进程里面:商店、邮件、好友、抽奖、聊天等等系统,但分区分服的一些系统就是这样做的

拆分系统

为什么要拆分系统?:Bug扩散、代码相互依赖、互相影响、责任不明确、不利于协同开发、按需部署、容灾处理麻烦。

为了支撑海量用户服务,把复杂的系统拆分成各个子系统,协作完成复杂的功能。

按功能拆分:邮件、好友

按流程拆分:登录、大厅状态、匹配

按通用组件拆分:连接管理组件、路由代理组件、数据库代理组件、负载均衡组件

CODM架构

Screen Shot 2021-04-08 at 21.55.35

TProxy:代理组件,把进程通信抽象化。

ds:专用服务器

MatchMaking:匹配规则

带来的问题

  • 系统之间如何通信:Rpc?协议?
    • 如工会、好友;游戏中的好友、游戏外的好友,假设工会和好友是在一个进程里面的话,会很简单;但是如果将功能拆分后,在不同的进程时,就会有一个进程间通信的问题。
  • 如何部署?
    • 进程数量增多,多个进程是部署在一台机器还是多台机器的问题
  • 系统之间如何协作:函数调用?
  • 如何定位问题?
    • 一个流程跨多系统。线上系统不能使用gdb的时候,需要查看日志了解调用链。
  • 如何监控?
    • 系统庞大、机器众多。
    • 需要时刻监控到系统的各项能力与数据。

架构层面的技术支撑

异步处理框架

  • 网络处理
    • 网络处理与业务逻辑解耦
    • 多路异步复用
  • 状态机框架
    • 可配置/可视化
    • 自动生成代码
    • 维护成本,降低沟通难度
  • 协程
    • 降低编码难度
    • 逻辑代码更清晰

底层通讯框架

  • 功能
    • 系统功能解耦
    • 作为系统间的路由
    • 作为容灾扩容的基础
  • 特性
    • 本身无状态
    • 多进程部署,平行扩容
    • 支持多种路由策略

多种路由策略如下:

Screen Shot 2021-04-08 at 22.16.53

扩容的时候导致用户数据的迁移。

取模的系统,带强cache,减轻DB的压力这种情况,会在本机做cache,这种会做mod。

一致性哈希,的特性在于处理机器增加的时候,不会导致大量的用户数据迁移。

能用随机尽量用随机方式分配。

自动化部署框架

Screen Shot 2021-04-08 at 23.10.57

立体化监控框架

Screen Shot 2021-04-08 at 23.23.21

Screen Shot 2021-04-08 at 23.33.40

分布式系统的关键能力

  • 协同开发
    • 系统间协议通讯、不直接调用函数、系统间解耦、独立测试
    • Bug隔离、各自优化、独立快速迭代、敏捷开发
  • 平行扩容
  • 负载均衡
    • 多级负载均衡
      • 前端接入 - 热更新能力(不要把用户踢下线)
      • 大厅分配 - 随机分配
      • 房间分配和管理
  • 灰度部署
  • 容灾备份:主备部署、自动切换
  • 柔性可用:屏蔽异常服务、保证核心流程
This post is licensed under CC BY 4.0 by the author.

第四课:游戏后台开发工具

第六课:游戏人工智能

Trending Tags