# WecomCenter / ROMAN 定制中心 — 项目总结与验收 > 更新时间:2026-11-06 > 适用:Zabbix 7.4.x(已在 7.4.16 + MySQL 8.0.43 验证) > 模块目录:`web-modules/WecomCenter`(manifest `2.0.1`) ## 1. 一句话定位 一个不修改 Zabbix 源码、以 custom module 方式挂载的运维定制中心:把企业微信告警、模板调优、日常告警等级维护,以及 L2 物理拓扑集中在一个页面里。所有配置写 Zabbix 数据库,重建容器/升级镜像后仍在。 ## 2. 功能清单 ### 2.1 告警 Alert - 企业微信群机器人 Webhook Key 的单字段读写、测试发送。 - 5 套告警策略预设:先预览(dry-run,不写库)再应用;支持回滚。 - 按类别批量调整模板触发器 / 触发器原型 / 已发现触发器严重度;必告警类别固定 Disaster。 - 手动严重度勾选、媒介总开关。 - 一键初始化/自检:媒体类型、机器人用户、触发器动作、`{$WECOM_KEY}` 宏;已存在则复用。 ### 2.2 优化 Optimization - 按 小/中/大 规模生成 Zabbix server 调优参数(只生成 `.env` / compose 片段,不落地)。 - 导入真实华为模板 `Huawei VRP by SNMP walk`,并按旧模板→新模板批量切换设备(保留其它模板链接)。 - Geomap 单点标记。 ### 2.3 日常维护 Maintenance - 按类别批量改告警等级。 - 按单个触发器勾选开关告警、行尾下拉改严重度;保存后页面自动刷新。 - 所有探测节点(模板→主机)同步。 ### 2.4 L2 拓扑 Topology(本次重点) - **只读展示**:不做任何交换机配置写入,不创建用户,不改 VLAN/端口/STP。 - **协议真相**:交换机级联关系只来自 STP 指定桥 + MAC 学习;绝不使用 `ifAlias` 猜关系。 - **一张全局大图**:核心 → 网络主交换 → 车间汇聚/分布 → 接入,一级一列;车间框内按 GRD→1F→3F→4F→7F 楼层排列。 - **层级**:`防火墙 → 行为管理 → 总核心 → 分核心(监控核心/办公核心/未来生产核心)`;角色留空则完全不显示、不占位;空的未来生产核心保留一行但不激活。 - **7 天历史**:每次全量采集成功按 `full_interval_min`(默认 5 分钟)gzip 写 `l2_topology_history`,按 `history_days`(默认 7 天)清理;`refresh_alarms.sh` 只刷新实时 JSON,不写历史。 - **单面板时间选择器**:右上「快照时间」一个按钮打开一个面板,左侧只列实际有快照的日期(含“实时(最新)”),右侧列该日期实际时间点;不再使用两个并排 select,也不会出现选了日期时间仍灰色不可选。 - **展示能力**:告警整节点红填充;离线红填充;延迟 3–5ms 橙框、>5ms 红框;链路 100M 橙 / 1G 绿 / 2.5G 青 / 10G 蓝 / 20G+ 紫;终端端口矩阵区分“最大速率外圈”和“当前速率实心”。 - **导出**:PNG 固定日间模式,图例直接烘焙进 PNG(DOM 覆盖层不会被 `cy.png()` 导出)。 - **交互**:搜索、缩放、适应窗口、离线面板、终端面板、实时自动刷新/暂停。 - **PoE**:优先 RFC3621 / 华为 PoE MIB,固件不开放时用 ENTITY-MIB 型号描述兜底;离线/无响应不显示 ⚡️。 ## 3. 需求与实现对照 | 需求 | 状态 | 落点 | |---|---|---| | 增加 L2 物理拓扑,只读展示 | 完成 | `actions/L2TopologyView.php`、`views/topology.view.php`、`assets/l2topology/` | | 7 天历史、按天/时间回看 | 完成 | `l2_topology_history`、`L2Store`、`app.js` | | 配置页命名 ROMAN 定制中心 / ROMAN Custom Center | 完成 | 菜单、`page.title`、locale | | 拓扑层级:总核心/分核心/防火墙/行为管理 | 完成 | `L2Store::defaults()` 的 `core_hierarchy`、配置页 | | 留空角色不显示、不占空间 | 完成 | 拓扑布局按实际匹配节点生成 | | 时间选择器:选日期后时间不能灰 | 完成 | 单面板 popover,日期与时间联动 | | 不要两个选择框,要美观 | 完成 | `.l2-ts-picker` 单按钮 + 单面板 | | 图例进 PNG 导出 | 完成 | `app.js` 导出逻辑追加 canvas 图例 | | 移除“鼠标移到交换机上…”提示 | 完成 | 已删除 | | 告警块上移 | 完成 | 布局调整 | | 不破坏 Zabbix、不创建用户、协议真相只来自 STP/MAC | 遵守 | L2 无写交换机、无新用户;关系仅 STP/MAC | | 检查 git 是否上传、新 Zabbix 能否安装、compose 是否默认有功能、拓扑是否有初始化 | 完成/已修 | 见第 5、6 节 | ## 4. 关键实现说明 - 自定义表: - `l2_topology_config`:单行 `id=1`,`config` LONGTEXT,`updated` DATETIME。 - `l2_topology_history`:`ts`、`captured_at`、`stats`、gzip `snapshot` MEDIUMBLOB。 - Zabbix 模块内读自定义表必须用 `\DBselect()` + `\DBfetch()`,写入/DDL 用 `\DBexecute()`;不能用 `DB::select()`(它不是裸 SQL,且会查 Zabbix schema 缓存)。 - `L2Store::ensureSchema()` 在页面加载时幂等建表;`L2Store::initialize()` 额外在配置行缺失时写入默认配置(绝不覆盖已有配置)。 - 采集器:宿主机 `/opt/zabbix/l2collector/`,cron: - `*/5 * * * * /bin/bash /opt/zabbix/l2collector/run_full.sh` - `* * * * * /bin/bash /opt/zabbix/l2collector/refresh_alarms.sh` - `l2_due.py` 按 `full_interval_min` 控制全量采集频率;`L2_FORCE_FULL=1` 可强制一次。 - 单次全量采集同时写实时 `snapshot.json` 和一份历史;历史行实测约 33–36 KB gzip,7 天 @5 分钟约 65–75 MB。 ## 5. 安装与初始化 ### 5.1 全新 Zabbix(仓库 compose) 仓库 `docker-compose.yaml` 已包含: - `web-modules/` 挂载到 `/usr/share/zabbix/modules`; - `wecom-module-init` 一次性侧车:等待 MySQL 和 Zabbix `module` 表就绪(最多 300 秒)→ 幂等登记 `wecom_center`(status=1)→ 创建 L2 两张表。 - 全新环境 `docker compose up -d` 后模块已启用,无需手工点启用;打开页面后默认配置自动生效。 ### 5.2 已有 Zabbix(手动) ```bash cd web-modules ./install.sh # 自动探测 web/mysql 容器 # 或:./install.sh /opt/zabbix/zabbix-server/web-modules ``` `install.sh` 会复制模块、设置权限、建 L2 表、在 `module` 表已就绪时自动登记/启用模块、把 collector 安装到 `/opt/zabbix/l2collector` 并安装 cron(`INSTALL_CRON=0` 可跳过)。若 MySQL/`module` 表尚未就绪,会提示到 UI 启用。 ### 5.3 初始化入口 - **告警页「初始化 / 自检」**:原有告警链路初始化 + 顺带 `L2Store::initialize()`(拓扑表/配置)。 - **L2 拓扑配置页顶部「初始化 / 自检 L2 存储」**:只初始化 L2(建表 + 缺配置时写默认),不创建/修改用户或告警对象。 - 采集器 cron 不在容器里,必须按 `docs/使用说明.md` 10.4 在宿主机安装;这是“页面初始化”不会替用户做的部分。 ## 6. 本次验证记录 - PHP lint:`L2Store.php`、`WecomCenterSave.php`、`topology.view.php`、`wecom.center.view.php`、`locale/en.php`、`locale/zh_CN.php` 全部通过。 - L2 初始化按钮:真实页面点击返回「L2 拓扑初始化完成:配置已存在,历史快照 73 条。」,无 JS 错误。 - 拓扑工具栏按钮编码回归:`◷ 实时(最新) ▾`、`❚❚`、`+`、`−` 均正常显示,没有 `鈼?` / `鉂氣潥` / `锛?` 乱码;`topology.view.php` 的图标已改用 HTML 数字实体,`install.sh` 已增加 mojibake 源文件阻断检查。 - 单面板时间选择器(Playwright): - 日期 `["实时(最新)","2026-11-06 (15)","2026-11-05 (60)"]`; - 选日期后 label `2026-11-06 · 选择时间`,时间列表 15 项; - 点 `01:42:01` 后 URL 带 `ts=...`,label 正确显示; - `pageerror` / `console.error` 为空。 - `docker compose config -q`:仓库 compose 与生产 `/opt/zabbix/docker-compose.yaml` 均通过。 - 生产侧车实测日志: `[wecom-init] waiting for MySQL...` → `waiting for Zabbix schema (module table)...` → `module 'wecom_center' ensured (enabled) + L2 tables ensured.` - `install.sh` 在临时目录实测:复制模块、建表、幂等登记模块、安装 collector 均成功。 - 数据库:`wecom_center` moduleid=1001,status=1;`l2_topology_history` 行数持续增长;`l2_topology_config` 行存在。 ## 7. 已知限制 / 注意事项 - 采集器必须能访问交换机 SNMP(UDP 161)且安装 `snmpwalk` 等工具;容器默认不跑采集器。 - 历史体积随 `full_interval_min` 缩短迅速增长;1 分钟 @7 天约 300 MB 级,默认 5 分钟更稳妥。 - 拓扑是展示层,不改交换机;STP/MAC 采集不到时不会凭空画关系。 - 生产 `/opt/zabbix/docker-compose.yaml` 已加入侧车并留备份 `docker-compose.yaml.bak_wecom-init_*`;下次 `docker compose up -d` 会自动保持模块启用。 - 告警初始化会创建/复用 `wecomrobot` 用户(原有行为);L2 单独初始化不会创建任何用户。 ## 8. 代码与提交 - 分支:`master` - 远端:`origin/master` - 本次涉及:`web-modules/WecomCenter/{actions,lib,views,locale,assets/l2topology}`、`web-modules/install.sh`、`docker-compose.yaml`、`README.md`、`docs/使用说明.md` - 具体提交见 `git log --oneline`;最新提交包含:单面板时间选择器、L2 初始化、compose 首装时序修复、安装器自动启用模块。