Grafana Loki 日志聚合
解读
在国内一线互联网公司的 PHP 面试中,日志聚合已经从“加分项”变成“必答题”。面试官问 Loki,并不是想听你背官网定义,而是考察三点:
- 你是否理解 PHP 传统写文件日志的痛点(磁盘碎片化、检索慢、无法横向扩容);
- 你是否能给出云原生时代的低成本替代方案(Loki vs ELK/EFK);
- 你是否真正落地过:PHP 项目如何无侵入地把日志送进 Loki,并在 Grafana 做多维度检索、告警、链路追踪。
因此,回答必须围绕“PHP 业务场景 + Loki 架构细节 + 国内云厂商实践”展开,既要体现技术深度,又要给出可落地的配置片段和排障经验。
知识点
- Loki 架构:Distributor → Ingester → Querier,索引与数据分离,仅对标签建索引,存储可对接阿里云 OSS、腾讯云 COS、MinIO。
- 标签设计哲学:高维度、低枚举值;切忌把用户 ID、订单号直接做标签,否则会出现“小文件爆炸”导致 OOM。
- PHP 日志驱动:monolog/monolog 3.x 原生支持 LokiHandler,底层走 HTTP POST /loki/api/v1/push,批量打包、异步非阻塞。
- 国内网络优化:VPC 内网域名 + HTTP Keep-Alive + gzip 压缩,可把延迟从 80 ms 降到 8 ms,单核 PHP-FPM QPS 提升 15%。
- 安全合规:传输层必须启用 TLS1.3,日志内容若含手机号、身份证,需在 PHP 端先做脱敏(正则替换 + 敏感词库),否则无法通过等保 2.0 审计。
- 成本对比:同等 100 GB/天 日志量,ELK 需要 3 台 8C16G + 2 TB SSD,月费用 1800 元;Loki + OSS 低频型,月费用 260 元,仅为前者 1/7。
- 常见坑:Ingester 默认 1 h 落盘,如果 PHP 业务突发 5 倍流量,可能出现“too many open files”,需调优 ulimit 与 ingester.max-transfer-retries。
答案
“我在上一家电商公司负责订单服务,峰值 3 万单/秒,PHP 模块原来用 file_put_contents 写本地 log,磁盘 IO 占满后常把 SSD 打挂。去年我们决定用 Grafana Loki 做日志聚合,整体分三步:
第一步,改造日志通道。monolog 3 内置 LokiHandler,我新增了一个 StreamHandler 做双写:本地保留 24 h 用于应急,Loki 做长期存储。标签只选固定的 4 个维度:service=order-api、dc=beijing、k8s_pod、level。为了防止高枚举,我把订单号做成日志内容字段,而不是标签。
第二步,部署 Loki 集群。我们采购了阿里云 ACK + OSS 低频型,Distributor 和 Querier 各 2 副本,Ingester 3 副本,每副本 4C8G。OSS Bucket 开同城冗余,存储费用 0.08 元/GB/月。通过内网 DNS 解析,PHP-FPM 到 Distributor 的 RT 平均 8 ms,p99 18 ms,对业务几乎无感知。
第三步,Grafana 侧建立模板变量,按 service、pod、level 下拉检索,并配置告警:当 5 分钟内 ERROR 日志占比超过 1% 且数量大于 100 条时,飞书 Webhook 通知。告警规则用 LogQL:
sum(rate({service="order-api",level="ERROR"}[5m])) by (pod) > 0.01 and sum(count_over_time({service="order-api",level="ERROR"}[5m])) by (pod) > 100
上线三个月,我们成功把日志检索平均耗时从 3 分钟降到 5 秒,硬件成本下降 75%,并且通过了等保 2.0 三级测评。”
拓展思考
- 多租户隔离:如果公司内有 20 个 PHP 微服务,如何基于 Loki 的 boltdb-shipper 做租户级别的存储与查询权限隔离?可以考虑在 nginx 网关层加 X-Scope-OrgID 头,配合 Grafana 的 Folder ACL。
- 链路追踪融合:Loki 与 Jaeger 的 TraceID 如何打通?在 PHP 端把 TraceID 注入日志内容,Grafana 10 的“Logs to Traces”功能可直接跳转,实现“日志—链路—指标”三合一排障。
- 边缘计算场景:国内直播客户常把 PHP 边缘节点部署在三四线城市机房,网络不稳定。可研究 Loki 的 Promtail 双缓冲 + 本地 WAL,断网时先写磁盘,恢复后自动重传,保证不丢日志。
- Serverless 冷启动:函数计算(阿里云 SAE、腾讯云 SCF)中 PHP 实例生命周期极短,如何把 50 ms 内的日志快速送到 Loki?可用 UDP + Grafana Agent 的 flow 模式,异步聚合后再转 HTTP,避免短连接开销。
- 国产化适配:在金融或政企项目,要求数据库、中间件全国产。Loki 的索引底层可替换为国产 TiKV 或 OceanBase 的 KV 接口,存储用国产 XSKY 对象存储,已完成 POC,性能下降 <8%,可接受。