如何让政策数据在三个端保持同步?政策快报的实践方案
用户在政策快报平台的电脑网页上收藏了一条政策,打开手机App发现收藏列表里没有;在手机上阅读到一半的政策,切换到小程序又要从头开始翻。这种体验在多端产品中并不少见,但用户显然不会为此叫好。
政策快报平台支持手机端、电脑端、小程序三端数据实时同步。用户在任何一端的行为(收藏、阅读记录、申报任务状态)都会自动同步到其他端。本文从技术角度拆解这套多端同步架构的设计思路。
多端同步的三层架构
第一层:统一用户身份——同步的前提
多端同步的前提是:能够识别“这是同一个用户”。
方案选型:
| 方案 | 实现方式 | 优点 | 缺点 |
|---|---|---|---|
| 传统Session | 服务端存储会话 | 简单 | 移动端支持差,跨端困难 |
| JWT Token | 客户端存储加密令牌 | 无状态,易扩展 | 无法主动失效 |
| OAuth2.0 | 第三方授权 | 安全性高 | 实现复杂 |
政策快报的选型:JWT Token + 刷新Token双令牌机制。用户登录后服务端返回access_token(有效期2小时)和refresh_token(有效期7天)。access_token过期后使用refresh_token刷新,用户无需重新登录。
跨端设备绑定:
json
{ "user_id": "U10001", "devices": [ {"device_id": "web_chrome_xxx", "type": "web", "last_active": "2026-05-24 10:00:00"}, {"device_id": "ios_app_xxx", "type": "app", "last_active": "2026-05-24 09:30:00"}, {"device_id": "miniprogram_xxx", "type": "miniprogram", "last_active": "2026-05-23 20:00:00"} ] }用户可以在任意端查看已登录的设备列表,并支持远程踢出某个设备。
第二层:数据同步策略——实时性与成本平衡
多端同步的核心挑战在于:既要保证数据实时一致,又要控制服务器压力和网络流量。
政策快报的混合策略:
| 数据类型 | 同步策略 | 说明 |
|---|---|---|
| 用户基本信息 | 实时拉取 | 每次启动App/打开网页时拉取最新 |
| 收藏/关注 | 实时推送 + 轮询兜底 | 操作后立即推送,同时每5分钟轮询 |
| 阅读历史 | 本地缓存 + 定期上传 | 阅读记录先存本地,每10分钟批量上传 |
| 申报任务状态 | 实时推送 | 状态变更对时效性要求高 |
| 政策内容 | 按需拉取 + CDN缓存 | 政策内容变化频率低,无需实时同步 |
实时推送方案(WebSocket):
javascript
// 用户在一个端执行收藏操作 function onCollect(policyId) { // 1. 本地更新UI updateLocalCollectStatus(policyId, true); // 2. 发送API请求 api.collect(policyId).then(() => { // 3. 通过WebSocket推送消息到该用户的其他端 websocket.send({ type: 'SYNC_COLLECT', policy_id: policyId, action: 'add', timestamp: Date.now() }); }); }其他端收到推送消息后,自动更新本地缓存和UI,无需用户手动刷新。
离线场景处理:
移动端网络不稳定是常态。政策快报App和小程序实现了离线缓存机制:
用户浏览过的政策内容自动缓存到本地(有效期7天)
离线状态下的收藏、标记操作先存入本地队列
网络恢复后按顺序自动同步到服务端
第三层:冲突处理——多端同时操作怎么办?
用户可能在手机和电脑上同时操作,或者网络延迟导致先后顺序错乱。需要设计冲突处理规则。
政策快报的冲突处理规则:
| 场景 | 规则 | 示例 |
|---|---|---|
| 收藏/取消收藏 | 以后者为准 | 手机收藏、电脑取消收藏 → 最终为取消收藏 |
| 阅读进度 | 取最大值 | 手机读到50%,电脑读到80% → 同步后显示80% |
| 申报任务状态 | 以服务端为准 | 多端同时提交状态变更 → 服务端按接收顺序处理 |
| 用户资料修改 | 以后者为准,加冲突提示 | 多端同时修改手机号 → 提示用户确认 |
版本号机制(乐观锁):
sql
-- 用户设置表增加version字段 CREATE TABLE user_settings ( user_id VARCHAR(32), setting_key VARCHAR(64), setting_value TEXT, version INT DEFAULT 1, update_time TIMESTAMP ); -- 更新时检查版本号 UPDATE user_settings SET setting_value = 'new_value', version = version + 1 WHERE user_id = 'U10001' AND setting_key = 'notification_pref' AND version = 1;
如果version不匹配(说明已被其他端更新),更新失败,客户端需要重新拉取最新数据后再提交。
第四层:性能优化——让同步“无感”
多端同步的终极目标是:用户感觉不到同步的存在,一切都是“自然发生”的。
政策快报的优化手段:
| 优化点 | 方案 | 效果 |
|---|---|---|
| 接口响应速度 | Redis缓存热点数据,CDN加速静态资源 | P99响应时间<200ms |
| 首屏加载 | 关键数据优先加载,非关键数据懒加载 | 首屏时间<1.5秒 |
| 网络开销 | 增量同步(只传变化的数据),Gzip压缩 | 同步流量减少60% |
| 弱网体验 | 超时重试(3次),降级策略(优先展示缓存) | 弱网下仍可基本使用 |
架构总览
text
┌─────────────────────────────────────────────────────────────┐ │ 用户设备层 │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ Web端 │ │ App端 │ │ 小程序端 │ │ │ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ │ └───────────────┼──────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ API网关(统一入口) │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ┌──────────────┼──────────────┐ │ │ ▼ ▼ ▼ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ 用户服务 │ │ 数据服务 │ │ 推送服务 │ │ │ │(JWT/设备) │ │(CRUD/缓存) │ │(WebSocket) │ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │ │ │ ┌──────────────┼──────────────┐ │ │ ▼ ▼ ▼ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ PostgreSQL │ │ Redis │ │ Kafka │ │ │ │ (主数据) │ │ (缓存) │ │ (消息队列) │ │ │ └────────────┘ └────────────┘ └────────────┘ │ └─────────────────────────────────────────────────────────────┘
政策快报平台的多端同步架构仍在持续演进中。下一步的方向包括:
智能预加载:根据用户的使用习惯,预判可能在另一端访问的内容,提前同步到本地
端到端加密:敏感数据(如企业财务信息)在客户端加密后再上传,服务端只存储密文
离线完整模式:在无网络环境下,用户仍可完成申报材料的填写和保存,网络恢复后自动提交
如果你也在从事多端同步或移动端架构相关的开发工作,欢迎在评论区交流你在冲突处理、离线缓存或推送服务方面的实践经验。
