Press "Enter" to skip to content

Go 语言高并发框架演变 – 第一章

今天跟大家分享一下使用 GO 语言编写「高并发」架构的几次迭代过程和设计思路,同时也算对 Go 语言架构的一次总结。

先说一下项目背景,项目是在线教育行业,一直以来使用 PHP 作为后台主要开发语言,在业务高速发展过程中经历了多轮迭代,但是目前依然存在几个比较严重的问题:

  1. 在线教育最复杂的场景就是互动,这通常意味着业务复杂。为了满足互动场景,代码中充斥着着大量的 Hardcode。这样的后果是项目代码极其复杂,且不易维护。
  2. 在线互动带来的另一个难点是「高并发和实时计算」。老师发起互动,学生会在很短时间内完成作答(高并发),系统需要快速响应并且做出正误评判,高峰时期有近几十万用户同时在线,近十万人同时进行并发互动,PHP 为主的后台业务很难满足高并发和实时计算。

基于以上原因,准备将项目进行重构:

  1. 采用 Go 语言作为后端语言,Go 语言在高并发上比 PHP 有优势,且从 PHP 转到 Go 语言相对不是很难。
  2. 使用高并发缓存服务,通过多级存储架构,提高业务的吞吐量。
  3. 业务上通过「提前预热」的方式,将数据提前加载到缓存,减少业务进行时对数据库的压力。

分层设计

新的业务架构采用分层设计,把用户的每一次操作,提交到「前台」和「后台」,每一层做完处理后交由下层处理,这样设计的好处是明确业务边界,收敛业务逻辑,同时提高业务并发。

  • App 层:用户的 UI 层,提供数据展现和交互逻辑。
  • 前台:接收「App 层」提交的数据,进行简单的参数校验,根据业务读取配置项,最后将数据提交到「后台」进行逻辑处理,最终将「后台」的返回值返给「App 层」。
  • 后台:接收「前台」提交过来的数据,进行业务逻辑处理,并将处理结果返回给「前台」。

分层的目的是为了减轻「前台」的压力,同时将业务逻辑收敛到「后台」,「前台」依然采用 PHP 开发的接口,一方面 PHP 可以很方便的做限流,另一方面「前台」可以较小的改动实现原有接口,同时利用 PHP 脚本语言易于部署升级的特点做一些配置管理。「后台」收敛所有的业务逻辑,这样我们只需要好好设计「后台」来提高整体的吞吐量,达到我们优化的目的。由于前后台承接的功能不同,总结一句话:前台越做越薄,后台越做越厚。

后台架构设计

后台是本次重构的重点,为了实现「高并发+实时计算」,我们将「后台」业务分成了两部分 Server 端和 Client 端,Client 端支持高并发的「前台」业务的,同时调用 Server 端进行「实时计算」,具体的架构如下:

后台系统以 A 代称,图中黑框部分就是 A 系统的核心内容,包括 Client 端、Server 端、本地存储、MQ、Stored 等服务。

  1. A 系统分为 A Client 和 A Server,它们之间通过 GRPC 服务通信。
  2. Client 端主要负责缓存读写和业务处理,当需要「实时计算」等业务时,通过 GRPC 交由 Server 端处理。
  3. Client 端使用 go-cache 本地存储,主要存储那些在一次课程中不怎么变化的数据,比如课程信息,教师信息等。
  4. Client 端和 Server 端都使用 Stored 作为缓存服务,我们可以把 Stored 理解为 Redis 的替代服务,提供更高并发的吞吐。
  5. 为了减少从 PHP 请求 Go 的耗时,在每个 PHP 业务存在的节点上同时部署了 A Client 服务,这样 HTTP 调用都走本机。

结论

以上就是我们本次重构的架构设计,本次重构的目的是为了提高业务的吞吐量和实时计算能力,基于此我们采用了「分层架构」设计,将业务逻辑收敛到「后台」,同时做薄「前台」。

在下一章节中,我将根据今天的「系统架构」进行代码架构设计,并详细阐述第一版代码架构的逻辑,大家敬请期待!

Be First to Comment

发表评论

电子邮件地址不会被公开。 必填项已用*标注