如何用单一代码库打造多应用平台
2 分钟阅读Mohammad Shaker

如何用单一代码库打造多应用平台

Alphazed通过共享Flutter框架和单一后端代码库,运营7款以上阿拉伯语儿童教育应用,实现独立数据和个性化配置。

Engineering

快速解答

Alphazed通过共享Flutter框架和单一后端代码库,运营7款以上阿拉伯语儿童教育应用,实现独立数据和个性化配置。

Alphazed通过共享Flutter移动框架和单一后端代码库,运营包括Amal、Thurayya、Qais、KidElite、Alphazed School、Alphazed Montessori等7款以上教育应用。每款应用拥有独立的数据库表(带前缀)、配置、推送通知、邮件模板和内容,但共享AWS Cognito身份验证、分析基础设施和核心学习算法。

后端:运行时应用选择

工作原理

部署时,通过环境变量确定应用:

# 部署Amal
export APP_NAME=amal
serverless deploy

部署Thurayya

export APP_NAME=thurayya serverless deploy

部署Qais

export APP_NAME=qais serverless deploy

每次部署都会生成独立Lambda函数、API Gateway路由及监控,但都连接同一后端代码库。

三层配置优先级

# src/config.py
import os

app_name = os.getenv('APP_NAME', 'amal')

第一层:精准匹配

config = load_json(f'config/{app_name}.json')

第二层:应用族匹配(若无精准配置)

if not config: family = app_name.split('_')[0] # 'amal_beta' → 'amal' config = load_json(f'config/{family}.json')

第三层:默认配置

if not config: config = load_json('config/default.json')

分应用配置示例(config/amal.json)

{
  "app_name": "amal",
  "app_id": "com.alphazed.amal",
  "database": {
    "table_prefix": "amal_"
  },
  "email": {
    "template_dir": "templates/amal",
    "from_address": "amal@alphazed.com",
    "from_name": "Amal Team"
  },
  "push_notifications": {
    "firebase_project": "alphazed-amal",
    "apns_certificate": "certs/amal.pem"
  },
  "content": {
    "s3_bucket": "amal-content-production",
    "curriculum_id": "amal_v3_arabic"
  },
  "feature_flags": {
    "enable_tajweed_feedback": false,
    "enable_noorani_qaida": false,
    "enable_juz_amma": false,
    "enable_creature_building": true,
    "enable_physics_games": true
  },
  "pricing": {
    "monthly_usd": 6.99,
    "yearly_usd": 67.99,
    "trial_days": 14
  }
}

共享与分应用资源对比

资源共享分应用原因
Lambda代码✓ 是✗ 否单代码库,分支取决于APP_NAME
RDS实例✓ 是✗ 否(表前缀区分)降低成本,统一备份
S3内容✗ 否✓ 是每个应用的课程内容不同
AWS Cognito✓ 是✗ 否(通过app_id区分)集中身份认证,用app_id区分应用
分析数据湖✓ 是✗ 否(通过应用分区)统一数据管道,数据隔离
Firebase消息通知✗ 否✓ 是应用专属APNs和FCM配置

前端:Flutter多应用架构

共享核心(packages/alphazed_common)

  • 状态管理(Riverpod)
  • 音频处理
  • 动画库(集成Rive)
  • 设计系统(色彩、字体、小部件)
  • 身份验证流程
  • 分析客户端

应用专属层(apps/amal,apps/thurayya等)

apps/
  ├── amal/
  │   ├── lib/
  │   │   ├── main.dart(应用入口)
  │   │   ├── config/
  │   │   │   ├── curriculum.json(Amal课程结构)
  │   │   │   ├── colors.dart(Amal主题色)
  │   │   │   └── characters.json(头像定制)
  │   │   └── screens/(Amal独有界面)
  │   └── pubspec.yaml(依赖)
  │
  ├── thurayya/
  │   ├── lib/
  │   │   ├── main.dart(不同入口)
  │   │   ├── config/
  │   │   │   ├── curriculum.json(Juz Amma课程结构)
  │   │   │   ├── colors.dart(Thurayya主题色)
  │   │   │   └── characters.json(头像定制)
  │   │   └── screens/(Thurayya独有界面)
  │   └── pubspec.yaml(依赖)
  │
  └── packages/
      └── alphazed_common/(共享代码)

构建时配置

# 构建Amal
flutter build apk --dart-define=APP_NAME=amal --dart-define=CURRICULUM=amal_v3

构建Thurayya

flutter build apk --dart-define=APP_NAME=thurayya --dart-define=CURRICULUM=thurayya_juzamma

构建时为每款应用内嵌各自课程数据、主题颜色和配置信息。单代码库,多编译产物。

部署:独立堆栈

Serverless框架配置

# serverless.yml
service: alphazed-backend

custom: pythonRequirements: dockerizePip: true app_name: ${env:APP_NAME}

functions:

针对每个APP_NAME部署下述函数

get_user: handler: src/handlers/user.get_user events: - http: path: app/{app_name}/user/{user_id} method: get

content_duo: handler: src/handlers/content.generate_content_duo timeout: 20 events: - http: path: app/{app_name}/content_duo method: post

resources: Resources: # 每个应用独有CloudWatch日志组 ${self:custom.app_name}LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: /aws/lambda/alphazed-${self:custom.app_name} RetentionInDays: 30

使用APP_NAME=amal部署,CloudFormation将创建:

  • 带“alphazed-amal-”前缀的Lambda函数
  • /amal/*路径下的API Gateway路由
  • /aws/lambda/alphazed-amal的CloudWatch日志组
  • 独立的自动扩缩和监控

意义所在

对产品团队

  • 新应用上线缩短至数周,节省基础设施搭建时间
  • 功能一致性保障,缺陷修复与算法更新即时生效所有应用
  • A/B测试便捷,先在单一应用试验新功能再推广

对工程团队

  • 单一代码库,统一测试与CI/CD流程
  • 共享学习算法,间隔重复和内容混合策略惠及所有应用
  • 运维高效,单队伍管理全部基础设施

对成本

  • 共享RDS数据库,成本低于7个独立数据库
  • 共享Cognito身份认证,统一账号体系
  • 共享分析流水线,整合7款应用数据
  • 预估节省成本每年4万至6万美元

挑战与解决方案

挑战1:数据库模式冲突

  • Amal需要amal_user_memory
  • Thurayya需要thurayya_user_memory表(字段不同用于古兰经背诵)
  • 解决方案:迁移脚本仅对当前APP_NAME执行,比如migrations/001_amal_user_memory.sql只在APP_NAME=amal时执行

挑战2:不同功能集

  • Thurayya有tajweed朗读反馈,Amal无
  • Amal有物理游戏,Thurayya无
  • 解决方案:通过配置中的功能开关控制,如enable_tajweed_feedbackenable_physics_games

挑战3:独立弹性伸缩

  • Amal流量高峰,Thurayya相对空闲
  • 共享Lambda资源池会竞争并发
  • 解决方案:为每款应用设置CloudWatch自动扩缩策略,发生并发瓶颈时独立伸缩

常见问题

问:共享单一代码库不会导致应用耦合吗?
答:不会。每个应用代码目录分离(如apps/amalapps/thurayya),共享代码集中在packages/alphazed_common并严格版本控制。紧耦合是设计臭味,我们在代码审查中避免。

问:如果某应用需要破坏性API更改怎么办?
答:我们按应用版本管理API路径,如/amal/v1/*/thurayya/v1/*,应用可独立升级,旧版本支持12个月,给予迁移时间。

问:应用间可以共享用户吗?
答:默认不能。每个应用都有自己独立的用户表(带前缀)。如果家长需要同时订阅Amal和Thurayya,需要分别注册账户,未来可能支持“家庭”账号关联功能。

相关文章