45 KiB
45 KiB
解班客后端架构文档
1. 后端架构概述
1.1 架构目标
- 高性能:支持高并发访问和快速响应
- 高可用:99.9%以上的服务可用性
- 可扩展:支持业务快速发展和功能扩展
- 安全性:全方位的安全防护机制
- 可维护:清晰的代码结构和完善的文档
1.2 技术选型
| 技术栈 | 版本 | 选型理由 |
|---|---|---|
| Node.js | 18+ LTS | 高性能、生态丰富、开发效率高 |
| Express.js | 4.x | 成熟的Web框架,中间件丰富 |
| TypeScript | 5.x | 类型安全,提高代码质量 |
| MySQL | 8.0+ | 成熟稳定的关系型数据库 |
| Redis | 7.x | 高性能缓存和会话存储 |
| MongoDB | 6.x | 灵活的文档型数据库 |
| RabbitMQ | 3.11+ | 可靠的消息队列 |
| Elasticsearch | 8.x | 强大的搜索和分析引擎 |
1.3 架构原则
- 单一职责:每个服务专注于特定的业务领域
- 松耦合:服务间通过标准接口通信
- 高内聚:相关功能聚合在同一服务内
- 无状态:服务设计为无状态,支持水平扩展
- 容错性:具备故障隔离和自动恢复能力
2. 系统架构设计
2.1 整体架构图
graph TB
subgraph "客户端"
A1[微信小程序]
A2[管理后台]
A3[官方网站]
end
subgraph "网关层"
B1[API Gateway]
B2[Load Balancer]
end
subgraph "业务服务层"
C1[用户服务<br/>User Service]
C2[活动服务<br/>Activity Service]
C3[认领服务<br/>Adoption Service]
C4[支付服务<br/>Payment Service]
C5[消息服务<br/>Message Service]
C6[文件服务<br/>File Service]
C7[管理服务<br/>Admin Service]
C8[通知服务<br/>Notification Service]
end
subgraph "数据层"
D1[MySQL<br/>主数据库]
D2[MySQL<br/>从数据库]
D3[Redis<br/>缓存集群]
D4[MongoDB<br/>文档数据库]
D5[Elasticsearch<br/>搜索引擎]
end
subgraph "消息队列"
E1[RabbitMQ<br/>消息队列]
end
subgraph "第三方服务"
F1[微信API]
F2[支付接口]
F3[短信服务]
F4[对象存储]
end
A1 --> B1
A2 --> B1
A3 --> B1
B1 --> B2
B2 --> C1
B2 --> C2
B2 --> C3
B2 --> C4
B2 --> C5
B2 --> C6
B2 --> C7
B2 --> C8
C1 --> D1
C2 --> D1
C3 --> D1
C4 --> D1
C7 --> D1
C1 --> D2
C2 --> D2
C3 --> D2
C4 --> D2
C7 --> D2
C1 --> D3
C2 --> D3
C3 --> D3
C4 --> D3
C5 --> D3
C8 --> D3
C6 --> D4
C2 --> D5
C3 --> D5
C2 --> E1
C3 --> E1
C4 --> E1
C5 --> E1
C8 --> E1
C1 --> F1
C4 --> F2
C8 --> F3
C6 --> F4
2.2 服务分层架构
graph TB
subgraph "表现层 Presentation Layer"
A1[REST API]
A2[GraphQL API]
A3[WebSocket API]
end
subgraph "业务逻辑层 Business Logic Layer"
B1[用户业务逻辑]
B2[活动业务逻辑]
B3[认领业务逻辑]
B4[支付业务逻辑]
B5[消息业务逻辑]
end
subgraph "服务层 Service Layer"
C1[用户服务]
C2[活动服务]
C3[认领服务]
C4[支付服务]
C5[消息服务]
C6[通知服务]
end
subgraph "数据访问层 Data Access Layer"
D1[MySQL DAO]
D2[Redis DAO]
D3[MongoDB DAO]
D4[ES DAO]
end
subgraph "数据存储层 Data Storage Layer"
E1[MySQL数据库]
E2[Redis缓存]
E3[MongoDB文档库]
E4[Elasticsearch]
end
A1 --> B1
A1 --> B2
A1 --> B3
A1 --> B4
A1 --> B5
B1 --> C1
B2 --> C2
B3 --> C3
B4 --> C4
B5 --> C5
C1 --> D1
C2 --> D1
C3 --> D1
C4 --> D1
C5 --> D2
C6 --> D3
D1 --> E1
D2 --> E2
D3 --> E3
D4 --> E4
3. 核心服务设计
3.1 用户服务 (User Service)
3.1.1 服务职责
- 用户注册、登录、认证
- 用户资料管理
- 权限验证和授权
- 用户关系管理(关注、粉丝)
- 用户行为记录
3.1.2 核心模块
graph TB
A[用户服务] --> B[认证模块]
A --> C[用户管理模块]
A --> D[权限模块]
A --> E[关系模块]
A --> F[行为记录模块]
B --> B1[微信登录]
B --> B2[JWT Token]
B --> B3[刷新Token]
C --> C1[用户注册]
C --> C2[资料管理]
C --> C3[实名认证]
D --> D1[角色管理]
D --> D2[权限验证]
D --> D3[资源控制]
E --> E1[关注关系]
E --> E2[好友推荐]
E --> E3[社交图谱]
F --> F1[登录记录]
F --> F2[操作日志]
F --> F3[行为分析]
3.1.3 数据模型
-- 用户基本信息表
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
openid VARCHAR(64) UNIQUE NOT NULL,
unionid VARCHAR(64),
phone VARCHAR(20),
nickname VARCHAR(50),
avatar VARCHAR(255),
gender TINYINT DEFAULT 0,
birthday DATE,
city VARCHAR(50),
bio TEXT,
status TINYINT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_openid (openid),
INDEX idx_phone (phone),
INDEX idx_status (status)
);
-- 用户认证信息表
CREATE TABLE user_auths (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
real_name VARCHAR(50),
id_card VARCHAR(18),
auth_status TINYINT DEFAULT 0,
auth_time TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user_id (user_id),
INDEX idx_auth_status (auth_status)
);
-- 用户关系表
CREATE TABLE user_relations (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
follower_id BIGINT NOT NULL,
following_id BIGINT NOT NULL,
status TINYINT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (follower_id) REFERENCES users(id),
FOREIGN KEY (following_id) REFERENCES users(id),
UNIQUE KEY uk_relation (follower_id, following_id),
INDEX idx_follower (follower_id),
INDEX idx_following (following_id)
);
3.2 活动服务 (Activity Service)
3.2.1 服务职责
- 活动发布和管理
- 活动报名和参与
- 活动搜索和推荐
- 活动评价和反馈
- 活动统计分析
3.2.2 核心模块
graph TB
A[活动服务] --> B[活动管理模块]
A --> C[报名管理模块]
A --> D[搜索推荐模块]
A --> E[评价模块]
A --> F[统计模块]
B --> B1[活动发布]
B --> B2[活动编辑]
B --> B3[活动状态管理]
C --> C1[报名申请]
C --> C2[报名审核]
C --> C3[参与者管理]
D --> D1[活动搜索]
D --> D2[个性化推荐]
D --> D3[热门活动]
E --> E1[活动评价]
E --> E2[用户反馈]
E --> E3[评分统计]
F --> F1[活动数据统计]
F --> F2[用户行为分析]
F --> F3[运营报表]
3.2.3 数据模型
-- 活动信息表
CREATE TABLE activities (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
creator_id BIGINT NOT NULL,
title VARCHAR(100) NOT NULL,
description TEXT,
category_id INT,
start_time TIMESTAMP NOT NULL,
end_time TIMESTAMP NOT NULL,
location VARCHAR(255),
latitude DECIMAL(10,8),
longitude DECIMAL(11,8),
max_participants INT DEFAULT 0,
current_participants INT DEFAULT 0,
fee_type TINYINT DEFAULT 0, -- 0:免费 1:AA制 2:付费
fee_amount DECIMAL(10,2) DEFAULT 0,
status TINYINT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (creator_id) REFERENCES users(id),
INDEX idx_creator (creator_id),
INDEX idx_category (category_id),
INDEX idx_start_time (start_time),
INDEX idx_location (latitude, longitude),
INDEX idx_status (status)
);
-- 活动报名表
CREATE TABLE activity_participants (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
activity_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
status TINYINT DEFAULT 0, -- 0:待审核 1:已通过 2:已拒绝 3:已取消
apply_message TEXT,
apply_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
review_time TIMESTAMP NULL,
FOREIGN KEY (activity_id) REFERENCES activities(id),
FOREIGN KEY (user_id) REFERENCES users(id),
UNIQUE KEY uk_participant (activity_id, user_id),
INDEX idx_activity (activity_id),
INDEX idx_user (user_id),
INDEX idx_status (status)
);
-- 活动评价表
CREATE TABLE activity_reviews (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
activity_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
rating TINYINT NOT NULL,
comment TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (activity_id) REFERENCES activities(id),
FOREIGN KEY (user_id) REFERENCES users(id),
UNIQUE KEY uk_review (activity_id, user_id),
INDEX idx_activity (activity_id),
INDEX idx_rating (rating)
);
3.3 认领服务 (Adoption Service)
3.3.1 服务职责
- 动物信息管理
- 认领申请处理
- 认领关系维护
- 探访预约管理
- 成长记录管理
3.3.2 核心模块
graph TB
A[认领服务] --> B[动物管理模块]
A --> C[认领管理模块]
A --> D[探访管理模块]
A --> E[成长记录模块]
A --> F[农场管理模块]
B --> B1[动物信息]
B --> B2[动物分类]
B --> B3[动物状态]
C --> C1[认领申请]
C --> C2[认领审核]
C --> C3[认领关系]
D --> D1[探访预约]
D --> D2[探访记录]
D --> D3[探访路线]
E --> E1[成长日记]
E --> E2[照片记录]
E --> E3[健康档案]
F --> F1[农场信息]
F --> F2[农场服务]
F --> F3[农产品]
3.3.3 数据模型
-- 农场信息表
CREATE TABLE farms (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
description TEXT,
address VARCHAR(255),
latitude DECIMAL(10,8),
longitude DECIMAL(11,8),
contact_phone VARCHAR(20),
contact_person VARCHAR(50),
images JSON,
status TINYINT DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_status (status),
INDEX idx_location (latitude, longitude)
);
-- 动物信息表
CREATE TABLE animals (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
farm_id BIGINT NOT NULL,
name VARCHAR(50),
species VARCHAR(50) NOT NULL,
breed VARCHAR(50),
gender TINYINT,
birth_date DATE,
description TEXT,
images JSON,
adoption_fee DECIMAL(10,2),
adoption_period INT, -- 认领周期(月)
status TINYINT DEFAULT 1, -- 1:可认领 2:已认领 3:不可认领
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (farm_id) REFERENCES farms(id),
INDEX idx_farm (farm_id),
INDEX idx_species (species),
INDEX idx_status (status)
);
-- 认领关系表
CREATE TABLE adoptions (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
animal_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
adoption_name VARCHAR(50), -- 用户给动物起的名字
start_date DATE NOT NULL,
end_date DATE NOT NULL,
total_fee DECIMAL(10,2),
status TINYINT DEFAULT 1, -- 1:认领中 2:已到期 3:已取消
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (animal_id) REFERENCES animals(id),
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_animal (animal_id),
INDEX idx_user (user_id),
INDEX idx_status (status),
INDEX idx_date_range (start_date, end_date)
);
-- 探访记录表
CREATE TABLE visits (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
adoption_id BIGINT NOT NULL,
visit_date DATE NOT NULL,
visit_time TIME,
visitor_count INT DEFAULT 1,
notes TEXT,
photos JSON,
status TINYINT DEFAULT 1, -- 1:已预约 2:已完成 3:已取消
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (adoption_id) REFERENCES adoptions(id),
INDEX idx_adoption (adoption_id),
INDEX idx_visit_date (visit_date),
INDEX idx_status (status)
);
3.4 支付服务 (Payment Service)
3.4.1 服务职责
- 支付订单管理
- 支付流程处理
- 退款处理
- 账户余额管理
- 交易记录查询
3.4.2 核心模块
graph TB
A[支付服务] --> B[订单管理模块]
A --> C[支付处理模块]
A --> D[退款模块]
A --> E[账户模块]
A --> F[对账模块]
B --> B1[订单创建]
B --> B2[订单查询]
B --> B3[订单状态管理]
C --> C1[微信支付]
C --> C2[支付宝支付]
C --> C3[余额支付]
D --> D1[退款申请]
D --> D2[退款处理]
D --> D3[退款查询]
E --> E1[余额管理]
E --> E2[充值提现]
E --> E3[交易记录]
F --> F1[支付对账]
F --> F2[财务报表]
F --> F3[异常处理]
3.4.3 数据模型
-- 支付订单表
CREATE TABLE payment_orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(32) UNIQUE NOT NULL,
user_id BIGINT NOT NULL,
business_type TINYINT NOT NULL, -- 1:活动支付 2:认领支付 3:商品支付
business_id BIGINT NOT NULL,
amount DECIMAL(10,2) NOT NULL,
currency VARCHAR(3) DEFAULT 'CNY',
payment_method TINYINT, -- 1:微信 2:支付宝 3:余额
payment_channel VARCHAR(20),
status TINYINT DEFAULT 0, -- 0:待支付 1:支付中 2:支付成功 3:支付失败 4:已取消
paid_at TIMESTAMP NULL,
expired_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_order_no (order_no),
INDEX idx_user (user_id),
INDEX idx_business (business_type, business_id),
INDEX idx_status (status),
INDEX idx_created_at (created_at)
);
-- 支付记录表
CREATE TABLE payment_records (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_id BIGINT NOT NULL,
transaction_id VARCHAR(64),
payment_method TINYINT NOT NULL,
amount DECIMAL(10,2) NOT NULL,
status TINYINT DEFAULT 0, -- 0:处理中 1:成功 2:失败
response_data JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES payment_orders(id),
INDEX idx_order (order_id),
INDEX idx_transaction (transaction_id),
INDEX idx_status (status)
);
-- 用户账户表
CREATE TABLE user_accounts (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT UNIQUE NOT NULL,
balance DECIMAL(10,2) DEFAULT 0.00,
frozen_balance DECIMAL(10,2) DEFAULT 0.00,
total_income DECIMAL(10,2) DEFAULT 0.00,
total_expense DECIMAL(10,2) DEFAULT 0.00,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user (user_id)
);
-- 账户流水表
CREATE TABLE account_transactions (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
type TINYINT NOT NULL, -- 1:收入 2:支出 3:冻结 4:解冻
amount DECIMAL(10,2) NOT NULL,
balance_after DECIMAL(10,2) NOT NULL,
business_type TINYINT,
business_id BIGINT,
description VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_user (user_id),
INDEX idx_type (type),
INDEX idx_business (business_type, business_id),
INDEX idx_created_at (created_at)
);
3.5 消息服务 (Message Service)
3.5.1 服务职责
- 即时消息处理
- 群聊管理
- 消息存储和查询
- 消息推送
- 敏感词过滤
3.5.2 核心模块
graph TB
A[消息服务] --> B[即时消息模块]
A --> C[群聊管理模块]
A --> D[消息存储模块]
A --> E[推送模块]
A --> F[内容审核模块]
B --> B1[私聊消息]
B --> B2[消息发送]
B --> B3[消息接收]
C --> C1[群组创建]
C --> C2[成员管理]
C --> C3[群消息]
D --> D1[消息持久化]
D --> D2[消息查询]
D --> D3[消息同步]
E --> E1[实时推送]
E --> E2[离线推送]
E --> E3[推送统计]
F --> F1[敏感词检测]
F --> F2[图片审核]
F --> F3[内容过滤]
3.6 文件服务 (File Service)
3.6.1 服务职责
- 文件上传处理
- 图片压缩和处理
- 文件存储管理
- CDN加速
- 文件安全检查
3.6.2 核心模块
graph TB
A[文件服务] --> B[上传处理模块]
A --> C[图片处理模块]
A --> D[存储管理模块]
A --> E[CDN模块]
A --> F[安全检查模块]
B --> B1[文件上传]
B --> B2[分片上传]
B --> B3[断点续传]
C --> C1[图片压缩]
C --> C2[格式转换]
C --> C3[水印添加]
D --> D1[本地存储]
D --> D2[云存储]
D --> D3[存储策略]
E --> E1[CDN分发]
E --> E2[缓存管理]
E --> E3[访问优化]
F --> F1[病毒扫描]
F --> F2[内容检测]
F --> F3[访问控制]
4. 数据架构设计
4.1 数据库架构
4.1.1 MySQL主从架构
graph TB
A[应用服务] --> B[数据库代理]
B --> C[MySQL主库]
B --> D[MySQL从库1]
B --> E[MySQL从库2]
C --> F[写操作]
D --> G[读操作]
E --> G
C --> H[主从同步]
H --> D
H --> E
I[备份服务] --> C
I --> J[备份存储]
4.1.2 数据分库分表策略
graph TB
A[业务数据] --> B[用户相关数据]
A --> C[活动相关数据]
A --> D[认领相关数据]
A --> E[支付相关数据]
B --> B1[用户库1<br/>user_id % 4 = 0]
B --> B2[用户库2<br/>user_id % 4 = 1]
B --> B3[用户库3<br/>user_id % 4 = 2]
B --> B4[用户库4<br/>user_id % 4 = 3]
C --> C1[活动库1<br/>按时间分表]
C --> C2[活动库2<br/>按时间分表]
D --> D1[认领库1<br/>按农场分表]
D --> D2[认领库2<br/>按农场分表]
E --> E1[支付库1<br/>按时间分表]
E --> E2[支付库2<br/>按时间分表]
4.2 缓存架构
4.2.1 Redis集群架构
graph TB
A[应用服务] --> B[Redis代理]
B --> C[Redis主节点1]
B --> D[Redis主节点2]
B --> E[Redis主节点3]
C --> F[Redis从节点1]
D --> G[Redis从节点2]
E --> H[Redis从节点3]
I[哨兵节点1] --> C
I --> D
I --> E
J[哨兵节点2] --> C
J --> D
J --> E
K[哨兵节点3] --> C
K --> D
K --> E
4.2.2 缓存策略
- 用户信息缓存:用户基本信息,过期时间30分钟
- 活动列表缓存:热门活动列表,过期时间10分钟
- 搜索结果缓存:搜索结果,过期时间5分钟
- 计数器缓存:点赞数、评论数等,实时更新
- 会话缓存:用户登录状态,过期时间7天
4.3 搜索架构
4.3.1 Elasticsearch集群
graph TB
A[应用服务] --> B[ES负载均衡]
B --> C[ES主节点1]
B --> D[ES主节点2]
B --> E[ES主节点3]
C --> F[ES数据节点1]
C --> G[ES数据节点2]
D --> H[ES数据节点3]
D --> I[ES数据节点4]
E --> J[ES数据节点5]
E --> K[ES数据节点6]
L[数据同步服务] --> M[MySQL]
L --> B
4.3.2 索引设计
{
"activities": {
"mappings": {
"properties": {
"id": {"type": "long"},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"description": {
"type": "text",
"analyzer": "ik_max_word"
},
"category": {"type": "keyword"},
"location": {"type": "geo_point"},
"start_time": {"type": "date"},
"creator_id": {"type": "long"},
"status": {"type": "integer"},
"tags": {"type": "keyword"}
}
}
}
}
5. API设计规范
5.1 RESTful API设计
5.1.1 URL设计规范
GET /api/v1/users # 获取用户列表
GET /api/v1/users/{id} # 获取指定用户
POST /api/v1/users # 创建用户
PUT /api/v1/users/{id} # 更新用户
DELETE /api/v1/users/{id} # 删除用户
GET /api/v1/activities # 获取活动列表
POST /api/v1/activities # 创建活动
GET /api/v1/activities/{id} # 获取活动详情
PUT /api/v1/activities/{id} # 更新活动
DELETE /api/v1/activities/{id} # 删除活动
POST /api/v1/activities/{id}/join # 参加活动
DELETE /api/v1/activities/{id}/leave # 退出活动
5.1.2 请求响应格式
// 请求格式
{
"data": {
"title": "周末爬山活动",
"description": "一起去爬山,享受自然风光",
"start_time": "2024-01-20T09:00:00Z",
"location": "香山公园"
}
}
// 成功响应格式
{
"code": 200,
"message": "success",
"data": {
"id": 12345,
"title": "周末爬山活动",
"description": "一起去爬山,享受自然风光",
"start_time": "2024-01-20T09:00:00Z",
"location": "香山公园",
"created_at": "2024-01-15T10:30:00Z"
},
"timestamp": 1705312200
}
// 错误响应格式
{
"code": 400,
"message": "参数错误",
"error": {
"field": "start_time",
"reason": "开始时间不能早于当前时间"
},
"timestamp": 1705312200
}
5.1.3 状态码规范
| 状态码 | 说明 |
|---|---|
| 200 | 请求成功 |
| 201 | 创建成功 |
| 400 | 请求参数错误 |
| 401 | 未授权 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 409 | 资源冲突 |
| 422 | 参数验证失败 |
| 500 | 服务器内部错误 |
| 502 | 网关错误 |
| 503 | 服务不可用 |
5.2 认证授权机制
5.2.1 JWT Token设计
// JWT Header
{
"alg": "HS256",
"typ": "JWT"
}
// JWT Payload
{
"user_id": 12345,
"openid": "wx_openid_123",
"role": "user",
"permissions": ["activity:read", "activity:create"],
"iat": 1705312200,
"exp": 1705398600
}
5.2.2 权限控制
// 权限定义
enum Permission {
// 用户权限
USER_READ = 'user:read',
USER_WRITE = 'user:write',
// 活动权限
ACTIVITY_READ = 'activity:read',
ACTIVITY_WRITE = 'activity:write',
ACTIVITY_DELETE = 'activity:delete',
// 认领权限
ADOPTION_READ = 'adoption:read',
ADOPTION_WRITE = 'adoption:write',
// 管理权限
ADMIN_USER = 'admin:user',
ADMIN_ACTIVITY = 'admin:activity',
ADMIN_SYSTEM = 'admin:system'
}
// 角色权限映射
const rolePermissions = {
user: [
Permission.USER_READ,
Permission.ACTIVITY_READ,
Permission.ACTIVITY_WRITE,
Permission.ADOPTION_READ,
Permission.ADOPTION_WRITE
],
admin: [
...rolePermissions.user,
Permission.ADMIN_USER,
Permission.ADMIN_ACTIVITY,
Permission.ADMIN_SYSTEM
]
};
6. 消息队列架构
6.1 RabbitMQ架构设计
6.1.1 集群架构
graph TB
A[生产者服务] --> B[RabbitMQ集群]
subgraph "RabbitMQ集群"
C[节点1<br/>主节点]
D[节点2<br/>从节点]
E[节点3<br/>从节点]
C --> F[队列镜像]
D --> F
E --> F
end
B --> G[消费者服务1]
B --> H[消费者服务2]
B --> I[消费者服务3]
J[HAProxy] --> C
J --> D
J --> E
6.1.2 队列设计
// 队列配置
const queueConfig = {
// 用户相关队列
'user.register': {
durable: true,
exclusive: false,
autoDelete: false,
arguments: {
'x-message-ttl': 300000, // 5分钟TTL
'x-dead-letter-exchange': 'dlx.user'
}
},
// 活动相关队列
'activity.created': {
durable: true,
exclusive: false,
autoDelete: false,
arguments: {
'x-message-ttl': 600000, // 10分钟TTL
'x-dead-letter-exchange': 'dlx.activity'
}
},
// 支付相关队列
'payment.success': {
durable: true,
exclusive: false,
autoDelete: false,
arguments: {
'x-message-ttl': 1800000, // 30分钟TTL
'x-dead-letter-exchange': 'dlx.payment'
}
},
// 通知相关队列
'notification.push': {
durable: true,
exclusive: false,
autoDelete: false,
arguments: {
'x-message-ttl': 60000, // 1分钟TTL
'x-dead-letter-exchange': 'dlx.notification'
}
}
};
6.2 消息处理模式
6.2.1 发布订阅模式
// 事件发布
class EventPublisher {
async publishUserRegistered(userId: number, userData: any) {
const message = {
eventType: 'user.registered',
userId,
userData,
timestamp: Date.now()
};
await this.publish('user.events', message);
}
async publishActivityCreated(activityId: number, activityData: any) {
const message = {
eventType: 'activity.created',
activityId,
activityData,
timestamp: Date.now()
};
await this.publish('activity.events', message);
}
}
// 事件消费
class EventConsumer {
async handleUserRegistered(message: any) {
// 发送欢迎邮件
await this.sendWelcomeEmail(message.userId);
// 初始化用户数据
await this.initUserData(message.userId);
// 推送注册成功通知
await this.pushRegistrationNotification(message.userId);
}
async handleActivityCreated(message: any) {
// 更新搜索索引
await this.updateSearchIndex(message.activityId);
// 推荐给相关用户
await this.recommendToUsers(message.activityId);
// 发送创建成功通知
await this.pushCreationNotification(message.activityId);
}
}
7. 监控和日志
7.1 监控架构
7.1.1 监控体系
graph TB
A[应用服务] --> B[Metrics收集]
A --> C[日志收集]
A --> D[链路追踪]
B --> E[Prometheus]
C --> F[ELK Stack]
D --> G[Jaeger]
E --> H[Grafana]
F --> H
G --> H
H --> I[告警系统]
I --> J[短信告警]
I --> K[邮件告警]
I --> L[微信告警]
7.1.2 关键指标监控
// 业务指标
const businessMetrics = {
// 用户指标
userRegistrations: 'counter', // 用户注册数
activeUsers: 'gauge', // 活跃用户数
userRetention: 'gauge', // 用户留存率
// 活动指标
activitiesCreated: 'counter', // 活动创建数
activitiesJoined: 'counter', // 活动参与数
activityCompletionRate: 'gauge', // 活动完成率
// 认领指标
adoptionsCreated: 'counter', // 认领创建数
adoptionRevenue: 'counter', // 认领收入
visitCount: 'counter', // 探访次数
// 支付指标
paymentSuccess: 'counter', // 支付成功数
paymentFailure: 'counter', // 支付失败数
paymentAmount: 'counter' // 支付金额
};
// 技术指标
const technicalMetrics = {
// 性能指标
responseTime: 'histogram', // 响应时间
throughput: 'counter', // 吞吐量
errorRate: 'gauge', // 错误率
// 系统指标
cpuUsage: 'gauge', // CPU使用率
memoryUsage: 'gauge', // 内存使用率
diskUsage: 'gauge', // 磁盘使用率
networkIO: 'gauge', // 网络IO
// 数据库指标
dbConnections: 'gauge', // 数据库连接数
dbQueryTime: 'histogram', // 查询时间
dbSlowQueries: 'counter', // 慢查询数
// 缓存指标
cacheHitRate: 'gauge', // 缓存命中率
cacheMemoryUsage: 'gauge', // 缓存内存使用
cacheConnections: 'gauge' // 缓存连接数
};
7.2 日志架构
7.2.1 日志分类
// 日志级别
enum LogLevel {
ERROR = 'error',
WARN = 'warn',
INFO = 'info',
DEBUG = 'debug'
}
// 日志类型
enum LogType {
ACCESS = 'access', // 访问日志
ERROR = 'error', // 错误日志
BUSINESS = 'business', // 业务日志
SECURITY = 'security', // 安全日志
PERFORMANCE = 'performance' // 性能日志
}
// 日志格式
interface LogEntry {
timestamp: string;
level: LogLevel;
type: LogType;
service: string;
traceId: string;
userId?: number;
message: string;
data?: any;
error?: {
name: string;
message: string;
stack: string;
};
}
7.2.2 日志收集流程
graph LR
A[应用服务] --> B[日志文件]
B --> C[Filebeat]
C --> D[Logstash]
D --> E[Elasticsearch]
E --> F[Kibana]
G[实时日志] --> H[Fluentd]
H --> D
I[错误日志] --> J[告警系统]
J --> K[通知服务]
8. 安全架构
8.1 安全防护体系
8.1.1 多层安全防护
graph TB
A[用户请求] --> B[CDN/WAF]
B --> C[负载均衡器]
C --> D[API网关]
D --> E[应用服务]
E --> F[数据库]
G[DDoS防护] --> B
H[SQL注入防护] --> D
I[XSS防护] --> D
J[CSRF防护] --> D
K[数据加密] --> F
L[访问控制] --> F
8.1.2 安全措施
// 安全配置
const securityConfig = {
// JWT配置
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: '7d',
refreshExpiresIn: '30d',
algorithm: 'HS256'
},
// 密码策略
password: {
minLength: 8,
requireUppercase: true,
requireLowercase: true,
requireNumbers: true,
requireSymbols: true,
maxAttempts: 5,
lockoutDuration: 300000 // 5分钟
},
// 接口限流
rateLimit: {
windowMs: 60000, // 1分钟
max: 100, // 最大请求数
skipSuccessfulRequests: false,
skipFailedRequests: false
},
// CORS配置
cors: {
origin: ['https://jiebanke.com', 'https://admin.jiebanke.com'],
credentials: true,
optionsSuccessStatus: 200
},
// 数据加密
encryption: {
algorithm: 'aes-256-gcm',
keyLength: 32,
ivLength: 16,
tagLength: 16
}
};
8.2 数据安全
8.2.1 敏感数据加密
// 数据加密服务
class EncryptionService {
// 加密敏感数据
async encryptSensitiveData(data: string): Promise<string> {
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipher('aes-256-gcm', key, iv);
let encrypted = cipher.update(data, 'utf8', 'hex');
encrypted += cipher.final('hex');
const tag = cipher.getAuthTag();
return JSON.stringify({
encrypted,
key: key.toString('hex'),
iv: iv.toString('hex'),
tag: tag.toString('hex')
});
}
// 解密敏感数据
async decryptSensitiveData(encryptedData: string): Promise<string> {
const { encrypted, key, iv, tag } = JSON.parse(encryptedData);
const decipher = crypto.createDecipher('aes-256-gcm',
Buffer.from(key, 'hex'),
Buffer.from(iv, 'hex')
);
decipher.setAuthTag(Buffer.from(tag, 'hex'));
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
}
9. 性能优化
9.1 数据库优化
9.1.1 索引优化策略
-- 用户表索引优化
CREATE INDEX idx_users_openid ON users(openid);
CREATE INDEX idx_users_phone ON users(phone);
CREATE INDEX idx_users_status_created ON users(status, created_at);
-- 活动表索引优化
CREATE INDEX idx_activities_creator_status ON activities(creator_id, status);
CREATE INDEX idx_activities_category_time ON activities(category_id, start_time);
CREATE INDEX idx_activities_location ON activities(latitude, longitude);
CREATE INDEX idx_activities_status_time ON activities(status, start_time);
-- 复合索引优化
CREATE INDEX idx_activity_participants_complex
ON activity_participants(activity_id, status, apply_time);
-- 覆盖索引优化
CREATE INDEX idx_activities_list_cover
ON activities(status, start_time, id, title, creator_id, current_participants);
9.1.2 查询优化
// 分页查询优化
class ActivityService {
// 使用游标分页替代OFFSET
async getActivitiesByCursor(cursor?: number, limit: number = 20) {
const whereClause = cursor ? 'WHERE id < ?' : '';
const params = cursor ? [cursor, limit] : [limit];
const sql = `
SELECT id, title, creator_id, start_time, current_participants
FROM activities
${whereClause}
ORDER BY id DESC
LIMIT ?
`;
return await this.db.query(sql, params);
}
// 批量查询优化
async getActivitiesWithCreators(activityIds: number[]) {
const sql = `
SELECT
a.id, a.title, a.start_time,
u.id as creator_id, u.nickname, u.avatar
FROM activities a
JOIN users u ON a.creator_id = u.id
WHERE a.id IN (${activityIds.map(() => '?').join(',')})
`;
return await this.db.query(sql, activityIds);
}
}
9.2 缓存优化
9.2.1 多级缓存策略
// 缓存服务
class CacheService {
private l1Cache: Map<string, any> = new Map(); // 内存缓存
private redis: Redis; // Redis缓存
async get(key: string): Promise<any> {
// L1缓存查询
if (this.l1Cache.has(key)) {
return this.l1Cache.get(key);
}
// L2缓存查询
const value = await this.redis.get(key);
if (value) {
const parsed = JSON.parse(value);
// 回写L1缓存
this.l1Cache.set(key, parsed);
return parsed;
}
return null;
}
async set(key: string, value: any, ttl: number = 300): Promise<void> {
// 设置L1缓存
this.l1Cache.set(key, value);
// 设置L2缓存
await this.redis.setex(key, ttl, JSON.stringify(value));
}
// 缓存预热
async warmupCache(): Promise<void> {
// 预热热门活动
const hotActivities = await this.getHotActivities();
for (const activity of hotActivities) {
await this.set(`activity:${activity.id}`, activity, 600);
}
// 预热用户信息
const activeUsers = await this.getActiveUsers();
for (const user of activeUsers) {
await this.set(`user:${user.id}`, user, 1800);
}
}
}
9.3 异步处理优化
9.3.1 任务队列优化
// 任务队列服务
class TaskQueueService {
private queues: Map<string, Queue> = new Map();
constructor() {
this.initQueues();
}
private initQueues(): void {
// 高优先级队列
this.queues.set('high', new Queue('high-priority', {
redis: redisConfig,
defaultJobOptions: {
removeOnComplete: 100,
removeOnFail: 50,
attempts: 3,
backoff: 'exponential'
}
}));
// 普通优先级队列
this.queues.set('normal', new Queue('normal-priority', {
redis: redisConfig,
defaultJobOptions: {
removeOnComplete: 50,
removeOnFail: 25,
attempts: 2,
backoff: 'fixed'
}
}));
// 低优先级队列
this.queues.set('low', new Queue('low-priority', {
redis: redisConfig,
defaultJobOptions: {
removeOnComplete: 20,
removeOnFail: 10,
attempts: 1
}
}));
}
async addTask(priority: string, taskType: string, data: any): Promise<void> {
const queue = this.queues.get(priority);
if (!queue) {
throw new Error(`Queue ${priority} not found`);
}
await queue.add(taskType, data, {
priority: this.getPriorityValue(priority),
delay: this.getDelayTime(taskType)
});
}
private getPriorityValue(priority: string): number {
const priorities = { high: 10, normal: 5, low: 1 };
return priorities[priority] || 1;
}
private getDelayTime(taskType: string): number {
const delays = {
'send-email': 0,
'update-search-index': 5000,
'generate-report': 10000
};
return delays[taskType] || 0;
}
}
10. 部署和运维
10.1 Docker容器化
10.1.1 Dockerfile优化
# 多阶段构建
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
RUN npm run build
# 生产镜像
FROM node:18-alpine AS production
# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
WORKDIR /app
# 复制构建产物
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
USER nodejs
EXPOSE 3000
CMD ["node", "dist/index.js"]
10.1.2 Docker Compose配置
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=mysql
- REDIS_HOST=redis
depends_on:
- mysql
- redis
restart: unless-stopped
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: jiebanke
volumes:
- mysql_data:/var/lib/mysql
- ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
restart: unless-stopped
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- app
restart: unless-stopped
volumes:
mysql_data:
redis_data:
10.2 Kubernetes部署
10.2.1 应用部署配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: jiebanke-backend
labels:
app: jiebanke-backend
spec:
replicas: 3
selector:
matchLabels:
app: jiebanke-backend
template:
metadata:
labels:
app: jiebanke-backend
spec:
containers:
- name: backend
image: jiebanke/backend:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: host
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: jiebanke-backend-service
spec:
selector:
app: jiebanke-backend
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jiebanke-backend-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- api.jiebanke.com
secretName: jiebanke-tls
rules:
- host: api.jiebanke.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jiebanke-backend-service
port:
number: 80
10.3 CI/CD流水线
10.3.1 GitHub Actions配置
name: Backend CI/CD
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: test
MYSQL_DATABASE: test
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
redis:
image: redis:7-alpine
options: >-
--health-cmd="redis-cli ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Run tests
run: npm run test:coverage
env:
DB_HOST: localhost
DB_PORT: 3306
DB_USER: root
DB_PASSWORD: test
DB_NAME: test
REDIS_HOST: localhost
REDIS_PORT: 6379
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
build-and-deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: |
docker build -t jiebanke/backend:${{ github.sha }} .
docker tag jiebanke/backend:${{ github.sha }} jiebanke/backend:latest
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push Docker image
run: |
docker push jiebanke/backend:${{ github.sha }}
docker push jiebanke/backend:latest
- name: Deploy to Kubernetes
uses: azure/k8s-deploy@v1
with:
manifests: |
k8s/deployment.yaml
k8s/service.yaml
k8s/ingress.yaml
images: |
jiebanke/backend:${{ github.sha }}
kubectl-version: 'latest'
11. 总结
11.1 架构优势
11.1.1 技术优势
- 现代化技术栈:采用Node.js + TypeScript,开发效率高
- 微服务架构:服务解耦,独立部署和扩展
- 容器化部署:Docker + Kubernetes,运维便捷
- 多数据库支持:MySQL + Redis + MongoDB + ES,满足不同场景需求
- 消息队列:RabbitMQ异步处理,提高系统性能
11.1.2 性能优势
- 多级缓存:内存缓存 + Redis缓存,提高响应速度
- 读写分离:MySQL主从架构,提高数据库性能
- 分库分表:支持大数据量和高并发
- CDN加速:静态资源CDN分发,提高访问速度
- 异步处理:消息队列异步处理,提高系统吞吐量
11.1.3 安全优势
- 多层防护:WAF + API网关 + 应用层多重安全防护
- 数据加密:敏感数据加密存储和传输
- 权限控制:RBAC权限模型,细粒度权限控制
- 安全监控:实时安全监控和告警
- 合规性:符合数据保护和隐私法规要求
11.2 扩展性设计
11.2.1 水平扩展
- 无状态服务:支持服务实例水平扩展
- 数据库扩展:支持读库扩展和分库分表
- 缓存扩展:Redis集群支持水平扩展
- 消息队列扩展:RabbitMQ集群支持扩展
11.2.2 垂直扩展
- 功能模块化:新功能可独立开发和部署
- 插件化架构:支持功能插件化扩展
- API版本管理:支持API平滑升级
- 配置化管理:业务规则配置化,灵活调整
11.3 运维保障
11.3.1 监控告警
- 全方位监控:业务指标 + 技术指标 + 系统指标
- 实时告警:多渠道告警通知
- 可视化面板:Grafana可视化监控面板
- 日志分析:ELK日志分析和查询
11.3.2 高可用保障
- 服务冗余:多实例部署,故障自动切换
- 数据备份:定期数据备份和恢复测试
- 灾备方案:异地灾备和快速恢复
- 故障演练:定期故障演练和应急响应
11.4 持续改进
11.4.1 技术演进
- 云原生:向云原生架构演进
- 服务网格:引入Istio服务网格
- AI集成:集成机器学习和AI能力
- 边缘计算:支持边缘计算场景
11.4.2 性能优化
- 持续优化:基于监控数据持续优化性能
- 新技术引入:关注新技术,适时引入
- 架构重构:根据业务发展适时重构
- 最佳实践:总结和推广最佳实践
本后端架构文档为解班客项目提供了完整的技术架构指导,涵盖了从服务设计到部署运维的各个方面。通过合理的架构设计和技术选型,确保系统的高性能、高可用、高安全和高扩展性,为业务发展提供坚实的技术保障。