2013-08-15

在线状态服务在网站系统中的应用

Views: 25892 | 18 Comments

我的前一篇博客文章"谈谈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 地址发给我, 大家一起交流.

补充: 其实本文是想通过这个例子来招聘人才.

Related posts:

  1. Libevent HTTP 内存泄露
  2. SSDB在大数据量日志分析中的应用案例
  3. 小数据与大数据
  4. 用 HBase 来存储 zset
  5. 让libevent HTTP服务器立即知道客户端的断开
Posted by ideawu at 2013-08-15 22:54:10

18 Responses to "在线状态服务在网站系统中的应用"

Leave a Comment