nginx 中移动端与 pc 端分流应使用 map 预解析 user-agent 生成 $is_mobile 变量,配合双 upstream 隔离后端、差异化缓存及爬虫兼容处理,并支持灰度与地域等扩展控制。

在 Linux 的 Nginx 中实现移动端与 PC 端分流,核心不是靠“智能判断”,而是把设备识别规则写成确定、高效、可维护的配置。关键在于避免运行时重复解析 User-Agent,同时确保后端隔离、缓存不混用、 fallback 不缺失。
用 map 预解析 UA,生成可靠布尔变量
不要在 location 里反复用 if + 正则匹配 User-Agent——性能差且易出错。应在 http 块顶部用 map 指令一次性映射:
- 显式包含 iPad:它默认被 UA 识别为桌面设备,必须单独加一行 ~*ipad 1;
- 覆盖主流标识:mobile、android、iphone、ios(大小写不敏感,用 ~*)
- default 必须设为 0:防止未匹配 UA 导致 $is_mobile 为空,引发 proxy_pass 失败
示例:
map $http_user_agent $is_mobile {~*mobile 1;
~*android 1;
~*iphone 1;
~*ipad 1;
~*ios 1;
default 0;
}
双 upstream 物理隔离后端服务
移动端和 PC 端通常对应不同接口能力、资源结构、部署节奏,不能共用同一组后端:
- 定义两个独立 upstream 块,如 mobile_backend 和 pc_backend,各自指向真实服务地址(IP:Port 或 Kubernetes Service)
- 每个 upstream 启用基础健康检查:max_fails=2 fail_timeout=30s
- 在 location 中用 if 分支转发,但必须在 if 外写 fallback ——否则未命中时会返回 500
正确写法(放在 server 或 location 内):
if ($is_mobile) {proxy_pass http://mobile_backend;
}
proxy_pass http://pc_backend;
差异化缓存与爬虫兼容处理
搜索引擎爬虫(如 Googlebot-Mobile)带 Mobile 字样,但需走 PC 分支以保障 SEO 一致性:
- 在 map 中增加爬虫 UA 排除逻辑,例如:~*Googlebot-Mobile 0,强制归入 PC 分支
- 为 mobile_backend 设置较短缓存:proxy_cache_valid 200 302 10m
- 为 pc_backend 启用强静态缓存:expires 1h + add_header Cache-Control "public, max-age=3600"
- 若启用 proxy_cache,cache key 必须含 $is_mobile,否则 PC 用户可能看到缓存的移动端页面
支持灰度与手动干预的扩展点
设备类型只是第一层维度,上线新功能时需叠加更多控制:
- 用 split_clients 对移动端用户再切 5% 到新接口:split_clients "$cookie_uid" $mobile_v2 { * 95%; 5% .v2; }
- 结合 geo 模块限制某地区仅开放移动端入口,比如海外只推 PWA
- 通过自定义 header(如 X-Env: staging)或 cookie 触发实验分支,方便运维临时切换











