nginx_perl试用

因为空闲时间比较多,所以在CPAN上乱翻,看到了nginx_perl这个项目(原名Nginx::Engine),现在托管在github.com上。地址见:https://github.com/zzzcpan/nginx-perl

这个模块的目的,是在nginx内置官方perl模块的基础上,实现一系列异步非阻塞的api。用connector/writer/reader完成类似proxy的功能(这里因为是交给perl完成,所以不单单局限在http上了),用take_connection/give_connection完成类似websocket的功能,用ssl_handshaker完成ssl的解析,用timer完成定时器,用resolver完成域名解析…使用方法简单来说,就是用main_count_inc/finalize_request控制计数器,用NGX_READ/NGX_WRITE/NGX_CLOSE等控制callback。

其他内容和apache的mod_perl,或者nginx.org的perl类似。最新版的POD地址见:http://zzzcpan.github.com/nginx-perl/Nginx.html

最后举例一个自己写的简单的例子:

package HelloWorld;
use Nginx;
use strict;
#用来在nginx启动的时候做的事情,这里单纯显示一下
sub init_worker {
    warn 'nginx_perl start [OK]';
};
#这里是nginx的http模块中调用的handler,alexander有计划改成tcp级别的
sub handler {
    my $r = shift;
#增加主循环的计数器
    $r->main_count_inc;
#使用非阻塞的连接器连接127.0.0.1的80端口,10秒超时
    ngx_connector '127.0.0.1', 80, 10, sub {
#如果连接出问题,会记录在$!中
        if ($!) {
            $r->send_http_header('text/html');
            $r->print("Connection failed, $!\n");
            $r->send_special(NGX_HTTP_LAST);
#不管怎么处理这次连接,最后一定要记得用$r->finalize_request(),会decrease之前$r->main_count_inc;里加上的计数。
            $r->finalize_request(NGX_OK);
            return NGX_CLOSE;
        };
#返回$c是建立的连接
        my $c = shift;
        my $req_buf = "GET /index.php HTTP/1.0\x0d\x0a".
              "Host: chenlinux.com\x0d\x0a".
              "Connection: close\x0d\x0a".
              "\x0d\x0a";
#这里记住定义buffer的时候不要搞成undef了,会报段错误的,不过俄国佬回信说他修复了
        my $res_buf = '';
#非阻塞写入,超时10秒
        ngx_writer $c, $req_buf, 10, sub {
            if ($!) {
                 ......
            };
            $req_buf = '';
#之前的buffer测试就是这里,如果加一个warn,就不会报错……汗
#warn "$req_buf\n$res_buf\n";
#写入完成后,开始调用读取
            return NGX_READ;
        };
#读取到buffer,最短0字节,最长8000字节,超时10秒
        ngx_reader $c, $res_buf, 0, 8000, 10, sub {
            if ($!) {
            ......
            }
            $r->send_http_header('text/html');
            $r->print($res_buf);
            $r->send_special(NGX_HTTP_LAST);
            $r->finalize_request(NGX_OK);
            return NGX_CLOSE;
        };
#这个是connector的语句,表示连接成功后调用写入
        return NGX_WRITE;
    };
#各个非阻塞调用完成后的返回,NGX_DONE只能用在http的handler里,不能在ngx_*r里用,里面请用NGX_CLOSE。
    return NGX_DONE;
};
1;

另:源码中带有一个真正的反向http的例子Nginx::Util和一个Redis的例子。并且与nodejs读取redis的性能做了对比。可以参见~~

Perl在nginx里的应用

你可能感兴趣的:(nginx_perl试用)