文档目录
内存进程监控

简介

本文件为 DouPHP 提供一套面向生产环境的“内存与进程监控”配置与实践指南,覆盖以下目标:

  • PHP 进程内存使用监控:统计峰值、识别增长模式、评估垃圾回收效果、定位潜在泄漏。
  • 缓存命中率监控:数据缓存、模板编译缓存、查询字段缓存的使用效率。
  • 会话数据存储监控:会话数量、大小、过期清理策略。
  • 进程间通信与资源竞争检测:基于共享存储(如 Memcache/Memcached)的并发访问与锁竞争。
  • 趋势分析与优化建议:结合指标进行容量规划与参数调优。

项目结构

DouPHP 采用分层与模块化组织,关键与监控相关的目录与文件包括:

  • 配置层:应用常量、系统常量等集中管理。
  • 基础设施层:会话服务、模板编译缓存、清单缓存生成等。
  • 业务路由层:URL 构建时的字段缓存预热。
  • 插件层:第三方 SDK 中的缓存适配器(Memcache/Memcached),可用于统一缓存与监控接入点。
  • 管理端:缓存清理服务,便于运维操作。
graph TB
A["配置(config)"] --> B["会话(Session)"]
A --> C["模板编译缓存(CompileCache)"]
A --> D["清单缓存(ManifestCacheGeneration)"]
E["路由 UrlBuilder"] --> F["字段缓存(进程内)"]
G["缓存适配器(Memcache/Memcached)"] --> H["外部缓存服务"]
I["缓存清理服务(CacheClearService)"] --> C
I --> D

核心组件

  • 会话服务:封装 $_SESSION[DOU_ID] 命名空间读写,提供安全降级与常用操作(get/set/push/pull/increment/decrement/forget/flash)。
  • 模板编译缓存:将模板编译产物持久化到磁盘,支持清理。
  • 清单缓存生成:用于静态资源版本与清单缓存。
  • URL 字段缓存:在请求生命周期内批量回填 slug/created_at 等字段,减少重复查询。
  • 缓存适配器:通过 Memcache/Memcached 实现外部缓存,可作为统一缓存与监控接入点。
  • 缓存清理服务:提供删除缓存目录的能力,便于运维清理。

架构总览

下图展示从请求进入、会话读写、缓存命中到外部缓存服务的整体流程,并标注可观测点(指标采集位置)。

sequenceDiagram
participant Client as "客户端"
participant App as "DouPHP 应用"
participant Sess as "会话服务(Session)"
participant UBuilder as "URL 构建器(UrlBuilder)"
participant Tpl as "模板编译缓存"
participant Cache as "外部缓存(Memcache/Memcached)"
participant DB as "数据库"
Client->>App : HTTP 请求
App->>Sess : 读取/写入会话(DOU_ID 命名空间)
App->>UBuilder : 构建 URL/字段缓存
UBuilder-->>DB : 批量查询缺失字段
UBuilder-->>App : 返回字段值(进程内缓存)
App->>Tpl : 渲染模板(命中编译缓存?)
Tpl-->>App : 返回编译结果或重新编译
App->>Cache : 读/写业务缓存键
Cache-->>App : 命中或未命中
App->>DB : 未命中时回源查询
DB-->>App : 数据行
App-->>Client : 响应

详细组件分析

进程内存使用监控

  • 指标定义
    • 峰值内存:进程最大 RSS/内存占用。
    • 平均内存:请求周期内均值。
    • 内存增长率:单位时间增量,识别异常增长。
    • GC 触发次数与耗时:评估垃圾回收效果。
  • 采集方式
    • 在请求入口与出口记录内存快照,计算差值与峰值。
    • 在模板编译、大对象处理前后采样,定位热点。
    • 对 URL 字段缓存、模板编译缓存、外部缓存调用进行埋点,关联内存变化。
  • 告警阈值
    • 峰值超过基线 + N% 持续 M 分钟。
    • 内存增长率连续 K 个周期为正且超阈值。
    • GC 频繁触发但内存未回落。

缓存命中率监控(数据缓存、模板缓存、查询缓存)

  • 指标定义
    • 命中率 = 命中次数 / (命中次数 + 未命中次数)。
    • 未命中率、回源率、延迟分布。
  • 采集点
    • 外部缓存:Memcache/Memcached 的 get/add/update/del 调用。
    • 模板编译缓存:编译命中/未命中、重建次数。
    • URL 字段缓存:进程内缓存命中与回源查询次数。
  • 可视化建议
    • 按模块/接口维度展示命中率与延迟。
    • 对比不同 TTL 下的命中率变化。
flowchart TD
Start(["缓存读取"]) --> CheckHit{"是否命中?"}
CheckHit --> |是| ReturnHit["返回缓存值"]
CheckHit --> |否| ReadSource["回源读取(数据库/文件系统)"]
ReadSource --> WriteCache["写入缓存(带TTL)"]
WriteCache --> ReturnMiss["返回源数据"]
ReturnHit --> End(["结束"])
ReturnMiss --> End

会话数据存储监控

  • 指标定义
    • 会话数量:活跃会话数、历史会话总数。
    • 会话大小:每个 DOU_ID 命名空间下数据体积。
    • 过期清理:清理频率、清理量、清理失败次数。
  • 采集点
    • 会话读写:get/set/pull/flush 等操作计数。
    • 会话清理:定时任务或框架内置 GC 的执行日志。
  • 优化建议
    • 控制单会话大小,避免大对象存入 $_SESSION。
    • 合理设置会话 TTL,降低存储压力。
    • 对高频写入的会话键做分片或压缩。
classDiagram
class Session {
+get(key, default, subKey) mixed
+set(key, value, subKey) void
+has(key, subKey) bool
+del(key, subKey) void
+clear() void
+push(key, value) void
+pull(key, default) mixed
+increment(key, by) int
+decrement(key, by) int
+forget(key, value) void
+setFlash(key, value) void
+getFlash(key, default) mixed
+pullAllFlashes() array
}

内存使用趋势分析

  • 分析方法
    • 收集每请求的内存曲线,绘制 P50/P95/P99 随时间变化。
    • 识别周期性峰值(如报表导出、批量导入)。
    • 关联缓存命中率与 GC 事件,分析内存释放时机。
  • 优化建议
    • 对大对象使用流式处理或分页加载。
    • 及时释放不再使用的引用,避免循环引用导致 GC 失效。
    • 调整 GC 阈值与策略,平衡吞吐与内存占用。

进程间通信监控与资源竞争检测

  • 场景说明
    • 多进程/多 Worker 共享外部缓存(Memcache/Memcached)时,可能出现键冲突、热键竞争。
  • 监控要点
    • 连接池健康度、错误率、超时率。
    • 热点键访问频次与延迟分布。
    • 写放大比例(更新频率 vs 读取频率)。
  • 缓解策略
    • 使用分布式锁或版本号控制避免竞态。
    • 对热点键做本地缓存+短 TTL 防抖。
    • 合理分片键名,分散负载。
sequenceDiagram
participant W1 as "Worker 1"
participant W2 as "Worker 2"
participant MC as "Memcache/Memcached"
W1->>MC : 获取键A
W2->>MC : 获取键A
MC-->>W1 : 返回旧值
MC-->>W2 : 返回旧值
W1->>MC : 更新键A(加锁/版本号)
W2->>MC : 重试获取键A
MC-->>W2 : 返回新值

依赖关系分析

  • 配置依赖:应用常量与系统常量影响运行时行为(如调试开关、模块白名单)。
  • 会话依赖:所有会话读写均通过 Session 类,确保命名空间隔离与安全降级。
  • 缓存依赖:外部缓存通过适配器抽象,便于替换与监控。
  • 模板与清单缓存:由管理端清理服务统一管理,避免脏数据。
graph LR
Config["配置(config)"] --> Session["会话(Session)"]
Config --> Compile["模板编译缓存"]
Config --> Manifest["清单缓存"]
Router["路由 UrlBuilder"] --> FieldCache["字段缓存"]
Adapter["缓存适配器"] --> External["外部缓存服务"]
Admin["缓存清理服务"] --> Compile
Admin --> Manifest

性能考量

  • 进程内存
    • 避免在会话中存放大对象;必要时序列化或外置存储。
    • 控制单次请求的数据集大小,使用分页与懒加载。
    • 关注模板编译产物大小,定期清理无用缓存。
  • 缓存
    • 合理设置 TTL,避免冷数据长期占用内存。
    • 对热点键进行本地缓存降载,减少外部缓存压力。
    • 监控命中率与延迟,及时调整缓存策略。
  • 会话
    • 限制会话大小与生命周期,防止存储膨胀。
    • 对频繁更新的会话键进行合并写入。

故障排查指南

  • 症状:内存持续增长
    • 检查是否存在未释放的大对象引用。
    • 观察 GC 触发频率与效果,必要时调整阈值。
    • 排查模板编译缓存是否堆积,执行清理。
  • 症状:缓存命中率低
    • 检查 TTL 是否过短或键设计不合理。
    • 确认外部缓存服务健康状态与连接池配置。
    • 分析热点键是否造成竞争,考虑本地缓存或分片。
  • 症状:会话丢失或过大
    • 检查会话存储路径权限与清理策略。
    • 审查会话写入逻辑,避免无界增长。
    • 对超大会话进行拆分或迁移至外部存储。

结论

通过在本项目中引入进程内存监控、缓存命中率监控、会话存储监控以及进程间通信监控,可以形成完整的可观测体系。结合趋势分析与优化建议,能够有效识别内存泄漏风险、提升缓存效率、稳定会话存储,并降低资源竞争带来的性能波动。建议在上线前完成指标采集与告警规则配置,并在日常运维中持续迭代优化。

附录

  • 建议采集的指标清单
    • 进程内存:RSS、堆内存、GC 次数/耗时。
    • 缓存:命中率、未命中率、延迟分布、错误率。
    • 会话:数量、大小、清理频率与失败率。
    • 外部缓存:连接池健康、超时、重试。
  • 建议的告警规则
    • 内存峰值超基线 + N% 持续 M 分钟。
    • 缓存命中率低于阈值持续一段时间。
    • 会话大小超过上限或清理失败率升高。
    • 外部缓存错误率或超时率异常。
添加日期:2026-10-05