SlideShare a Scribd company logo
Perl 与 Nginx 应用 —— jeff
题目的由来 perl 是 OPSer 最熟悉的 script language nginx 是 OPSer 最喜欢的 web server 相信我的 perl 和 nginx 水平都不是最好的,不过感谢 laird 的乱点鸳鸯谱,把它们凑在一起给我作讲题,大概或许可能仿佛应该想来我看过一些而大家没留意的吧  ^=^
提要 nginx 的主要功能 nginx 原生 perl 模块介绍 几个简单的例子 nginx 第三方模块 (ngx_js/ngx_lua) 介绍 nginx 增强版 perl 介绍 总结
nginx 的主要功能 nginx 主要分成 http 和 mail 两个部分,一般来说,我们的操作都是 http 部分的(奇怪的是 nginx-src 的 configure 选项里只有 --without-http 而没有 --without-mail ) http 中,最常用的标准模块是静态文件发布的 core ,反向代理的 proxy ,上游集群的 upstream ,重定向的 rewrite 等 …… 其他常用官方模块有: fastcgi/flv/mp4/gzip_static/limit_conn/uwsgi 等
nginx 与动态应用 nginx 的标准作用是静态文件发布( proxy_cache/proxy_store 的结果也是静态文件发布,区别在目录结构而已) 与动态程序结合,最通用的办法就是使用 proxy 和 upstream 模块。 方便一点的,比如用 fastcgi 启动 perl/php 程序,或者支持 uwsgi 标准的 python/perl 程序等 ……
nginx 原生 perl 模块介绍 大家都知道, apache 除了 cgi 方式外,还有 mod_perl , nginx 也一样。 在编译时,启用 --with-http_perl_module 选项即可。 功能上,主要分两种,一种是简单的通过 perl_set 指令,返回一个 nginx.conf 的内部变量,完成后续响应;一种是通过 handler 替代一部分 serve 功能。 指令的使用方法,见 nginx 的 wiki 。
perl_set 举例 通过 perl_set 完成 url 大小写的改变。注意,这并不意味着 url 大小写不重要了,只是说在实际文件统一小写的情况下,不会对有大写的 url 返回 404 了 …… nginx.conf: http {   perl_set $new_uri '   sub {   my $r = shift;   return lc($r->uri);   };   ';   rewrite ^.*$ $new_uri last; };
perl 举例 在文件下载服务时,根据文件大小的不同,将请求引向不同的服务器集群。进一步可以根据 ip ,根据 dir ,根据 cookie 等等 …… nginx.conf: http {   perl_module perl/lib;   perl_require Redirect.pm;   server {   location / {   perl Redirect::handler;   };   }; }; Redirect.pm: package Redirect; use nginx; sub handler {   my $self = shift;   my $webroot = '/www/dl.gamedomain.com/'   return HTTP_NOT_ALLOWED unless $self->uri =~ m!^(/.+/)[^/]+$!;   my $file = $webroot . $1 . $self->filename;   my @filestat = stat($file) or return HTTP_NOT_FOUND;   my $filesize = $filestat[7];   if ( $filesize < 8 * 1024 * 1024 ) {   return OK;   } else {   $self->location('http://bigfile.cdndomain.com'.$self->uri);   } }; 1
模拟 ngx_perl 的 ngx_js 除了 Igor Sysoev 提供的 ngx_perl ,在第三方模块库里还有另外一个 ngx_javascript 模块,其实现效果甚至指令命名,都模仿了 ngx_perl 的形式。 感谢微博上某位我不记得的童鞋当初告诉我这个模块 …… 可惜偶不会 js ,估计会 js 又想折腾 webserver 都去玩 node 去了 = =!
突破 ngx_perl 的 ngx_lua agentzh 目前全力以赴的 OpenResty 项目主要就是以这个 ngx_lua 为中心,粘合一系列其他 ngx_*(memd/redis/mysql...) 的 asynchronous 模块完成一个全程 asynchronous 的 webservice 。 agentzh 提到过两点:一是 openresty 的早期版本是 perl 的,后来因为性能废弃了;二是 ngx_perl 模块的 blocking 完全浪费了 nginx 优秀的 nonblocking 设计所以纯粹是个玩具。
突破 ngx_perl 的 ngx_lua 在 ngx_perl 的 wiki 上,有这么两句话:一是不要试图使用 perl 来完成类似 dns 解析、 mysql 请求之类的需要长时间等待的任务,这会导致整个 worker 被阻塞;二是启用了 ngx_perl 的 server ,尽量避免使用 reload 命令,有可能会内存溢出。 在 agentzh 的文档 ( 讲座 ?) 中,也曾提到, ngx_lua 模块最好用来做运算,把 IO 请求通过 subrequest 交给专门的模块来做。
nginx 增强版 perl 介绍 由上推断,可以认为如果只是单纯的运算类的事情,使用 ngx_perl 完成是完全可以的,比如之前举例的 perl_set 的情况。 那么,如果想完成一个复杂功能,只能靠 ngx_lua 了么? 感谢 CPAN ,我发现了 Nginx::Engine 模块 —— 前不久这个模块刚刚从 cpan 搬到 github ,名为 nginx_perl ,会在 release 后再搬回 cpan~~
nginx 增强版 perl 介绍 在 Nginx::Engine 的介绍上,写的是 an asynchronous web framework based on nginx ;在 nginx_perl 的介绍上,则是 full-featured perl support for nginx 。 通过 $r->print 发送内容的方式很类似原始的 CGI.pm ,所以如果是写网页,还是用 dancer 之类的 framework 比较方便。 除了一些细节上的功能,比如 perl_init_worker/perl_eval 指令之外,最重要的几个地方:
nginx_perl 新增功能 1 、 $r->main_count_inc; 每个 async 的 handler 都要 increase 主进程的计数器以便 callback ; 2 、 ngx_timer $after, $repeat, sub {}; 一个定时器,在 $after 秒后 callback ,重复 $repeat 次; 3 、 ngx_connector $ip, $port, $timeout, sub {}; 异步链接 $ip:$port ,超时时间 $timeout ,成功的话,建立的链接将作为 $_[0] 返回;否则返回 $! 。
nginx_perl 新增功能 4 、 ngx_reader $connection, $buf, $min, $max, $timeout, sub{}; 从 ngx_connector 返回的 $connection 中异步读取数据到 $buf ,规定 $buf 的长度在 $min 到 $max 之间。如果长度不足,返回 NGX_EOF ,也会存入 $! 中。 5 、 ngx_writer $connection, $buf, $timeout, sub {}; 和 ngx_reader 相对的。
nginx_perl 新增功能 ngx_ssl_handshaker $connection, sub {}; 如果启动了 ssl 加密,必须在 connection 之后使用 handshaker ,再创建 reader/writer 。 ngx_resolver $host, $timeout, sub {}; 返回域名解析结果 ip 列表到 @_ 中;目前这个指令还是 nginx 原生 resolver 的封装,如果要使用的话,建议在本机配备 named/dnsmasq 等 dns 缓存 …… 这里是 TODO 中列的下一步重点改进。
nginx_perl 新增功能 $r->take_connection(); $r->give_connection(); 之前的 ngx_connector 指令,用来创建和其他 server 的链接,而这里的 takeover ,是用来获取 client 的链接,这样做 websocket 之类的就比较方便 …… 使用时同样要记得 inc ,更关键的是要使用 $r->finalize_request(NGX_DONE) 表示 EOF , return NGX_NOOP 表示 NGX_CLOSE 。
nginx_perl 示例 源码中默认有 helloworld,self_sufficient,redis 和 Nginx::Util 四个示例。不过我还是自己试着写一个类似 proxy_pass 的例子,从中也发现一些 README 没有说明的细节: 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;
nginx_perl 示例 # 使用非阻塞的连接器连接 127.0.0.1 的 80 端口, 10 秒超时 ngx_connector '127.0.0.1', 80, 10, sub { # 如果连接出问题,会记录在 $! 中 if ($!) { $r->send_http_header('text/html'); $r->print(&quot;Connection failed, $!\n&quot;); $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 = &quot;GET /index.php HTTP/1.0\x0d\x0a&quot;. &quot;Host: chenlinux.com\x0d\x0a&quot;. &quot;Connection: close\x0d\x0a&quot;. &quot;\x0d\x0a&quot;; # 这里记住定义 buffer 的时候不要搞成 undef 了,会报段错误的,不过俄国佬回信说他修复了 my $res_buf = '';
nginx_perl 示例 # 非阻塞写入,超时 10 秒 ngx_writer $c, $req_buf, 10, sub { if ($!) { ...... }; $req_buf = ''; # 之前的 buffer 测试就是这里,如果加一个 warn ,就不会报错 …… 汗 #warn &quot;$req_buf\n$res_buf\n&quot;; # 写入完成后,开始调用读取 return NGX_READ; };
nginx_perl 示例 # 读取到 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;
总结 今天主要是介绍了一下在 nginx.conf 里能够使用的几个 script ,以及用 perl 完成的两个 cdn 功能的实验。 关于 asynchronous 的应用,其实我还是门外围观者,感觉单纯 perl 也好 lua 也好,主要还是多多搭配各种模块的复杂运用。

More Related Content

PPTX
OpenResty/Lua Practical Experience
PPTX
浮云脱水小说站的搭建
PPT
ByPat博客出品-高性能Web服务器nginx及相关新技术的应用
PPTX
lua & ngx_lua 的介绍与应用
PPTX
Nae client(using Node.js to create shell cmd)
PPT
高性能Web服务器Nginx及相关新技术的应用实践
PPT
高性能Web服务器Nginx及相关新技术的应用实践
PPT
构建ActionScript游戏服务器,支持超过15000并发连接
OpenResty/Lua Practical Experience
浮云脱水小说站的搭建
ByPat博客出品-高性能Web服务器nginx及相关新技术的应用
lua & ngx_lua 的介绍与应用
Nae client(using Node.js to create shell cmd)
高性能Web服务器Nginx及相关新技术的应用实践
高性能Web服务器Nginx及相关新技术的应用实践
构建ActionScript游戏服务器,支持超过15000并发连接

What's hot (18)

PPT
Monitor is all for ops
PDF
Automate with Ansible basic (3/e)
PDF
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
PPT
Effective linux.1.(commandline)
PPT
使用Nginx轻松实现开源负载均衡
DOC
智能Dns工作流程及配置
PDF
高性能Web服务器nginx及相关新技术的应用
PDF
JCConf2015: groovy to gradle
PDF
Using armeria to write your RPC
PPT
Effective linux.2.(tools)
DOC
Nginx+常见应用技术指南
PPT
DNS协议与应用简介
PDF
Deployment with Capistrano
PDF
gRPC - 打造輕量、高效能的後端服務
PDF
Python xmlrpc-odoo
PDF
Continuous Delivery with Ansible x GitLab CI
PDF
PPTX
Windbg入门
Monitor is all for ops
Automate with Ansible basic (3/e)
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
Effective linux.1.(commandline)
使用Nginx轻松实现开源负载均衡
智能Dns工作流程及配置
高性能Web服务器nginx及相关新技术的应用
JCConf2015: groovy to gradle
Using armeria to write your RPC
Effective linux.2.(tools)
Nginx+常见应用技术指南
DNS协议与应用简介
Deployment with Capistrano
gRPC - 打造輕量、高效能的後端服務
Python xmlrpc-odoo
Continuous Delivery with Ansible x GitLab CI
Windbg入门
Ad

Viewers also liked (20)

PDF
Load balancing in the SRE way
PPTX
Script up your application with Lua! -- RyanE -- OpenWest 2014
PDF
Nginx+lua在阿里巴巴的使用
KEY
淺入淺出 GDB
PDF
Gdb tutorial-handout
PDF
Learn C Programming Language by Using GDB
PDF
Trafficshifting: Avoiding Disasters & Improving Performance at Scale
PDF
Production Ready Services at Netflix
PDF
基于OpenResty的百万级长连接推送
PDF
Software Reliability Engineering
PDF
PDF
The basics and design of lua table
PDF
Using ngx_lua / lua-nginx-module in pixiv
PDF
SRE Tools
PDF
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
PDF
SRE From Scratch
PPTX
Feedback loops: How SREs benefit and what is needed to realize their potential
PDF
Microservices & API Gateways
PDF
Making Linux do Hard Real-time
PDF
C/C++调试、跟踪及性能分析工具综述
Load balancing in the SRE way
Script up your application with Lua! -- RyanE -- OpenWest 2014
Nginx+lua在阿里巴巴的使用
淺入淺出 GDB
Gdb tutorial-handout
Learn C Programming Language by Using GDB
Trafficshifting: Avoiding Disasters & Improving Performance at Scale
Production Ready Services at Netflix
基于OpenResty的百万级长连接推送
Software Reliability Engineering
The basics and design of lua table
Using ngx_lua / lua-nginx-module in pixiv
SRE Tools
給自己更好未來的 3 個練習:嵌入式作業系統設計、實做,與移植 (2015 年春季 ) 課程說明
SRE From Scratch
Feedback loops: How SREs benefit and what is needed to realize their potential
Microservices & API Gateways
Making Linux do Hard Real-time
C/C++调试、跟踪及性能分析工具综述
Ad

Similar to Perl在nginx里的应用 (20)

PPT
高性能Web服务器nginx及相关新技术的应用
PPT
高性能Web服务器Nginx及相关新技术的应用实践
PDF
配置Oracle 10g 双向流复制
PDF
Ruby on Rails 開發環境建置 for Ubuntu
PDF
Erlang Practice
DOC
康盛创想项目部Linux 服务器部署标准(最新版)
DOC
X64服务器 lamp服务器部署标准 new
DOCX
Puppet安装测试
DOCX
Handler socket测试报告 - 20110422
XLS
Puppet安装总结
PDF
高性能LAMP程序设计
PDF
Ria的强力后盾:rest+海量存储
PPT
PPTX
8, lamp
PPT
Nginx使用和模块开发
PPT
使用Nginx轻松实现开源负载均衡——对外版
PDF
Lucene 全文检索实践
PDF
Migrations 與 Schema 操作
PDF
运维自动化
DOC
Oraliux+mysql5单机多实例安装文档
高性能Web服务器nginx及相关新技术的应用
高性能Web服务器Nginx及相关新技术的应用实践
配置Oracle 10g 双向流复制
Ruby on Rails 開發環境建置 for Ubuntu
Erlang Practice
康盛创想项目部Linux 服务器部署标准(最新版)
X64服务器 lamp服务器部署标准 new
Puppet安装测试
Handler socket测试报告 - 20110422
Puppet安装总结
高性能LAMP程序设计
Ria的强力后盾:rest+海量存储
8, lamp
Nginx使用和模块开发
使用Nginx轻松实现开源负载均衡——对外版
Lucene 全文检索实践
Migrations 與 Schema 操作
运维自动化
Oraliux+mysql5单机多实例安装文档

More from 琛琳 饶 (9)

PPT
{{more}} Kibana4
PPT
ELK stack at weibo.com
PPTX
More kibana
PPT
Perl调用微博API实现自动查询应答
PDF
Add mailinglist command to gitolite
PPT
Skyline 简介
PPT
How ElasticSearch lives in my DevOps life
PPT
Logstash
DOC
Mysql测试报告
{{more}} Kibana4
ELK stack at weibo.com
More kibana
Perl调用微博API实现自动查询应答
Add mailinglist command to gitolite
Skyline 简介
How ElasticSearch lives in my DevOps life
Logstash
Mysql测试报告

Perl在nginx里的应用

  • 1. Perl 与 Nginx 应用 —— jeff
  • 2. 题目的由来 perl 是 OPSer 最熟悉的 script language nginx 是 OPSer 最喜欢的 web server 相信我的 perl 和 nginx 水平都不是最好的,不过感谢 laird 的乱点鸳鸯谱,把它们凑在一起给我作讲题,大概或许可能仿佛应该想来我看过一些而大家没留意的吧 ^=^
  • 3. 提要 nginx 的主要功能 nginx 原生 perl 模块介绍 几个简单的例子 nginx 第三方模块 (ngx_js/ngx_lua) 介绍 nginx 增强版 perl 介绍 总结
  • 4. nginx 的主要功能 nginx 主要分成 http 和 mail 两个部分,一般来说,我们的操作都是 http 部分的(奇怪的是 nginx-src 的 configure 选项里只有 --without-http 而没有 --without-mail ) http 中,最常用的标准模块是静态文件发布的 core ,反向代理的 proxy ,上游集群的 upstream ,重定向的 rewrite 等 …… 其他常用官方模块有: fastcgi/flv/mp4/gzip_static/limit_conn/uwsgi 等
  • 5. nginx 与动态应用 nginx 的标准作用是静态文件发布( proxy_cache/proxy_store 的结果也是静态文件发布,区别在目录结构而已) 与动态程序结合,最通用的办法就是使用 proxy 和 upstream 模块。 方便一点的,比如用 fastcgi 启动 perl/php 程序,或者支持 uwsgi 标准的 python/perl 程序等 ……
  • 6. nginx 原生 perl 模块介绍 大家都知道, apache 除了 cgi 方式外,还有 mod_perl , nginx 也一样。 在编译时,启用 --with-http_perl_module 选项即可。 功能上,主要分两种,一种是简单的通过 perl_set 指令,返回一个 nginx.conf 的内部变量,完成后续响应;一种是通过 handler 替代一部分 serve 功能。 指令的使用方法,见 nginx 的 wiki 。
  • 7. perl_set 举例 通过 perl_set 完成 url 大小写的改变。注意,这并不意味着 url 大小写不重要了,只是说在实际文件统一小写的情况下,不会对有大写的 url 返回 404 了 …… nginx.conf: http { perl_set $new_uri ' sub { my $r = shift; return lc($r->uri); }; '; rewrite ^.*$ $new_uri last; };
  • 8. perl 举例 在文件下载服务时,根据文件大小的不同,将请求引向不同的服务器集群。进一步可以根据 ip ,根据 dir ,根据 cookie 等等 …… nginx.conf: http { perl_module perl/lib; perl_require Redirect.pm; server { location / { perl Redirect::handler; }; }; }; Redirect.pm: package Redirect; use nginx; sub handler { my $self = shift; my $webroot = '/www/dl.gamedomain.com/' return HTTP_NOT_ALLOWED unless $self->uri =~ m!^(/.+/)[^/]+$!; my $file = $webroot . $1 . $self->filename; my @filestat = stat($file) or return HTTP_NOT_FOUND; my $filesize = $filestat[7]; if ( $filesize < 8 * 1024 * 1024 ) { return OK; } else { $self->location('http://bigfile.cdndomain.com'.$self->uri); } }; 1
  • 9. 模拟 ngx_perl 的 ngx_js 除了 Igor Sysoev 提供的 ngx_perl ,在第三方模块库里还有另外一个 ngx_javascript 模块,其实现效果甚至指令命名,都模仿了 ngx_perl 的形式。 感谢微博上某位我不记得的童鞋当初告诉我这个模块 …… 可惜偶不会 js ,估计会 js 又想折腾 webserver 都去玩 node 去了 = =!
  • 10. 突破 ngx_perl 的 ngx_lua agentzh 目前全力以赴的 OpenResty 项目主要就是以这个 ngx_lua 为中心,粘合一系列其他 ngx_*(memd/redis/mysql...) 的 asynchronous 模块完成一个全程 asynchronous 的 webservice 。 agentzh 提到过两点:一是 openresty 的早期版本是 perl 的,后来因为性能废弃了;二是 ngx_perl 模块的 blocking 完全浪费了 nginx 优秀的 nonblocking 设计所以纯粹是个玩具。
  • 11. 突破 ngx_perl 的 ngx_lua 在 ngx_perl 的 wiki 上,有这么两句话:一是不要试图使用 perl 来完成类似 dns 解析、 mysql 请求之类的需要长时间等待的任务,这会导致整个 worker 被阻塞;二是启用了 ngx_perl 的 server ,尽量避免使用 reload 命令,有可能会内存溢出。 在 agentzh 的文档 ( 讲座 ?) 中,也曾提到, ngx_lua 模块最好用来做运算,把 IO 请求通过 subrequest 交给专门的模块来做。
  • 12. nginx 增强版 perl 介绍 由上推断,可以认为如果只是单纯的运算类的事情,使用 ngx_perl 完成是完全可以的,比如之前举例的 perl_set 的情况。 那么,如果想完成一个复杂功能,只能靠 ngx_lua 了么? 感谢 CPAN ,我发现了 Nginx::Engine 模块 —— 前不久这个模块刚刚从 cpan 搬到 github ,名为 nginx_perl ,会在 release 后再搬回 cpan~~
  • 13. nginx 增强版 perl 介绍 在 Nginx::Engine 的介绍上,写的是 an asynchronous web framework based on nginx ;在 nginx_perl 的介绍上,则是 full-featured perl support for nginx 。 通过 $r->print 发送内容的方式很类似原始的 CGI.pm ,所以如果是写网页,还是用 dancer 之类的 framework 比较方便。 除了一些细节上的功能,比如 perl_init_worker/perl_eval 指令之外,最重要的几个地方:
  • 14. nginx_perl 新增功能 1 、 $r->main_count_inc; 每个 async 的 handler 都要 increase 主进程的计数器以便 callback ; 2 、 ngx_timer $after, $repeat, sub {}; 一个定时器,在 $after 秒后 callback ,重复 $repeat 次; 3 、 ngx_connector $ip, $port, $timeout, sub {}; 异步链接 $ip:$port ,超时时间 $timeout ,成功的话,建立的链接将作为 $_[0] 返回;否则返回 $! 。
  • 15. nginx_perl 新增功能 4 、 ngx_reader $connection, $buf, $min, $max, $timeout, sub{}; 从 ngx_connector 返回的 $connection 中异步读取数据到 $buf ,规定 $buf 的长度在 $min 到 $max 之间。如果长度不足,返回 NGX_EOF ,也会存入 $! 中。 5 、 ngx_writer $connection, $buf, $timeout, sub {}; 和 ngx_reader 相对的。
  • 16. nginx_perl 新增功能 ngx_ssl_handshaker $connection, sub {}; 如果启动了 ssl 加密,必须在 connection 之后使用 handshaker ,再创建 reader/writer 。 ngx_resolver $host, $timeout, sub {}; 返回域名解析结果 ip 列表到 @_ 中;目前这个指令还是 nginx 原生 resolver 的封装,如果要使用的话,建议在本机配备 named/dnsmasq 等 dns 缓存 …… 这里是 TODO 中列的下一步重点改进。
  • 17. nginx_perl 新增功能 $r->take_connection(); $r->give_connection(); 之前的 ngx_connector 指令,用来创建和其他 server 的链接,而这里的 takeover ,是用来获取 client 的链接,这样做 websocket 之类的就比较方便 …… 使用时同样要记得 inc ,更关键的是要使用 $r->finalize_request(NGX_DONE) 表示 EOF , return NGX_NOOP 表示 NGX_CLOSE 。
  • 18. nginx_perl 示例 源码中默认有 helloworld,self_sufficient,redis 和 Nginx::Util 四个示例。不过我还是自己试着写一个类似 proxy_pass 的例子,从中也发现一些 README 没有说明的细节: 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;
  • 19. nginx_perl 示例 # 使用非阻塞的连接器连接 127.0.0.1 的 80 端口, 10 秒超时 ngx_connector '127.0.0.1', 80, 10, sub { # 如果连接出问题,会记录在 $! 中 if ($!) { $r->send_http_header('text/html'); $r->print(&quot;Connection failed, $!\n&quot;); $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 = &quot;GET /index.php HTTP/1.0\x0d\x0a&quot;. &quot;Host: chenlinux.com\x0d\x0a&quot;. &quot;Connection: close\x0d\x0a&quot;. &quot;\x0d\x0a&quot;; # 这里记住定义 buffer 的时候不要搞成 undef 了,会报段错误的,不过俄国佬回信说他修复了 my $res_buf = '';
  • 20. nginx_perl 示例 # 非阻塞写入,超时 10 秒 ngx_writer $c, $req_buf, 10, sub { if ($!) { ...... }; $req_buf = ''; # 之前的 buffer 测试就是这里,如果加一个 warn ,就不会报错 …… 汗 #warn &quot;$req_buf\n$res_buf\n&quot;; # 写入完成后,开始调用读取 return NGX_READ; };
  • 21. nginx_perl 示例 # 读取到 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;
  • 22. 总结 今天主要是介绍了一下在 nginx.conf 里能够使用的几个 script ,以及用 perl 完成的两个 cdn 功能的实验。 关于 asynchronous 的应用,其实我还是门外围观者,感觉单纯 perl 也好 lua 也好,主要还是多多搭配各种模块的复杂运用。