现在的位置: 首页 > 综合 > 正文

nginx轻松实现comet服务器推

2013年11月13日 ⁄ 综合 ⁄ 共 3597字 ⁄ 字号 评论关闭

前不久偶尔发现nginx一个实现服务器推的模块NGiNX_HTTP_Push_Module,尝试了一下,可以轻松实现服务器推,而且由于nginx服务器自身是采用事件驱动而非线程模型提供服务,可以保证高并发低延迟的特点。

首先下载nginx_http_push_module模块安装

./configure –add-module=path/to/nginx_http_push_module …
make
make install

修改nginx.conf配置文件,这里我尽量简化模块指令的配置

location /publish {
        set $push_channel_id $arg_id;
        push_publisher;                   #发布者
}
 
location /activity {
        push_subscriber;                  #订阅者
        set $push_channel_id $arg_id;
}

然后启动nginx,一切工作完毕,来测试一下nginx的“发布-订阅”功能吧。

打开浏览器访问http://localhost/activity?id=10000,我们可以看到服务器端维持了这个长连接,并不返回内容或者任何4xx,5xx的http状态码。

(其中id=10000表示通道号,“id”是$arg_id变量去掉前缀后的名称)

编辑perl脚本

#!/usr/bin/perl
 
use LWP::UserAgent;
use HTTP::Request::Common;
my $ua = new LWP::UserAgent;
my $response = $ua->request(
        POST 'http://127.0.0.1//publish?id=10000',
        Content_Type => 'text/html',
        Content => 'hi,i posted a message'
);
my $content = $response->content;
print $content;

保存并执行perl脚本向指定通道发布消息,然后我们可以看到浏览器接收到订阅通道的消息’hi,i posted a message’。

做完上面的实验,我们再来看看模块的具体的命令:

  1. 首先是push_subscriber [ long-poll | interval-poll ]指定订阅者角色,默认选择长轮询long-poll,如果指定interval-poll,则服务器端会在订阅通道没有消息时立即返回304Not
    Modified状态。
  2. 可以通过配置push_subscriber_concurrency [ last | first | broadcast ] 控制订阅者获取通道消息的顺序,默认是“广播”方式,last表示通道保持最后一个长连接,其它长连接返回409冲突错误。
  3. 还有其它控制通道消息的指令

      •     push_store_messages [ on | off ],是否保存发布的消息
      •     push_max_reserved_memory [ size ] ,存储消息空间大小
      •     push_message_timeout [ time ],消息过期时间
      •     其它指令可以参照模块的使用手册

测试一:我们来做个简单的压力测试并发的效果,在10000通道没有消息队列时,用apache自带工具模拟并发500的测试,然后查看vmstat,可以看到系统内存和cpu都没有被占用,只是磁盘IO有所变化,存在写磁盘,随即恢复正常

vm6245:/usr/sbin # ab2 -c 500 -n 10000 http://localhost/activity?id=10000
vm6245:~/penjin # vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0  12312 317364  19056  17480    0    0     0     3    8    5  0  0 100  0  0
 0  0  12312 317364  19116  17420    0    0     0    60   38   14  0  0 99  1  0
 0  0  12312 317372  19116  17420    0    0     0     0   17    9  0  0 100  0  0
 0  0  12312 317372  19116  17420    0    0     0     0   19    7  0  0 100  0  0

测试二:而当通道有了消息发布后,再通过ab测试结果如下

vm6245:/usr/sbin # ab2 -c 500 -n 10000 http://localhost/activity?id=10000
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Finished 10000 requests


Server Software:        nginx/1.1.13
Server Hostname:        localhost
Server Port:            80

Document Path:          /activity?id=10001
Document Length:        21 bytes

Concurrency Level:      500
Time taken for tests:   1.191773 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2580000 bytes
HTML transferred:       210000 bytes
Requests per second:    8390.86 [#/sec] (mean)
Time per request:       59.589 [ms] (mean)
Time per request:       0.119 [ms] (mean, across all concurrent requests)
Transfer rate:          2113.66 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   24  22.4     18      74
Processing:     6   30  11.8     36      46
Waiting:        0   13   8.8     11      34
Total:          8   54  32.5     53     117

Percentage of the requests served within a certain time (ms)
  50%     53
  66%     71
  75%     82
  80%     88
  90%    101
  95%    107
  98%    112
  99%    113
 100%    117 (longest request)

我们可以看出500并发的情况下,响应速度还是不错的,同时vmstat显示可以看出 程序内存影响不大,cpu占用很快也得到恢复
vm6245:~/penjin # vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  12312 319588  20696  20000    0    0     0     3    8    5  0  0 100  0  0
 3  0  12312 310776  20700  20516    0    0     0     0  198 23935 10 20 70  0  0
 0  0  12312 314864  20820  21176    0    0     0  1244  524 15876 11 31 56  4  0
 0  0  12312 315484  20820  21176    0    0     0     0   28   15  0  0 100  0  0
 0  0  12312 315484  20820  21176    0    0     0     0   20    6  0  0 100  0  0
 0  0  12312 315656  20820  21176    0    0     0     0   19   12  0  0 100  0  0

我们主要关注测试一的结果,系统在维持长连接的时候cpu,内存,磁盘IO的压力都不大。网上有人说到NGiNX_HTTP_Push_Module模块存在内存问题,因为保持长连接的内存没有适时得到释放,但在我的测试中看不出来,不知道这种说法是否属实。

抱歉!评论已关闭.