参考资料:Comet--基于 HTTP 长连接、无须在浏览器端安装插件的“服务器推”技术为“Comet”
MochiWeb--建立轻量级HTTP服务器的Erlang库
-
// TODO - gracefully handle failure / reconnect / etc
-
pthread_exit ( 0 ) ;
-
}
-
-
int main ( int argc, char **argv )
-
{
-
// Launch the thread that runs the cnode:
-
pthread_attr_t tattr;
-
pthread_t helper;
-
int status;
-
pthread_create ( &helper, NULL , cnode_run, NULL ) ;
-
-
int i;
-
for ( i= 0 ;i<=MAXUSERS;i++ ) slots [ i ] =i;
-
// Launch libevent httpd:
-
struct evhttp *httpd;
-
event_init ( ) ;
-
httpd = evhttp_start ( "0.0.0.0" , 8000 ) ;
-
evhttp_set_gencb ( httpd, request_handler, NULL ) ;
-
event_dispatch ( ) ;
-
// Not reached, event_dispatch() shouldn’t return
-
evhttp_free ( httpd ) ;
-
return 0 ;
-
}
最大用户数由#defined定义, 类似提及的mochiweb服务器, 他监听在8000端口,期待着用户用/test/<userid>的形式连接,erlang节点的名称被硬编码,他将为接收消息连接 httpdmaster@localhost
, erlang cookie, “secretcookie”. 相应的改变这些。
首先运行连接的erlang节点:$ erl -setcookie secretcookie -sname httpdmaster@localhost
编译运行:$ gcc -o httpdcnode httpdcnode.c -lerl_interface -lei -levent
$ ./httpdcnode
在erlang shell, 检查你能看到隐藏的c-node:erl> nodes(hidden).
[c1@localhost]
现在在你的浏览器中连接 http://localhost:8000/test/123
. 你将看到欢迎信息.
现在回到erlang shell - 向C节点发送一条消息:
erl> {any, c1@localhost} ! {123, <<"Hello Libevent World">>}.
注意我们没有用pid,以此我们用另外一种形式 {procname, node}.我们用 ‘any’ 作为进程名称,它可以被C节点忽略。
现在你能够通过erlang传递comet消息, 但是所有的http连接都被用libevent C语言编写的erlang节点管理。
在删除debug打印语句后, 我用同一个上面提到的客户端向http C节点服务器连接1M个用户, 这台机子显示少于10G的内存被使用。服务器进程常驻内存稳定在2G以下:
因此, 当处理大量连接时相比较webchiweb有很大的节省,对于用libevent服务器进程每个连接的常驻内存低于2KB。所有的都连接后,服务器状态如下:Mem: 32968672k total, 9636488k used, 23332184k free, 180k buffers
每个连接的内核/tcp 栈占了另外8KB内存, 看起来有点高,但是我没有基础对象用来与之比较。libevent-cnode服务器需要多点的工作 . 他还不能聪明的处理从同一个用户来的多连接, 没有锁,假如你在一个消息被分发出去后断开连接,这时就有一个竞争条件存在.
即使这样, 我想这将被普遍化,以这种方式,他允许你用 Erlang 做很多有意思的事, 有一个C+libevent进程充当一个默默无闻的连接池 . 通过更多的包装代码和回调到erlang,你几乎不需要知道这个怎么运行的-C程序作为一个驱动或者一个C节点运行,一个Erlang包装器能给你一个合适的建筑于libevent的api. (看 这个 ,一个Erlang C驱动). 我将来在这上面会尝试更多。
最后的思考
我现在有足够的数据判断假如我为Last.fm发布一个大的伸缩性的comet系统我到底需要多少硬件. 即使每个连接40KB有些浪费但不是过分的-内存很便宜,40GB能支持一个百万用户的系统不过分. 10GB更好. 我将完成这个应用,我将在哪个地方构建发布它,人们可以试用它. 顺着这条路我将整理erlang memcached客户端,我正在用且分发他