frankenphp自身不内置mercure服务,mercure是独立的sse实时推送服务,须作为单独deployment部署;hpa只能作用于mercure自身deployment,不可跨服务联动,且需统一jwt密钥、共享redis后端并禁用service/ingress会话亲和性以保障扩容有效性。

FrankenPHP 自身不内置 Mercure 服务,Mercure 是一个独立的、基于 Server-Send Events(SSE)的实时推送服务,通常以 mercure 二进制或 Docker 镜像形式单独部署。你在 Kubernetes 中要水平扩容 Mercure,和 FrankenPHP 是否在用它无关——关键是你怎么部署和伸缩 Mercure 本身。
为什么不能直接对 FrankenPHP Deployment 做 HPA 来扩 Mercure?
Mercure 不是 FrankenPHP 的子进程,也不是它容器里的一个可选组件;它是外部依赖服务,运行在独立 Pod 中。即使你把 mercure 和 frankenphp 打进同一个镜像、共容器部署,也违背了十二要素和 K8s 的“一个容器一个关注点”原则,且无法健康探针分离、指标采集混乱、扩缩容逻辑耦合——HPA 会误判:CPU 高是因为 PHP 处理慢,还是 Mercure 在广播大量事件?
- FrankenPHP 容器里只该跑 PHP 应用进程(
frankenphp-worker或frankenphp-server) - Mercure 必须作为独立 Service + Deployment 部署,通过
http://mercure:8080这类 DNS 名被 FrankenPHP 调用 - HPA 只能作用于 Mercure 的 Deployment,不能跨服务联动
如何给 Mercure Deployment 配 HPA(v2beta2+)
Mercure 官方镜像(dunglas/mercure)暴露了 /metrics 端点(Prometheus 格式),但默认不启用。你需要先确认它是否已接入 Metrics Server 或 Prometheus Adapter,否则 HPA 拿不到指标。
- 确保集群已部署
metrics-server(kubectl get apiservice v1beta1.metrics.k8s.io应为True) - Mercure Pod 必须有
resources.requests(HPA 要求),例如:cpu: 100m,memory: 128Mi - 推荐用
type: Resource+cpu做初始 HPA,避免过早引入自定义指标复杂度
示例 HPA 配置(mercure-hpa.yaml):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: mercure-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: mercure
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
Mercure 扩容后连接数不均?注意 StatefulSet vs Deployment
Mercure 本身是无状态的,但它依赖底层连接保持和事件广播一致性。如果你发现新扩容的 Pod 接收不到客户端连接,大概率是 Ingress 或 Service 的 sessionAffinity 配置问题,而非 Mercure 自身缺陷。
- Service 层必须禁用
sessionAffinity: ClientIP(默认就是None),否则客户端被固定到某 Pod,扩容无效 - Ingress(如 Nginx Ingress)若启用了
affinity: cookie,也要关掉;Mercure 的 SSE 连接应被轮询分发 - Mercure 的
PUBLISHER_JWT_KEY和SUBSCRIBER_JWT_KEY必须所有副本一致,否则签名验证失败,订阅中断 - 不要用
StatefulSet部署 Mercure——它不需要稳定网络标识,Deployment 更合适
想按实时订阅数扩缩?得上自定义指标(Prometheus + kube-metrics-adapter)
Mercure 的 /metrics 暴露了 mercure_subscribers_total 计数器。但 HPA 默认不认这个指标,必须通过 prometheus-adapter 注册为 External Metric。
- 先确认 Prometheus 已 scrape 到 Mercure 的指标(查
curl http://mercure:8080/metrics | grep mercure_subscribers_total) - 配置
prometheus-adapter的 rules,将mercure_subscribers_total映射为 external metric,比如叫mercure_subscribers - HPA 改用
type: External,target 设为平均每个 Pod 承载 500 订阅者:averageValue: 500
这步跳过的话,仅靠 CPU 利用率扩缩 Mercure,在低流量高连接场景下(比如长连接保活)会严重滞后——CPU 很低,但连接已打满。
真正容易被忽略的是:Mercure 的水平扩容不是“加 Pod 就完事”,它要求所有副本共享同一套 JWT 密钥、使用同一套 Redis(如果启用了 Redis 后端做广播),并且你的客户端必须支持重连(SSE 默认重连)。没配好 Redis 或密钥不一致,扩容后的 Pod 就是孤岛。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











