Skip to content

Lirous587/live-interact-engine

Repository files navigation

live-interact-engine

一个微服务架构的直播后端系统,包含用户管理、房间管理、弹幕推送、礼物打赏等功能模块。

通过分布式设计研究系统在高并发、强一致性场景下的问题和解决方案。

项目概述

本项目采用微服务架构,包含 5 个核心服务1 个共享库

服务 端口 职责
api-service 8080 HTTP 网关,请求路由聚合
user-service 9094 用户鉴权、账户管理
room-service 9095 房间创建、用户角色管理
gift-service 9096 礼物/打赏业务、钱包管理、交易记录
danmaku-service 9093 弹幕实时推送、WebSocket 连接管理

技术架构图

┌─────────────────────────────────────────────────────────┐
│         HTTP 客户端 (Web / Mobile)                       │
└────────────────┬────────────────────────────────────────┘
                 │
        ┌────────▼────────┐
        │  API Service    │  (HTTP 入口点)
        │    :8080        │
        └────────┬────────┘
                 │
     ┌───────────┼───────────┬─────────────┐
     │           │           │             │
  ┌──▼──┐  ┌─────▼──┐  ┌────▼────┐  ┌────▼────┐
  │User │  │ Room   │  │  Gift   │  │Danmaku  │
  │:9094│  │ :9095  │  │ :9096   │  │ :9093   │
  └─────┘  └────────┘  └─────────┘  └─────────┘
     │         │           │             │
     └─────────┼───────────┼─────────────┘
               │           │
         ┌─────▼───────────▼──────┐
         │  PostgreSQL (Database) │
         └────────────────────────┘

         ┌─────────────────────────┐
         │  Redis (Cache)          │
         ├─────────────────────────┤
         │  RabbitMQ (EventBus)    │
         └─────────────────────────┘

核心服务说明

1. API Service (HTTP 网关)

  • 统一的 HTTP 入口点
  • 路由转发至各微服务的 gRPC 接口
  • 请求验证、错误处理、响应聚合

2. User Service (用户服务)

  • 用户注册、登录、认证
  • Token 生成和验证 (JWT)
  • 用户信息管理

3. Room Service (房间服务)

  • 房间的创建与管理
  • 用户房间角色控制
  • 房间状态维护

4. Gift Service (礼物/打赏服务)

  • 核心业务:礼物定义、用户充值、礼物打赏
  • 钱包管理:用户余额存储、交易记录持久化
  • 并发控制:处理高并发的打赏场景

5. Danmaku Service (弹幕服务)

  • WebSocket 长连接管理
  • 实时消息广播
  • 房间级别的连接池管理

Shared (共享库)

  • 错误码统一定义
  • 日志工具、加密工具
  • JWT 认证模块
  • gRPC Protocol Buffer 定义
  • 可观测性工具 (追踪、指标)

技术栈

分类 技术
编程语言 Go 1.22+
Web 框架 Gin (HTTP), gRPC (RPC)
数据库 PostgreSQL
缓存 Redis
消息队列 RabbitMQ
实时通信 WebSocket
ORM Ent Framework
日志 Uber Zap

项目结构

live-interact-engine/
├── api/                       # API 文档
├── build/                     # 编译产物
├── docs/                      # 文档
├── infra/                     # 基础设施配置
│   ├── development/           # 开发环境配置
│   ├── postgres/              # 数据库初始化脚本
│   └── production/            # 生产环境配置
├── proto/                     # Protocol Buffer 定义
├── services/                  # 微服务目录
│   ├── api-service/           # HTTP 网关
│   ├── danmaku-service/       # 弹幕服务
│   ├── gift-service/          # 打赏/钱包服务
│   ├── room-service/          # 房间服务
│   └── user-service/          # 用户服务
├── shared/                    # 共享库
│   ├── crypto/                # 加密工具
│   ├── env/                   # 环境变量
│   ├── jwt/                   # JWT 认证
│   ├── logger/                # 日志工具
│   ├── proto/                 # gRPC Protocol Buffer
│   ├── svcerr/                # 错误处理
│   └── telemetry/             # 链路追踪、指标
├── docker-compose.yml         # 本地开发环境
├── Dockerfile*                # 服务容器镜像
└── Makefile                   # 构建脚本

核心设计亮点

Gift Service 高并发场景下的强一致性设计

Gift Service 是整个系统中最复杂的部分,需要在高并发场景下保证用户钱包余额的绝对准确,零资金丢失。为此采用了多层递进的并发控制策略:

1. 客户端扣款 - Redis Lua 脚本原子性

用户发送礼物时,需要从 Redis 中原子地扣减余额:

问题:普通 Redis 命令无法保证原子性,分布式环境下容易出现竞态条件

解决方案:使用 Redis Lua 脚本在单个原子操作中完成:

  • 检查余额是否充足
  • 扣减余额
  • 记录幂等性密钥(防止重复扣款)

效果:单个用户在同一时刻发起多次打赏操作,余额扣减绝对正确,不会超支

2. 消费事件处理 - 交易流水表 + 幂等性防重

RabbitMQ 消费消息时可能因网络或处理过程中出现重试,导致同一条消息被处理多次:

问题:消息重复消费会导致余额被重复加减,造成数据混乱

解决方案

  • 统一的 wallet_transaction 流水表记录每笔交易
  • 每条消息使用唯一的 idempotency_key(幂等性密钥)
  • 流水表对 idempotency_key 设置唯一约束
  • 重复消息到达时会触发约束冲突,自动去重

效果:即使消息被投递多次,流水表也只会保存一条记录,余额只会更新一次

3. 并发更新 - PostgreSQL 乐观锁 + 版本号

消费者在处理事件时需要更新用户钱包余额,多个消费者可能同时处理同一用户的多条事件:

问题:普通 UPDATE 会导致后来的更新覆盖前面的更新,导致余额错误

解决方案

  • 钱包表添加 version_number 字段
  • 每次更新时检查版本号是否匹配
  • 版本号不匹配说明有其他消费者已更新,立即返回冲突错误
  • 收到冲突错误后,使用指数退避重试(50ms × 2^n,最多10次)重新读取最新余额再尝试

效果:并发消费多条事件时,每条事件都能准确更新余额,不会丢失任何一次更新

4. 消息顺序保证 - RabbitMQ QoS + 单线程消费

为了减少并发冲突的概率,采用保序策略:

设置:RabbitMQ QoS=1,单个消费者一次只处理一条消息,处理完毕才 ACK 确认

效果:同一用户的消息按顺序处理,减少版本冲突频率

5. 数据库事务保证 - 原子执行

流水表插入和钱包余额更新在同一数据库事务内执行:

  • 开启事务 → 插入流水 → 更新钱包 → 提交
  • 任何步骤失败都回滚,保证原子性
  • 使用 domain.Tx 接口解耦 ORM 框架

效果:流水记录与余额始终保持一致

综合效果

这五层递进的并发控制策略共同作用,实现了:

场景 保证机制
单用户多次打赏 Redis Lua 原子操作
消息重复投递 幂等性密钥 + 唯一约束
多消费者并发更新 版本号乐观锁 + 指数退避重试
流水记录与余额不一致 数据库事务
消息丢失或顺序错乱 RabbitMQ QoS 保序

性能基准

测试工具:k6 · 测试脚本:test/ · 环境:Docker Compose,宿主机 2 CPU

弹幕服务

指标 数值
并发 WebSocket 连接 1000
弹幕接收吞吐 30,597 条/秒
WebSocket 错误率 0.00%
连接建立 p(95) 97ms
所有会话完整生命周期 ✓ 无提前断开

礼物打赏服务(单主播场景)

指标 优化前 优化后
稳定吞吐 348 RPS 1097 RPS (+215%)
p(95) 延迟 2.24s 593ms (-73%)
错误率 2.11% 0.00%
max 延迟 10.55s 1.09s

瓶颈分析:单主播场景下所有观众的 Redis Lua 扣款串行排队,是当前 2 CPU Docker 环境下的核心瓶颈。真实生产 4~8 核独立部署预计还有 3~5x 提升空间。 详细报告见 test/STRESS_TEST_REPORT.md


架构设计原则

分层架构

每个服务遵循四层架构

  • Domain Layer: 业务域模型和接口定义
  • Service Layer: 业务逻辑实现
  • Infrastructure Layer: 外部依赖实现 (数据库、消息队列、gRPC)
  • Handler/Adapter Layer: HTTP/gRPC 请求处理

通信方式

  • 服务间: gRPC (同步)
  • 事件通知: RabbitMQ (异步)
  • 客户端: HTTP

数据存储

  • 持久化: PostgreSQL
  • 缓存: Redis

快速开始

环境要求

  • Go 1.22+
  • Docker & Docker Compose
  • PostgreSQL 15+
  • Redis 7+
  • RabbitMQ 3.12+

本地开发

# 编译 + 构建镜像 + 启动所有服务
make rebuild

# 初始化礼物数据(首次启动后执行)
make seed-gifts

常用命令

make up            # 启动所有服务
make down          # 停止所有服务
make rebuild       # 重新构建并启动
make seed-gifts    # 初始化礼物 seed 数据
make logs          # 查看 api-service 日志
make clean         # 完全清理(含数据卷)

可观测性

服务 地址
API http://localhost:8080
Swagger 文档 http://localhost:8080/swagger/index.html
Jaeger 链路追踪 http://localhost:16686
Prometheus 指标 http://localhost:9091
Grafana 面板 http://localhost:3000
RabbitMQ 管理 http://localhost:15672

压力测试

# 礼物打赏压测
k6 run -e BASE_URL=http://localhost:8080 test/gift_stress_test.js

# 弹幕服务压测
k6 run -e BASE_URL=http://localhost:8080 test/danmaku_stress_test.js

部署

Docker Compose

make rebuild

Kubernetes

参考 infra/production/k8s/ 目录的配置文件。



贡献指南

提交 PR 时请确保:

  1. 代码风格符合项目规范
  2. 新增功能附带单元测试
  3. Commit 消息清晰(Conventional Commits)

许可证

MIT License

Copyright (c) 2026 lirous587

About

一个具备实时弹幕广播与强一致性礼物结算的高并发直播后端引擎

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors