Files
vibe_coding/.cursor/rules/references/017-architecture-deep.md
2026-03-05 21:27:11 +08:00

8.5 KiB
Raw Blame History

017-architecture.mdc (Deep Reference)

该文件为原始详细规范归档,供 Tier 3 按需读取。


🏗️ Million-Level Concurrency Architecture Standards

架构总览

                    ┌──────────────┐
                    │   CDN/WAF    │
                    └──────┬───────┘
                           │
              ┌────────────┴────────────┐
              │     Nginx Cluster       │
              │  (负载均衡 + SSL + 静态) │
              └────────────┬────────────┘
                           │
         ┌─────────────────┼─────────────────┐
         ▼                 ▼                 ▼
   ┌──────────┐    ┌──────────┐    ┌──────────┐
   │ Hyperf-1 │    │ Hyperf-2 │    │ Hyperf-N │
   │ Swoole   │    │ Swoole   │    │ Swoole   │
   │ HTTP:9501│    │ HTTP:9501│    │ HTTP:9501│
   │ WS:9502  │    │ WS:9502  │    │ WS:9502  │
   └────┬─────┘    └────┬─────┘    └────┬─────┘
        │               │               │
        └───────┬───────┴───────┬───────┘
                │               │
         ┌──────┴──────┐ ┌─────┴──────┐
         │ Redis       │ │ MySQL      │
         │ Cluster/    │ │ Master     │
         │ Sentinel    │ │  ├─Slave 1 │
         │             │ │  └─Slave 2 │
         └─────────────┘ └────────────┘

无状态服务设计

所有 Hyperf 实例必须无状态,确保水平扩展:

状态类型 存储位置 禁止
用户 Session Redis 存储在内存/文件
JWT Token Redis (可验证+可吊销) 仅本地验证
文件上传 对象存储 (S3/OSS) 本地 storage/
WebSocket 连接 Redis 维护映射表 进程内变量
配置 配置中心 / env 硬编码

缓存策略

多级缓存

L1: 进程内缓存 (APCu / Swoole Table)     — 毫秒级, 容量小
L2: Redis 缓存                           — 亚毫秒级, 容量中
L3: MySQL 查询                           — 毫秒级, 容量大

缓存防护

问题 场景 解决方案
穿透 查询不存在的数据 布隆过滤器 / 缓存空值 (TTL 30s)
雪崩 大量缓存同时过期 TTL 加随机抖动 / 预热
击穿 热点 Key 过期时大量请求 互斥锁 (singleflight)
// Cache-Aside with mutex lock
public function getOrderWithLock(int $id): ?ProductionOrder
{
    $cacheKey = "order:{$id}";
    $lockKey = "lock:order:{$id}";

    $cached = $this->redis->get($cacheKey);
    if ($cached !== false) {
        return unserialize($cached);
    }

    // Mutex: only one coroutine queries DB
    $lock = $this->redis->set($lockKey, '1', ['NX', 'EX' => 5]);
    if ($lock) {
        try {
            $order = ProductionOrder::find($id);
            $ttl = 300 + random_int(0, 60); // jitter
            $this->redis->setex($cacheKey, $ttl, serialize($order));
            return $order;
        } finally {
            $this->redis->del($lockKey);
        }
    }

    // Wait and retry
    Coroutine::sleep(0.05);
    return $this->getOrderWithLock($id);
}

限流策略

令牌桶 (API 级别)

use Hyperf\RateLimit\Annotation\RateLimit;

#[RateLimit(create: 1, capacity: 100, limitCallback: [RateLimitHandler::class, 'handle'])]
public function list(): array
{
    // 每秒生成 1 个令牌,桶容量 100
}

滑动窗口 (用户级别)

// Redis ZSET sliding window
public function isRateLimited(string $key, int $maxRequests, int $windowSeconds): bool
{
    $now = microtime(true);
    $windowStart = $now - $windowSeconds;

    $pipe = $this->redis->pipeline();
    $pipe->zremrangebyscore($key, '-inf', (string) $windowStart);
    $pipe->zadd($key, [(string) $now => $now]);
    $pipe->zcard($key);
    $pipe->expire($key, $windowSeconds);
    $results = $pipe->exec();

    return $results[2] > $maxRequests;
}

消息队列削峰

高并发写入:
  Client → API → Redis Queue (缓冲) → Consumer → MySQL

适用场景:
- 订单创建 (削峰)
- 通知发送 (异步)
- 日志记录 (解耦)
- 数据统计 (批处理)

服务降级与熔断

// 降级策略
class OrderService
{
    public function getStatistics(int $orderId): array
    {
        try {
            return $this->doGetStatistics($orderId);
        } catch (\Throwable $e) {
            // Fallback: return cached/default data
            return $this->getCachedStatistics($orderId) ?? self::DEFAULT_STATS;
        }
    }
}

// 熔断器模式
// Circuit Breaker: CLOSED → OPEN → HALF-OPEN → CLOSED
// Use hyperf/circuit-breaker component

数据库扩展策略

垂直拆分 (按业务域)

production_db  → 订单、子订单、发货
permission_db  → 用户、角色、权限
notification_db → 通知、消息

水平分片 (百万级后)

分片键: order_id
分片策略: order_id % shard_count
路由层: Hyperf 中间层 或 ProxySQL

注意: 跨分片查询需要聚合层

部署扩展清单

阶段 QPS 架构
起步 < 1K 单机 Docker Compose
成长 1K ~ 10K Nginx + 2~4 Hyperf + MySQL主从 + Redis Sentinel
规模 10K ~ 100K K8s + HPA + MySQL Cluster + Redis Cluster
百万 100K+ 微服务拆分 + 消息队列 + 分库分表 + CDN

模块通信规范

019-modular.mdc 互补,本节侧重跨服务/跨进程通信019 侧重代码内模块边界

通信方式选择矩阵

场景 推荐方式 禁止方式
同进程同步调用 依赖注入 + 接口 全局静态方法
跨进程异步 AsyncQueue / RabbitMQ 轮询 DB
实时推送 WebSocket + Redis Pub/Sub HTTP 长轮询
定时任务 Hyperf Crontab sleep 循环
跨服务数据 REST API / 共享 Redis 直连对方 DB

前端模块通信规范

组件间通信优先级(由低到高耦合):
  1. Props & Emits父子         — 首选
  2. provide/inject跨层级       — 适合主题/配置
  3. Pinia Store状态共享        — 跨模块全局状态
  4. EventBus (mitt)              — 非父子一次性事件(慎用)
  5. URL / Query Params            — 页面级状态持久化
// ✅ 推荐:通过 Pinia 跨模块共享状态
// stores/notification.ts
export const useNotificationStore = defineStore('notification', () => {
  const unreadCount = ref(0)
  const messages = ref<Notification[]>([])

  function addNotification(msg: Notification): void {
    messages.value.unshift(msg)
    unreadCount.value++
  }

  return { unreadCount, messages, addNotification }
})

// 订单模块使用通知(无直接耦合)
// views/order/composables/useOrderActions.ts
const notificationStore = useNotificationStore()

async function createOrder(data: OrderCreateForm): Promise<void> {
  const order = await OrderApi.create(data)
  // 通过 Store 通知,不直接调用通知组件
  notificationStore.addNotification({
    type: 'success',
    title: '订单创建成功',
    content: `订单号 ${order.orderNo} 已提交`,
  })
}

WebSocket 模块通信

// src/composables/useWebSocket.ts — 全局单例 WebSocket 管理
// 所有模块订阅自己关心的消息类型,不感知连接细节
export const wsClient = useWebSocket()

// 订单模块:只监听订单相关消息
const { on, off } = useWebSocket()
on('order.status_changed', (payload) => {
  orderStore.updateOrderStatus(payload.orderId, payload.status)
})

// 通知模块:只监听通知消息
on('notification.new', (payload) => {
  notificationStore.addNotification(payload)
})

性能基线

指标 目标值 监控方式
API P99 延迟 < 200ms Prometheus + Grafana
数据库查询 < 50ms 慢查询日志
Redis 命令 < 5ms Redis INFO
缓存命中率 > 85% 自定义指标
错误率 < 0.1% Sentry / 日志
可用性 99.9% 健康检查 + 告警