Ledger 系统架构设计
架构概述
Ledger 模块采用现代化的微服务架构设计,基于 清洁架构 和 领域驱动设计 原则,确保系统的可扩展性、可维护性和可测试性。整个系统设计面向移动端应用场景,支持高并发、低延迟的服务需求。
核心设计原则
1. 清洁架构 (Clean Architecture)
- 依赖倒置: 高层模块不依赖低层模块,双方都依赖抽象
- 接口隔离: 面向接口编程,所有外部依赖通过接口抽象
- 单一职责: 每个模块职责单一,边界清晰
- 开闭原则: 对扩展开放,对修改封闭
2. 可测试性优先
- 100% 可测试: 消除所有不可测试的代码层
- 依赖注入: 通过 Wire 框架实现自动依赖注入
- 接口抽象: 所有外部依赖都可被 Mock 替换
- TDD 驱动: 测试驱动开发,保证代码质量
3. 高性能设计
- 多级缓存: 本地缓存 + Redis 集群
- 异步处理: 消息队列 + 工作池
- 连接复用: 数据库和 Redis 连接池优化
- 读写分离: 主从架构,查询性能优化
系统分层架构
核心组件设计
1. API 网关层
负责请求路由、限流、认证和负载均衡。
主要职责:
- 请求路由和负载均衡
- API 限流和熔断保护
- 统一认证和授权
- 请求日志和监控
技术选型:
- 负载均衡: Nginx/Kong Gateway
- 限流算法: 令牌桶 + 滑动窗口
- 监控: Prometheus + Grafana
- 日志: ELK Stack
2. 表现层 (Presentation Layer)
处理外部请求,协议转换和数据验证。
HTTP API Server (Gin)
go
// HTTP 服务器配置
type HTTPServer struct {
engine *gin.Engine
middleware []gin.HandlerFunc
config *HTTPConfig
}
// 中间件链
func setupMiddleware() []gin.HandlerFunc {
return []gin.HandlerFunc{
middleware.Recovery(),
middleware.Logger(),
middleware.CORS(),
middleware.RateLimiter(),
middleware.Authentication(),
middleware.RequestID(),
middleware.Metrics(),
}
}gRPC API Server
go
// gRPC 服务器配置
type GRPCServer struct {
server *grpc.Server
interceptors []grpc.UnaryServerInterceptor
config *GRPCConfig
}
// 拦截器链
func setupInterceptors() []grpc.UnaryServerInterceptor {
return []grpc.UnaryServerInterceptor{
recovery.UnaryServerInterceptor(),
logging.UnaryServerInterceptor(logger),
metrics.UnaryServerInterceptor(),
tracing.UnaryServerInterceptor(),
ratelimit.UnaryServerInterceptor(limiter),
auth.UnaryServerInterceptor(authFunc),
}
}3. 应用层 (Application Layer)
协调领域对象,实现业务用例。
服务接口设计
go
// 账本服务接口
type LedgerService interface {
CreateLedger(ctx context.Context, req *CreateLedgerRequest) (*Ledger, error)
GetLedger(ctx context.Context, id string) (*Ledger, error)
UpdateLedger(ctx context.Context, req *UpdateLedgerRequest) (*Ledger, error)
DeleteLedger(ctx context.Context, id string) error
ListLedgers(ctx context.Context, req *ListLedgersRequest) (*ListLedgersResponse, error)
}
// 交易服务接口
type TransactionService interface {
CreateTransaction(ctx context.Context, req *CreateTransactionRequest) (*Transaction, error)
GetTransaction(ctx context.Context, id string) (*Transaction, error)
UpdateTransaction(ctx context.Context, req *UpdateTransactionRequest) (*Transaction, error)
DeleteTransaction(ctx context.Context, id string) error
ListTransactions(ctx context.Context, req *ListTransactionsRequest) (*ListTransactionsResponse, error)
BatchCreateTransactions(ctx context.Context, req *BatchCreateTransactionsRequest) (*BatchCreateTransactionsResponse, error)
}依赖注入配置
go
// Wire 依赖注入配置
//go:build wireinject
// +build wireinject
func InitializeLedgerService(
config *Config,
db *gorm.DB,
redis redis.Cmdable,
kafkaProducer *kafka.Producer,
) (*LedgerService, error) {
wire.Build(
// Repository 层
repository.NewLedgerRepository,
repository.NewTransactionRepository,
repository.NewTagRepository,
repository.NewBudgetRepository,
// Service 层
service.NewLedgerService,
service.NewTransactionService,
service.NewBudgetService,
service.NewNotificationService,
// Infrastructure 层
cache.NewCacheManager,
queue.NewMessageProducer,
external.NewExternalServiceClient,
)
return &LedgerService{}, nil
}4. 领域层 (Domain Layer)
包含业务逻辑和领域对象。
聚合根设计
go
// 账本聚合根
type Ledger struct {
id LedgerID
name string
description string
currency Currency
ownerID UserID
settings LedgerSettings
createdAt time.Time
updatedAt time.Time
version int64 // 乐观锁版本号
}
// 业务方法
func (l *Ledger) UpdateSettings(settings LedgerSettings) error {
l.settings = settings
l.updatedAt = time.Now()
l.recordEvent(NewLedgerSettingsUpdatedEvent(l.id, settings))
return nil
}
// 交易聚合根
type Transaction struct {
id TransactionID
ledgerID LedgerID
type_ TransactionType
amount Money
description string
note string
tags []Tag
transactionDate time.Time
createdAt time.Time
updatedAt time.Time
version int64
}
// 业务方法
func (t *Transaction) UpdateAmount(newAmount Money) error {
if newAmount.IsZero() {
return ErrInvalidAmount
}
oldAmount := t.amount
t.amount = newAmount
t.updatedAt = time.Now()
t.recordEvent(NewTransactionAmountChangedEvent(
t.id, t.ledgerID, oldAmount, newAmount,
))
return nil
}领域事件设计
go
// 领域事件接口
type DomainEvent interface {
EventID() string
EventType() string
AggregateID() string
OccurredAt() time.Time
Version() int
}
// 交易创建事件
type TransactionCreatedEvent struct {
eventID string
transactionID string
ledgerID string
amount Money
type_ TransactionType
occurredAt time.Time
version int
}
// 事件处理器
type TransactionEventHandler struct {
budgetService BudgetService
notificationSvc NotificationService
analyticsService AnalyticsService
}
func (h *TransactionEventHandler) Handle(event DomainEvent) error {
switch e := event.(type) {
case *TransactionCreatedEvent:
return h.handleTransactionCreated(e)
case *TransactionUpdatedEvent:
return h.handleTransactionUpdated(e)
default:
return nil
}
}5. 基础设施层 (Infrastructure Layer)
实现技术细节和外部依赖。
仓储模式实现
go
// 仓储接口
type LedgerRepository interface {
Save(ctx context.Context, ledger *Ledger) error
FindByID(ctx context.Context, id LedgerID) (*Ledger, error)
FindByUserID(ctx context.Context, userID UserID) ([]*Ledger, error)
Delete(ctx context.Context, id LedgerID) error
Count(ctx context.Context, criteria *LedgerCriteria) (int64, error)
}
// GORM 实现
type gormLedgerRepository struct {
db *gorm.DB
cache CacheManager
}
func (r *gormLedgerRepository) Save(ctx context.Context, ledger *Ledger) error {
model := r.toModel(ledger)
// 乐观锁检查
result := r.db.WithContext(ctx).
Where("id = ? AND version = ?", model.ID, model.Version-1).
Updates(model)
if result.RowsAffected == 0 {
return ErrOptimisticLockConflict
}
// 更新缓存
go r.cache.Set(r.cacheKey(ledger.ID()), ledger, time.Hour)
return result.Error
}缓存管理器
go
// 多级缓存管理
type CacheManager interface {
Get(ctx context.Context, key string) (interface{}, error)
Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error
Delete(ctx context.Context, key string) error
InvalidatePattern(ctx context.Context, pattern string) error
}
type multiLevelCacheManager struct {
localCache *bigcache.BigCache // L1: 本地缓存
redisCache redis.Cmdable // L2: 分布式缓存
serializer Serializer // 序列化器
}
func (c *multiLevelCacheManager) Get(ctx context.Context, key string) (interface{}, error) {
// L1: 本地缓存
if data, err := c.localCache.Get(key); err == nil {
return c.serializer.Deserialize(data)
}
// L2: Redis 缓存
if data, err := c.redisCache.Get(ctx, key).Bytes(); err == nil {
value, err := c.serializer.Deserialize(data)
if err == nil {
// 回写本地缓存
go c.localCache.Set(key, data)
}
return value, err
}
return nil, ErrCacheMiss
}中间件架构设计
基于 Kratos 框架的中间件设计模式:
中间件实现示例
go
// 限流中间件
func RateLimiterMiddleware(limiter ratelimit.Limiter) gin.HandlerFunc {
return func(c *gin.Context) {
userID := getUserID(c)
key := fmt.Sprintf("user:%s", userID)
if !limiter.Allow(key) {
c.JSON(http.StatusTooManyRequests, gin.H{
"error": "rate limit exceeded",
"retry_after": limiter.RetryAfter(key),
})
c.Abort()
return
}
c.Next()
}
}
// 熔断中间件
func CircuitBreakerMiddleware(breaker circuitbreaker.CircuitBreaker) gin.HandlerFunc {
return func(c *gin.Context) {
err := breaker.Execute(func() error {
c.Next()
if c.Writer.Status() >= 500 {
return fmt.Errorf("server error: %d", c.Writer.Status())
}
return nil
})
if err != nil {
if errors.Is(err, circuitbreaker.ErrOpenState) {
c.JSON(http.StatusServiceUnavailable, gin.H{
"error": "service temporarily unavailable",
})
}
}
}
}数据流架构
部署架构
性能特性
1. 吞吐量目标
- HTTP API: 5,000 QPS (单实例 1,500 QPS)
- gRPC API: 10,000 QPS (单实例 3,000 QPS)
- 数据库写入: 2,000 TPS
- 缓存读取: 50,000 OPS
2. 延迟目标
- API 响应时间: P99 < 200ms
- 数据库查询: P95 < 50ms
- 缓存访问: P99 < 5ms
- 消息队列延迟: < 10ms
3. 可用性目标
- 服务可用性: 99.9% (8.76小时/年)
- 数据持久性: 99.999999999% (11个9)
- 故障恢复时间: < 15分钟
- 数据备份: 每小时备份,保留30天
扩展性设计
1. 水平扩展
- 无状态服务: 所有服务都设计为无状态,支持自动扩缩容
- 数据分片: 支持按用户ID或账本ID进行数据分片
- 缓存分布: Redis 集群支持数据分布和故障转移
- 消息队列: Kafka 分区支持消息并行处理
2. 垂直扩展
- 服务拆分: 支持按业务功能拆分为独立微服务
- 数据库分离: 读写分离,按业务拆分数据库
- 专用缓存: 不同业务使用独立的缓存实例
- 异步解耦: 通过消息队列实现服务间异步通信
3. 地理分布
- 多区域部署: 支持跨区域部署和数据同步
- CDN 加速: 静态资源通过 CDN 分发
- 就近路由: 根据用户地理位置路由到最近的服务节点
- 数据合规: 支持数据本地化存储要求
安全架构
1. 网络安全
- TLS 加密: 所有外部通信使用 TLS 1.3
- VPC 隔离: 服务部署在私有网络中
- 防火墙: 严格的入站和出站规则
- DDoS 防护: 云厂商 DDoS 防护服务
2. 应用安全
- 身份认证: JWT Token + Refresh Token 机制
- 权限控制: RBAC 基于角色的访问控制
- API 限流: 多维度限流策略
- 输入验证: 严格的参数验证和 SQL 注入防护
3. 数据安全
- 加密存储: 敏感数据 AES-256 加密
- 访问审计: 完整的数据访问日志
- 备份加密: 备份数据加密存储
- 数据脱敏: 开发测试环境数据脱敏
监控和可观测性
1. 指标监控
- 业务指标: 交易量、用户活跃度、预算使用率
- 技术指标: QPS、延迟、错误率、资源使用率
- 基础设施: CPU、内存、磁盘、网络使用情况
- 告警机制: 基于阈值和趋势的智能告警
2. 日志管理
- 结构化日志: JSON 格式的结构化日志
- 链路追踪: 分布式请求链路追踪
- 集中收集: ELK Stack 日志聚合分析
- 日志分级: ERROR、WARN、INFO、DEBUG 分级
3. 链路追踪
- 分布式追踪: Jaeger 全链路追踪
- 性能分析: 请求耗时分解和瓶颈识别
- 依赖分析: 服务依赖关系图谱
- 错误诊断: 异常请求快速定位
质量保证
1. 代码质量
- 代码覆盖率: > 90%
- 静态检查: golint、go vet、gosec
- 代码审查: 强制 PR Review
- 文档同步: 代码变更同步更新文档
2. 测试策略
- 单元测试: 所有业务逻辑单元测试
- 集成测试: API 和数据库集成测试
- 性能测试: 压力测试和基准测试
- 安全测试: 渗透测试和安全扫描
3. 持续集成
- 自动构建: 代码提交自动触发构建
- 自动测试: 构建后自动运行测试套件
- 自动部署: 测试通过后自动部署到测试环境
- 回滚策略: 部署失败自动回滚
这个架构设计确保了 Ledger 模块具备工业级的可靠性、性能和可维护性,为移动端财务管理应用提供稳定可靠的后端服务支撑。