# 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) | ```php // 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 级别) ```php use Hyperf\RateLimit\Annotation\RateLimit; #[RateLimit(create: 1, capacity: 100, limitCallback: [RateLimitHandler::class, 'handle'])] public function list(): array { // 每秒生成 1 个令牌,桶容量 100 } ``` ### 滑动窗口 (用户级别) ```php // 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 适用场景: - 订单创建 (削峰) - 通知发送 (异步) - 日志记录 (解耦) - 数据统计 (批处理) ``` ## 服务降级与熔断 ```php // 降级策略 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 — 页面级状态持久化 ``` ```typescript // ✅ 推荐:通过 Pinia 跨模块共享状态 // stores/notification.ts export const useNotificationStore = defineStore('notification', () => { const unreadCount = ref(0) const messages = ref([]) 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 { const order = await OrderApi.create(data) // 通过 Store 通知,不直接调用通知组件 notificationStore.addNotification({ type: 'success', title: '订单创建成功', content: `订单号 ${order.orderNo} 已提交`, }) } ``` ### WebSocket 模块通信 ```typescript // 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% | 健康检查 + 告警 |