Skip to content

角色与启动流程

Vistack 采用「单二进制 + 多角色」架构:cmd/vistack 编译出一个二进制,启动时按 VISTACK_ROLE(或首个位置参数)分发到不同角色的启动引导。

bash
# 角色解析逻辑(cmd/vistack/main.go)
VISTACK_ROLE 环境变量 > 首个非 flag 位置参数 > 默认 api

角色一览

角色启动函数依赖职责
apirole.RunAPIDB + Redis + MinIO + KafkaHTTP 服务:视频/文件/弹幕/评论/互动;投递 Kafka 消息
workerrole.RunWorkerDB + Redis + MinIO + Kafka + etcdKafka 消费:转码编排、删除文件、弹幕/评论落库、重试 + watchdog
transcoderrole.RunTranscoderMinIO + etcdgRPC 转码服务(FFmpeg),不连 DB / Redis / Kafka
authrole.RunAuthDB + MinIO + etcdHTTP 认证 + gRPC 用户查询 + JWKS
migraterole.RunMigrateDB执行 GORM 自动迁移后退出

api 角色(RunAPI)

启动流程:

  1. 初始化 DB / MinIO / Redis / 缓存层 / Snowflake;
  2. 创建 JWKS 验签器authpkg.NewTokenVerifier)并每小时自动刷新——不持私钥、不回调 auth,本地无状态验签;
  3. 创建 auth 用户查询客户端(gRPC,经 etcd 发现);
  4. 初始化 Kafka,确保弹幕 topic 存在;
  5. 异步构建视频布隆过滤器(best-effort);
  6. 初始化限流器(按配置选令牌桶或滑动窗口);
  7. 按开关启动 互动服务(点赞/收藏/播放量 + Flusher)、弹幕服务(敏感词加载)、评论服务(敏感词 + Flusher);
  8. 注册路由与中间件(auth / cors / requestid / ratelimit);
  9. http.Server + 信号感知优雅停机(30s 排空在途请求)。

worker 角色(RunWorker)

启动流程:

  1. 初始化 DB / MinIO / Redis / Snowflake / Kafka;
  2. 创建 transcoder gRPC 客户端transcoder.NewClient:etcd 发现或静态兜底地址);
  3. 启动常规消费者(并发消费):
    • StartTranscodeWorker(转码编排)
    • StartVideoDeleteWorker(文件删除)
    • StartDanmakuWorker(弹幕落库)
    • StartCommentModerationWorker(评论落库)
  4. 启动 单例任务runSingletonJobs):
    • etcd 可用 → 领导选举,仅 leader 运行 retry dispatcher + watchdog;
    • etcd 不可用 → 降级直接运行(仅限单实例,记录告警);
  5. 信号感知优雅停机:停止消费 → 排空在途任务(30s 上限)。

transcoder 角色(RunTranscoder)

启动流程极简——只初始化 MinIO 客户端,不连 DB / Redis / Kafka

  1. 初始化 MinIO;
  2. 启动 gRPC 服务(ProcessVideo);
  3. 向 etcd 注册(租约 TTL 10s、每 3s 保活),实现服务发现。

无状态设计使其可以任意扩容:新增副本自动注册,worker 自动发现并分担任务。

auth 角色(RunAuth)

启动流程:

  1. 初始化 DB / MinIO;
  2. 加载 RSA 私钥:VISTACK_AUTH_RSA_PRIVATE_KEY(PEM)> VISTACK_AUTH_RSA_PRIVATE_KEY_FILE > 生成临时密钥(仅开发);
  3. 创建 TokenManager(RS256 签发 / 验签);
  4. 启动 gRPC 服务UserService:用户查询),并注册到 etcd(供 api 发现);
  5. 启动 HTTP 服务:8081):注册 / 登录 / 资料 / JWKS;
  6. 优雅停机:HTTP Shutdown + gRPC GracefulStop。

依赖隔离的意义

  • transcoder 不连 DB:转码任务最重,DB 故障不影响转码执行(结果写库由 worker 完成);
  • api 不持私钥:认证密钥只存在于 auth 服务,api 仅通过 JWKS 本地验签,降低私钥泄露面;
  • worker 持有全部数据访问:编排中枢,负责状态机推进与幂等。

基于 MIT License 发布