我的前一篇博客文章” 谈谈Facebook的聊天系统架构“, 对Facebook的聊天系统架构进行了分析. 其中的有些思想和系统划分, 对即使不是做聊天系统, 如一般的网站系统, 也是很有借鉴意义的. 例如其中的在线状态服务器(Presence).
在线状态服务, 是这样的一个服务, 它维护了网站当前的在线用户列表, 接受其它模块的查询. 是实现统计网站同时在线人数, 维护在线用户列表等功能的基础服务. 在Facebook的聊天系统中, 在线状态是为聊天系统服务的, 所以在线状态是一种”强”在线, 也即用户保持着和Comet服务器的连接, 可随时接受服务器推送(push)的消息.
但在一般的网站应用中, 不要求强在线, 一般的在线即表示用户在最近几分钟刷新了网页. 而且, 网页中还可以用JavaScript启动一个定时器, 定期报告在线状态, 也就是向在线状态服务器发送心跳包.
对于某个同时在线100万人, 每天1亿PV的网站来说, 在线状态服务器一天接收到的心跳包大概是10亿个, 也即每秒10000个请求(10000qps). 要实现这样的在线状态服务器, 也是一个挑战.
最常见的实现方式, 就是 PHP + MySQL 的方法, 服务器在接收到心跳包时往数据库表插入一条用户在线记录, 或者更新这条记录的时间字段, 然后还有一个定时清理超时用户的进程. 这种方式 MySQL 很容易成为瓶颈.
于是, 第二种方法出现了, 就是把 MySQL 换成 Redis. 但是, PHP 本身的损耗也很大, 要单台服务器达到 10000qps 的性能几乎不可能.
再有一种方案就是用 C/C++ 开发专用的 HTTP 服务器, 完全整合逻辑处理(如 PHP)和存储(Redis). 因为这是一个专用的 HTTP 服务器, 可以只需要支持 HTTP 协议的一个精简子集, 可以用现成的库如 libevent 来做. libevent 同时提供了网络框架. 而存储部分, 可以设计一个精巧高速的内存数据结构, 应该可以比 Redis 性能高一些, 因为 Redis 是通用存储, 性能会有一些损耗. 根据 Redis 30000 到 50000 qps 的能力, 这样的一个 C/C++ 内存逻辑服务器应该能轻松达到单台服务器处理速度 10000qps, 也即每天处理 10 亿个请求.
看我博客的同学, 如果你能做出这样的一个服务器, 欢迎把 github 地址发给我, 大家一起交流.
你现在看的文章是: 在线状态服务在网站系统中的应用