一、📋 项目概述
1、背景问题
当前项目内部各种筛选项、多国内容都是依靠 cms 进行配置、然后后端读取后形成json 文件存储在s3, 还有部分配置文件未经 cms, 在修改和发布时, 经常要登录亚马逊系统,找到对应的文件下载、修改、上传, 发布到生产环境也是要先从预发复制到生产。 整个过程较多人工手动操作, 容易出现错误、又没有版本概念、不利于内容变更的追踪、另外上线的过程手工复制同步,效率也比较低下,并且缺乏审计, 不知道谁在什么时候修改了什么配置。
目前配置项的修改发布流程如下 运营(开发)修改 cms系统配置项 ------> 后端读取cms数据库生成配置文件存到 s3的命名为 预发的文件夹下 ------> 应用端预发环境调用接口读取该配置 ------> 预发验证 ------> 发布时登录AWS 将配置复制粘贴到 生产环境的文件夹下 ------> 应用端生产环境调用接口读取配置 还有些配置是单独配置的,未经过 cms 系统,配置文件的修改,更繁琐一些, 需要先下载下来, 修改后在上传进行替换, 整个过程还是比较繁琐, 随着配置和人员的增加, 不太利于管理
2、解决方案
Data Config Admin 项目实现了一个完整的配置文件管理系统, 通过 AWS S3 和 GitHub 的双向同步机制,解决以下痛点问题
- 1、运营修改cms配置,或者开发人员直接修改配置项可以同步修改的内容
- 2、预发环境提交配置信息,可以自动同步内容到 AWS S3 对应的预发环境文件夹下
- 3、预发环境通过Pull Request的形式合到 master 分支可以同步到对应的线上环境文件夹下
- 4、通过配置的形式进行管理, 监控s3上哪些文件变动推动到仓库的哪个文件下, 都由配置的方式灵活管理
二、🏗️ 系统架构
1、核心架构
arduino
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ GitHub Repo │◄──►│ Lambda Function│◄──►│ AWS S3 Bucket │
│ │ │ │ │ │
│ - staging分支 │ │ - 事件驱动 │ │ - config/ │
│ - main分支 │ │ - 双向同步 │ │ - config2/ │
│ - 版本控制 │ │ - 冲突检测 │ │ - config3/ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 本地开发环境 │ │ 监控和日志 │ │ 多环境支持 │
│ │ │ │ │ │
│ - configuration/│ │ - CloudWatch │ │ - staging │
│ - 文件管理 │ │ - 详细日志 │ │ - production │
│ - 验证工具 │ │ - 状态监控 │ │ - 独立配置 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
2、技术栈
- 后端: Node.js 18.x
- 云服务: AWS Lambda, S3, CloudWatch
- 版本控制: GitHub API
- 部署: Serverless Framework
- 监控: 自定义监控脚本
3、本地环境变量配置
bash
# AWS配置
AWS_ACCESS_KEY_ID=your_aws_access_key
AWS_SECRET_ACCESS_KEY=your_aws_secret_key
AWS_REGION=ap-southeast-2
# GitHub配置
GITHUB_TOKEN=your_github_token
GITHUB_REPO=s2265681/data-config-admin
# S3配置
S3_BUCKET=rock-service-data
三、🔧 核心功能
1、多文件管理
- 统一配置:通过
config/folders.json
统一管理所有配置文件 - 多环境支持:支持staging和production环境独立配置
- 文件分类:支持多个配置目录
js
{
"folders": [
{
"name": "config", // 文件夹名称
"description": "主要配置文件", // 文件夹描述
"local_path_staging": "app-config/config/staging", // Staging环境本地路径
"local_path_production": "app-config/config/production", // Production环境本地路径
"s3_prefix_staging": "config/staging", // Staging环境S3前缀
"s3_prefix_production": "config/production", // Production环境S3前缀
"files": [ // 监控的文件列表
{
"name": "test.json", // 文件名
"description": "主要配置文件" // 文件描述
},
{
"name": "1.json",
"description": "新增"
},
{
"name": "2.json",
"description": "新增"
},
{
"name": "test1-2.json",
"description": "测试配置文件1-2"
}
]
},
{
"name": "config2",
"description": "次要配置文件",
"local_path_staging": "app-config/config2/staging",
"local_path_production": "app-config/config2/production",
"s3_prefix_staging": "config2/staging",
"s3_prefix_production": "config2/production",
"files": [
{
"name": "test2.json",
"description": "第二个配置文件"
},
{
"name": "test3.json",
"description": "第三个配置文件"
}
]
},
{
"name": "config3",
"description": "第三方配置文件",
"local_path_staging": "app-config/config3/staging",
"local_path_production": "app-config/config3/production",
"s3_prefix_staging": "config3/staging",
"s3_prefix_production": "config3/production",
"files": [
{
"name": "test4.json",
"description": "第四个配置文件"
}
]
}
]
}
按照文件对应s3的层级关系进行设计, 在 s3 新建了三个 config 文件, 模拟多文件下的配置项管理, 对照 s3 上的文件路径, 在对应到代码仓库也进行了相同层级的对应, 比较容易找到位置,和对配置进行分类存放, 通过 local_path_staging
和 local_path_production
两个配置项代表了本地存放的路径, s3_prefix_staging
和 s3_prefix_production
在Lambda函数中验证S3路径是否在监控范围内, 未在配置内的不监管, files
代表文件夹下的哪些文件纳入监管, 未写入的不纳入监管
2、智能同步机制
- 哈希比较:通过SHA256哈希值比较文件内容,只同步变更的文件
- 循环监测: 防止GitHub S3之间的无限循环同步
- 元数据追踪:记录同步来源、时间、 方向等信息
3. 双向同步流程
GitHub → S3 同步
css
graph LR
A[本地文件变更] --> B[GitHub Push]
B --> C[GitHub Actions]
C --> D[Lambda Function]
D --> E[上传到S3]
E --> F[更新元数据]
S3 → GitHub 同步
css
graph LR
A[S3文件变更] --> B[S3事件触发]
B --> C[Lambda Function]
C --> D[检查来源]
D --> E[避免循环同步]
E --> F[更新GitHub] commit 记录哪个文件变更了
4. 环境隔离
js
- **Staging环境**: 使用staging分支,S3路径为 `config/staging/`支持通过 filter 文件同时配置多个s3路径
- **Production环境**: 使用main分支,S3路径为 `config/production/`支持通过 filter 文件同时配置多个s3路径
- **独立配置**: 每个环境有独立的配置路径和分支
5. 监控和日志
- 实时监控 :
monitor-multi.js
脚本提供实时同步状态监控 - 详细日志: 记录所有同步操作的详细信息
- 错误处理: 完善的错误处理和重试机制
js
# 监控同步状态
npm run monitor
# 查看Lambda日志
serverless logs -f s3ToGithubSync --tail
四、📊 项目结构分析
csharp
data-config-admin/
├── 📁 .github/ # GitHub 相关配置
│ └── 📁 workflows/ # GitHub Actions 工作流
│ ├── 📄 github-to-s3-staging-sync.yml # Staging环境同步工作流
│ └── 📄 github-to-s3-production-sync.yml # Production环境同步工作流
│
├── 📁 .serverless/ # Serverless Framework 部署缓存
│
├── 📁 app-config/ # 应用程序配置文件目录
│ ├── 📁 config/ # 主要配置文件
│ │ ├── 📁 staging/ # Staging环境配置
│ │ │ ├── 📄 test.json # 主要配置文件
│ │ │ ├── 📄 1.json # 新增配置文件
│ │ │ ├── 📄 2.json # 新增配置文件
│ │ │ └── 📄 test1-2.json # 测试配置文件1-2
│ │ └── 📁 production/ # Production环境配置
│ │ ├── 📄 test.json # 主要配置文件
│ │ ├── 📄 1.json # 新增配置文件
│ │ ├── 📄 2.json # 新增配置文件
│ │ └── 📄 test1-2.json # 测试配置文件1-2
│ ├── 📁 config2/ # 次要配置文件
│ │ ├── 📁 staging/ # Staging环境配置
│ │ │ ├── 📄 test2.json # 第二个配置文件
│ │ │ └── 📄 test3.json # 第三个配置文件
│ │ └── 📁 production/ # Production环境配置
│ │ ├── 📄 test2.json # 第二个配置文件
│ │ └── 📄 test3.json # 第三个配置文件
│ └── 📁 config3/ # 第三方配置文件
│ ├── 📁 staging/ # Staging环境配置
│ │ └── 📄 test4.json # 第四个配置文件
│ └── 📁 production/ # Production环境配置
│ └── 📄 test4.json # 第四个配置文件
│
├── 📁 config/ # 项目配置目录
│ ├── 📄 folders.json # 文件夹管理配置文件(核心配置)
│ └── 📄 README.md # 配置说明文档
│
├── 📁 handlers/ # AWS Lambda 函数处理器
│ ├── 📄 s3-to-github.js # S3到GitHub同步处理器(主要)
│ └── 📄 s3-to-github-production.js # S3到GitHub同步处理器(生产环境专用)
│
├── 📁 node_modules/ # Node.js 依赖包
│
├── 📁 plugins/ # Serverless Framework 插件
│ └── 📄 dynamic-s3-events.js # 动态S3事件配置插件
│
├── 📁 scripts/ # 管理脚本目录
│ ├── 📄 deploy.js # 部署脚本(带配置验证)
│ ├── 📄 manage-folders.js # 文件夹管理脚本
│ ├── 📄 migrate-to-folders.js # 迁移到文件夹结构脚本
│ ├── 📄 monitor-folders-sync.js # 监控文件夹同步状态脚本
│ ├── 📄 pull-from-s3.js # 从S3拉取文件到GitHub脚本
│ ├── 📄 sync-folders-to-s3.js # 同步文件夹到S3脚本
│ └── 📄 update-lambda.js # 更新Lambda函数脚本
│
├── 📁 test/ # 测试文件目录
│ └── 📄 sync.test.js # 同步功能测试文件
│
├── 📁 utils/ # 工具类目录
│ ├── 📄 folder-manager.js # 文件夹管理器(核心工具类)
│ └── 📄 generate-s3-arns.js # S3 ARN生成器
│
├── 📄 .DS_Store # macOS系统文件
├── 📄 .gitignore # Git忽略文件配置
├── 📄 deploy.sh # 部署Shell脚本
├── 📄 env.example # 环境变量示例文件
├── 📄 FOLDER_MANAGEMENT.md # 文件夹管理说明文档
├── 📄 package-lock.json # npm依赖锁定文件
├── 📄 package.json # 项目配置和依赖管理
├── 📄 README.md # 项目主要说明文档
├── 📄 response.json # 响应示例文件
├── 📄 SCRIPTS_USAGE.md # 脚本使用说明文档
├── 📄 serverless.yml # Serverless Framework 配置文件
├── 📄 SETUP.md # 项目设置说明文档
└── 📄 技术文档.md # 技术实现文档
1. Lambda 函数处理器 (handlers/
)
s3-to-github.js
- 主要同步处理器
- 功能: 处理S3文件变更事件,同步到GitHub
- 触发条件: S3文件创建、修改、删除事件
- 处理流程 :
- 验证S3路径是否在监控范围内
- 提取文件信息和文件夹配置
- 根据环境确定GitHub目标路径
- 执行GitHub文件同步操作
s3-to-github-production.js
- 生产环境专用处理器
- 功能: 专门处理生产环境的S3到GitHub同步
- 特点: 只处理production环境的文件变更
- 安全措施: 额外的生产环境验证
2. 工具类 (utils/
)
folder-manager.js
- 文件夹管理器
- 功能: 核心配置管理工具类
- 主要方法 :
getFolders()
: 获取所有文件夹配置validateFoldersConfig()
: 验证配置有效性fileExists()
: 检查文件是否存在getFileHash()
: 获取文件哈希值readFile()
: 读取文件内容
generate-s3-arns.js
- S3 ARN生成器
- 功能: 根据文件夹配置动态生成S3权限ARN
- 用途: 为Lambda函数生成精确的S3访问权限
3. 管理脚本 (scripts/
)
deploy.js
- 部署脚本
- 功能: 带配置验证的完整部署
- 流程: 验证配置 → 显示部署信息 → 执行Serverless部署
sync-folders-to-s3.js
- 同步到S3脚本
- 功能: 将本地文件夹同步到S3
- 特点: 智能同步,只同步变更的文件
pull-from-s3.js
- 从S3拉取脚本
- 功能: 从S3拉取文件到GitHub仓库
- 用途: 恢复或同步S3中的配置文件
monitor-folders-sync.js
- 监控脚本
- 功能: 监控本地、S3、GitHub三方的文件同步状态
- 输出: 详细的同步状态报告
manage-folders.js
- 文件夹管理脚本
- 功能: 管理文件夹配置的增删改查
- 命令: 验证、添加、删除、列出文件夹配置
4. Serverless 插件 (plugins/
)
dynamic-s3-events.js
- 动态S3事件插件
- 功能: 根据文件夹配置动态生成S3事件规则
- 触发时机: 部署前自动生成事件配置
- 优势: 避免手动配置S3事件,减少配置错误
5. GitHub Actions 工作流 (.github/workflows/
)
github-to-s3-staging-sync.yml
- Staging环境同步
- 触发条件: staging分支的app-config/**或config/folders.json变更
- 功能: 自动同步staging环境配置到S3
github-to-s3-production-sync.yml
- Production环境同步
- 触发条件: main分支的app-config/**或config/folders.json变更
- 功能: 自动同步production环境配置到S3
五、🚀 使用流程 快速部署
1. 克隆仓库
bash
git clone https://github.com/s2265681/data-config-admin.git
cd data-config-admin
2. 配置环境变量
bash
cp env.example .env
编辑 .env
文件,填入你的配置:
env
AWS_REGION=ap-southeast-2
AWS_ACCESS_KEY_ID=your_aws_access_key_id
AWS_SECRET_ACCESS_KEY=your_aws_secret_access_key
GITHUB_TOKEN=your_github_personal_access_token
GITHUB_REPO=s2265681/data-config-admin
S3_BUCKET=rock-service-data
3. 一键部署
bash
./deploy.sh
4. 配置GitHub Secrets
在GitHub仓库设置 → Secrets and variables → Actions 中添加:
AWS_ACCESS_KEY_ID
: 你的AWS访问密钥IDAWS_SECRET_ACCESS_KEY
: 你的AWS访问密钥GITHUB_TOKEN
: GitHub个人访问令牌(自动提供)
5. 测试同步
测试S3 → GitHub同步
bash
# 上传文件到S3
aws s3 cp test.json s3://rock-service-data/config/staging/test.json
测试GitHub → S3同步
bash
# 修改test.json文件
echo '{"test": "data"}' > test.json
git add test.json
git commit -m "测试同步"
git push origin staging
🔧 手动部署步骤
如果自动部署失败,可以按以下步骤手动部署:
1. 安装依赖
bash
npm install
npm install -g serverless
2. 部署Lambda函数
bash
serverless deploy
3. 创建staging分支
bash
git checkout -b staging
git push -u origin staging
git checkout main
📋 权限要求
AWS权限
json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::rock-service-data",
"arn:aws:s3:::rock-service-data/*"
]
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
GitHub权限
repo
权限(完整仓库访问)- 或者
public_repo
权限(如果是公开仓库)
🧪 验证部署
1. 检查Lambda函数
bash
serverless info
2. 监控同步状态
bash
npm run monitor
3. 查看日志
bash
# Lambda日志
serverless logs -f s3ToGithubSync --tail
# GitHub Actions日志
# 访问 https://github.com/s2265681/data-config-admin/actions