1. 项目背景与需求分析
在移动互联网时代,WiFi连接已经成为线下商业场景的基础设施。传统WiFi连接方式存在诸多痛点:用户需要手动输入冗长的密码、商户无法获取用户信息、缺乏有效的营销渠道等。我们团队经过市场调研发现,超过78%的用户在公共场所连接WiFi时遇到过困难,而商户则普遍希望将WiFi服务转化为营销工具。
这个WiFi扫码连接系统正是为解决这些问题而生。它通过二维码技术实现一键连接,同时为商户提供用户触达、广告投放和收益分账等增值功能。系统需要满足以下核心需求:
-
用户端需求:
- 扫码即可连接WiFi,无需手动输入密码
- 连接过程不超过3秒
- 支持微信小程序原生体验
-
商户端需求:
- 多级账号管理体系(总部-分店)
- 自定义连接后跳转页面(广告/菜单)
- 实时数据统计看板
-
系统级需求:
- 支持日均10万+连接请求
- 广告曝光数据误差率<0.1%
- 资金结算准确率100%
技术选型时我们特别注重框架的成熟度和团队技术栈匹配度。经过对比测试,Egg.js在Node.js框架中表现出最佳的稳定性和开发效率,这也是我们最终选择它的关键原因。
2. 技术架构设计
2.1 整体架构设计
系统采用经典的三层架构设计,各层职责明确:
code复制┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 客户端层 │ │ 接口层 │ │ 服务层 │
│ (微信小程序/Web) │───▶│ (路由/鉴权) │───▶│ (业务逻辑处理) │
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
▼
┌─────────────────────┐
│ 数据层 │
│ (MySQL/Redis/OSS) │
└─────────────────────┘
这种分层设计带来了三个显著优势:
- 职责分离,各层可独立演进
- 便于横向扩展,如单独扩容接口层应对流量高峰
- 测试更聚焦,单元测试只需mock相邻层
2.2 核心服务拆分
系统由6个微服务组成,通过轻量级RPC通信:
- 认证服务:处理JWT签发/验证
- 二维码服务:生成/解析二维码
- WiFi服务:管理热点配置
- 广告服务:广告投放与统计
- 结算服务:收益计算与分账
- 日志服务:集中式日志收集
每个服务都遵循以下设计原则:
- 独立数据库schema
- 接口幂等设计
- 熔断降级机制
- 监控埋点
3. 关键技术实现
3.1 二维码生成方案
我们对比了三种二维码生成方案:
| 方案 | 生成速度 | 容错率 | 复杂度 | 最终选择 |
|---|---|---|---|---|
| QRCode.js | 快 | 低 | 简单 | × |
| node-qrcode | 中 | 中 | 中等 | √ |
| 腾讯云API | 慢 | 高 | 复杂 | × |
选择node-qrcode的核心考量是:
- 服务端生成更安全(避免WiFi密码泄露)
- 支持动态内容替换
- 容错率可配置(我们使用L级别)
关键代码实现:
javascript复制const QRCode = require('qrcode')
const generateWifiQR = async (ssid, password) => {
const wifiConfig = `WIFI:T:WPA;S:${ssid};P:${password};;`
return await QRCode.toDataURL(wifiConfig, {
errorCorrectionLevel: 'L',
margin: 2,
scale: 8
})
}
3.2 WiFi连接流程优化
传统连接流程存在两个性能瓶颈:
- 二维码解码耗时(平均300ms)
- 系统配置下发延迟(可达1s)
我们的优化方案:
- 预生成机制:提前生成常用WiFi的二维码base64缓存
- 短链跳转:二维码内容存储为短链,解码速度提升60%
- 长连接推送:建立WebSocket连接实时推送配置
优化后性能对比:
code复制| 步骤 | 优化前 | 优化后 |
|--------------|---------|---------|
| 扫码解码 | 300ms | 50ms |
| 获取配置 | 1000ms | 200ms |
| 总耗时 | 1300ms | 250ms |
3.3 广告系统设计
广告模块采用"曝光-点击-结算"三层架构:
-
曝光层:
- 基于Redis HyperLogLog去重
- 滑动窗口限流(100次/分钟)
- 设备指纹校验
-
点击层:
- 二次确认机制防误触
- Referrer校验防刷
- 异步日志上报
-
结算层:
- T+1对账机制
- 三级分账比例配置
- 自动提现处理
广告收益计算公式:
code复制单日收益 = Σ(曝光数 × 曝光单价) + Σ(点击数 × 点击单价)
4. 安全防护体系
4.1 认证安全
采用双Token机制增强安全性:
- Access Token:短期有效(2小时)
- Refresh Token:长期有效(7天)
- 绑定设备指纹防止盗用
Token生成算法:
javascript复制function generateToken(user) {
const payload = {
uid: user.id,
role: user.role,
iat: Date.now()
}
return jwt.sign(payload, SECRET_KEY, {
expiresIn: '2h',
algorithm: 'HS256'
})
}
4.2 数据安全
敏感数据采用三层加密:
- 传输层:HTTPS + 国密SM2
- 存储层:AES-256-CBC
- 密码字段:bcrypt哈希
特别对WiFi密码的处理:
javascript复制const encryptPassword = (password) => {
const salt = bcrypt.genSaltSync(10)
return bcrypt.hashSync(password, salt)
}
4.3 防刷策略
我们建立了五道防线:
- 设备指纹校验
- 行为分析模型
- 验证码挑战
- 请求频率限制
- IP信誉库
防刷规则配置示例:
yaml复制anti_cheat:
rules:
- name: '高频扫码'
threshold: 30次/分钟
action: '临时封禁1小时'
- name: '异常设备'
conditions:
- '无GPS信息'
- '模拟器特征'
action: '永久封禁'
5. 性能优化实践
5.1 数据库优化
针对MySQL的优化措施:
- 索引优化:为所有查询条件创建复合索引
sql复制ALTER TABLE qrcode_stats ADD INDEX idx_merchant_time (merchant_id, created_at) - 查询优化:使用覆盖索引减少回表
- 分表策略:按商户ID哈希分表
优化效果:
code复制| 查询类型 | 优化前 | 优化后 |
|---------------|-------|-------|
| 扫码记录查询 | 1200ms| 80ms |
| 广告统计 | 2500ms| 150ms |
5.2 缓存策略
采用多级缓存架构:
- 本地缓存:LRU缓存热点数据
- Redis缓存:
- 字符串缓存:配置数据
- 哈希存储:用户会话
- 有序集合:实时排行榜
- CDN缓存:静态资源加速
缓存更新策略:
- 配置类数据:定时刷新(5分钟)
- 用户数据:惰性更新 + 过期时间
- 统计类数据:写穿透 + 异步刷新
5.3 前端性能优化
管理后台的优化手段:
- 组件懒加载:
javascript复制const AdManagement = () => import('./views/AdManagement.vue') - 接口聚合:GraphQL替代REST
- 虚拟滚动:万级数据表格优化
- Web Worker:复杂计算后台执行
优化前后对比:
code复制| 指标 | 优化前 | 优化后 |
|---------------|-------|-------|
| 首屏加载 | 3.2s | 1.1s |
| 表格渲染 | 卡顿 | 流畅 |
6. 运维监控体系
6.1 日志系统
采用ELK架构处理日志:
- 日志分类:
- 访问日志(Nginx)
- 业务日志(应用)
- 错误日志(Sentry)
- 日志格式:
json复制{ "timestamp": "ISO8601", "traceId": "请求唯一标识", "level": "INFO/ERROR", "message": "日志内容" } - 日志告警:基于关键词触发企业微信通知
6.2 监控指标
核心监控指标包括:
- 系统健康度:
- CPU/Memory使用率
- 进程存活状态
- 业务指标:
- 扫码成功率
- 广告填充率
- 接口成功率
- 自定义指标:
- 分账差异率
- 用户留存率
使用Prometheus + Grafana构建看板:
yaml复制scrape_configs:
- job_name: 'node_app'
metrics_path: '/metrics'
static_configs:
- targets: ['app:3000']
6.3 灾备方案
为确保系统高可用,我们实施:
- 多可用区部署:跨机房容灾
- 数据备份:
- MySQL每日全备 + binlog
- Redis RDB+AOF
- 故障演练:
- 每月模拟数据库宕机
- 季度全链路压测
7. 项目演进路线
7.1 第一阶段:MVP验证
核心目标:验证扫码连接可行性
- 技术方案:纯前端生成二维码
- 数据统计:本地日志分析
- 耗时:2周
关键成果:
- 连接成功率92%
- 平均连接时间1.8s
7.2 第二阶段:商业化版本
新增功能:
- 多角色管理系统
- 广告投放平台
- 自动化结算
- 耗时:8周
技术升级:
- 引入Egg.js框架
- 实现JWT鉴权
- 接入微信支付
7.3 第三阶段:规模化运营
优化方向:
- 微服务化改造
- 分库分表
- 智能风控系统
- 耗时:6周
性能提升:
- 单机QPS从200提升至2000
- 结算时效从T+3到T+1
8. 经验总结与反思
在项目实施过程中,我们积累了几个关键经验:
-
二维码生成时机:初期采用实时生成导致接口响应慢,改为异步预生成后性能提升5倍。建议对静态内容提前生成缓存。
-
广告防刷策略:单纯依靠IP限制效果有限,引入设备指纹+行为分析后,刷量行为下降87%。关键是要建立多维度风控体系。
-
分账准确性:早期因浮点数计算出现0.1%的误差,改用decimal类型后问题解决。金融级计算必须使用精确数值类型。
-
小程序兼容性:不同厂商手机对WiFi接口支持度不同,最终我们增加了3种fallback方案。真机测试覆盖率要达到100%。
-
监控盲区:曾因Redis连接泄漏导致服务不可用,后来增加了连接池监控。所有中间件都要纳入监控范围。
这个项目给我们的最大启示是:技术方案必须与商业场景深度结合。比如在广告系统设计中,我们不仅考虑了技术实现,还研究了广告法相关规定,确保系统合规性。