几年前做过一个项目评估,甲方是一家做园区WiFi运营的公司,他们用的WiFi网络计费系统经常在高峰期出现认证超时和计费延迟的问题。看了一圈日志以后发现问题不在计费系统本身的逻辑上,而在底层数据库的性能上——高峰期并发认证请求一多,数据库的写入队列就开始排队,认证响应时间从一两百毫秒飙到两三秒甚至更长。
认证和计费的并发压力到底有多大WiFi网络计费系统的并发压力的特点跟传统的Web应用完全不同。传统的Web应用是用户主动访问才有请求,但WiFi计费场景多是设备自动发起的——用户手机连上WiFi以后自动触发认证流程,认证成功以后NAS自动发送计费报文,用户切换AP的时候又触发重新认证。这意味着系统的请求量不是用户主动操作的量,而是所有在线设备的总量。几千台设备在同一个时间段内连上WiFi所产生的并发请求量,比同等用户规模的Web应用要高出好几个数量级。
举个例子:一个商场早上十点开门,半小时内可能有上千台设备同时尝试连接WiFi。每一台设备的认证流程至少涉及两到三次RADIUS报文交互(Access-Request/Access-Accept或者Access-Challenge),再加上后续的计费报文。短时间内涌过来的报文量如果超过了WiFi网络计费系统的处理能力上限,就会出现排队甚至丢包。
数据库层的性能瓶颈和优化策略大部分WiFi网络计费系统的性能瓶颈都在数据库上。认证过程中需要查询用户账号、验证密码、检查账户余额和套餐状态,每一步都在读数据库;计费报文的写入又是高频的写操作。如果用户名和密码表的查询没有合适的索引,上万用户的系统在高峰期就扛不住。
常见的优化方向有几个:第一,热点数据放Redis里,用户基本信息、套餐信息这些高频读取的数据,在用户首次认证的时候从MySQL加载到Redis,后续的认证直接从Redis读,响应延迟从几十毫秒降到一毫秒以内。第二,计费写入做批量处理,不要每收到一条Accounting报文就写一次数据库,而是内存里攒一批(比如五十条或者五百毫秒内的所有报文)再批量写入。第三,读写分离,认证请求走读库,计费写入走写库,互不干扰。
RADIUS服务本身的并发处理能力WiFi网络计费系统里的RADIUS服务本身的并发处理能力也很关键。FreeRADIUS默认的线程配置通常偏保守,在生产环境中需要根据实际硬件条件做调整。另外RADIUS用的是UDP协议,UDP没有连接的概念,所以RADIUS服务在操作系统层面的socket缓冲区大小和接收队列长度也会直接影响高并发下的丢包率。
如果单节点的RADIUS服务已经无法满足并发需求了,下一步就是RADIUS集群加负载均衡。前面放一个LVS或者Nginx UDP Stream做四层负载均衡,后面挂多个RADIUS节点,每个节点独立处理一部分请求。这种架构下需要注意的一点是RADIUS的响应报文必须原路返回——NAS把请求发给了负载均衡器,负载均衡器转发给了节点A,节点A的响应必须通过负载均衡器回到NAS,不能直接回给NAS,否则NAS会认为响应来源IP跟请求目标IP不一致而丢弃。
监控和容量规划:不要等到高峰期才想起来看性能WiFi网络计费系统的性能监控应该覆盖几个关键指标:每秒认证请求数(Auth TPS)、每秒计费报文处理数(Accounting TPS)、平均认证响应延迟、P99认证响应延迟、RADIUS消息队列长度、数据库慢查询数量。正常情况下的这些指标值就是你的基准线,一旦某个指标偏离基准线超过一定比例,就应该触发告警。
容量规划方面,建议至少按实际峰值的两倍来设计系统容量。因为WiFi使用场景的并发是高度集中的——午饭时间、晚上八点到十点、周末下午,这些时段的高峰很容易达到平常值的五到十倍。如果你按平时负载来设计容量,高峰期一定会出问题。高并发性能优化在WiFi网络计费系统里不是一次性的工作。用户规模增长、新业务功能上线、第三方接口的变化,都会持续影响系统性能。建议把性能基线数据纳入日常运维监控,每次做版本升级或者配置变更之后都跑一轮性能回归测试。性能问题发现得越早,修复成本越低,对用户的影响也越小。等到用户已经开始投诉"WiFi认证太慢了"的时候,优化窗口已经过了大半。另外还有一个经常被忽视的点:性能优化的优先级不是均匀的。认证响应延迟的优化优先级应该是最高的,因为它直接影响用户体验;计费写入性能次之,影响的是内部运营效率;报表查询性能优先级最低,因为它既不影响用户也不影响实时运营。