一直没有时间使用 ngx_lua,上周算是真正使用了下,总结下,也算是帮忙推广下 openresty。

什么是 openresty



openresty 的主力作者是 @agentzh 它的网页在 这里,上面有介绍。按我的理解,他是介于客户端浏览器 js 和数据库之间的一层。
在 ajex 还没有盛行的时代,数据库的数据需要展现在浏览器的时候,一般都是使用 php/jsp 之类读取数据,然后拼表格/图表这些。在客户端机器越来越牛逼之后,把部分运算放在浏览器里面开始盛行,ajex 也越来越流行。这个时候通常还需要有个服务器端的程序来配合从数据库获取并提供数据,应该也有不少类似的程序来提供这个数据。
老版本的 openresty 是基于 perl 做的,可以上 cpan 上面 搜到 (不知道为啥这页面我打不开了)。agentzh 还专门为他写了一个 admin site,纯 js + oprensty 来实现的,可以直接在上面配置接口,很方便。目前老版本应该没人用了。
新版本的 openresty 基本上等于是 nginx 和一些 nginx 模块的集合,大部分模块都是 agentzh 和 chaoslawful 完成的,目前 agentzh 离职在家全职开发 openresty 相关,chaoslawful 还在淘宝 量子统计
这大概就是我了解的 openresty 的起源和目前的情况。写的比较简单,里面的曲折就不多说了,可以找上面提到的大牛聊天。



怎么使用 openresty



我下面用一个简单的例子来描述下,我是怎么使用 openresty 的,从中应该能看出来 openresty 能干啥,怎么用。


需求



在 postgresql 数据库有张网站日访问流量表,包含两个字段 thedate 和 pv。需要把里面的数据展现出来,画出来流量曲线。
注意
下面的代码大都从现有程序里面扒出来的,所以不一定直接就能用,只是个示意而已。



安装 openresty



首先需要安装 openresty。从 openresty.org 下载当前的 stable 版本 ngx_openresty-1.0.6.22.tar.gz。
$ cd ngx_openresty-1.0.6.22
$ ./configure --with-http_drizzle_module --with-http_postgres_module --with-pg_config=/opt/pg90/bin/pg_config --prefix=/usr/local/openresty --with-libdrizzle=/usr/local/libdrizzle/ --with-luajit --with-http_iconv_module # 这是我用到的参数,按照需要加减
$ make
# make install
configure 的时候 postgres_module 是必须的,其他的 drizzle_module 是用来支持从 mysql 获取数据的,iconv_module 是用来做编码转换的,luajit 据说可以提升不少性能。 不出问题的话,在 /usr/local/openresty 目录下面就安装好了。其实更合理的方式应该是提供一个 rpm 或者 deb 包的。

启动 nginx

openresty 给提供了简单可用的 nginx.conf,所以现在可以先尝试启动下 /usr/local/openresty/nginx/sbin/nginx 了,如果启动没问题,那就 ok 了。 配置文件在 /usr/local/openresty/nginx/conf/nginx.conf。

配置 nginx

主要就是配置 /usr/local/openresty/nginx/conf/nginx.conf,以后很多事情都会在这里面来完成,说是 nginx.conf 编程也不为过,呵呵。 增加下面的配置

    upstream pgsql {
        postgres_server server_ip:5432 dbname=test password=123 user=test;
        #postgres_keepalive  max=2 mode=single overflow=reject;
        postgres_keepalive off;
    }

# server 里面增加一个 location

       location /=/pv {
            postgres_query 'select thedate, pv from pv';
            postgres_pass pgsql;

            rds_json on;
            rds_json_format compact;

            xss_get on;
            xss_callback_arg '_c';
        }
  1. 其中关于 upstream postgres 用来定义需要连接的数据库信息,和发送 sql 到数据库,可以参考 这里
  2. rds_json 用来将数据库的输出变成 json 格式,可以参考 这里
  3. xss_get 用来支持跨域,jquery 默认使用的 callback 参数是 _c,可以参考 这里
这样配置好之后,重启下。结果应该很清晰了,请求 http://your\_ip/=/pv 应该就可以得到数据库里面的数据了,可以使用 curl 看看结果,应该类似下面的

js 画图

挑一个画图程序,比如我用过的 highcharts, amcharts 这些都不错,amcharts 是使用 flash 画图,兼容各种浏览器,highcharts 号称也支持,不过我弄出来的图在 chrome/firefox 下面没问题,ie 不支持,他用的是 svg 标签。 就写几行代码来示意下吧
    $.ajax({
        url : 'http://your_ip/=/pv',
        success: function (data) {
            renderPvCharts(data);
        }
    });

    function renderPvCharts(data) {
        $('body').append('
        var result = Utils.getSplineChartSeries( data ); # 将 nginx 返回的 json 格式数据转化为 highcharts 需要的格式
        var options = {
			chart: {
                zoomType: 'xy',
				renderTo: 'pv', # div 的 id
				defaultSeriesType: 'spline'
			},
			title: {
                text: '每日 pv'
            },
			xAxis: {
                type: 'datetime'
			},
			tooltip: {
				formatter: function() {
			        return ''+ this.series.name +'
'+
						Highcharts.dateFormat('%e. %b', this.x) +': '+ this.y;
				}
			},
			legend: {
				layout: 'vertical',
				align: 'right',
				verticalAlign: 'top',
				x: -10,
				y: 100,
				borderWidth: 0
			},
            series : result.y
        };

        var chart = new Highcharts.Chart( options );
    };

} );
简单解释下
  1. 在页面 readay 的时候,使用 ajex 设置回调函数并请求接口。
  2. 回调函数里面使用 Utils.getSplineChartSeries 转换一下数据,方便直接给 options 里面数据赋值,具体需要的数据格式,看 highcharts 的 spline 的 demo 就可以。
  3. 回调函数里面显示图表。
这样就完事了,数据就展现出来了。

其他

从上面可以看到整个数据流是怎么回事。openresty 可以做的事情远比上面描述的复杂,上面只是个最简单的应用了。
  1. 比如使用 rds_csv 来直接得到 csv 格式的数据提供给用户,而不是 json。
  2. 可以使用 ngx_lua 在 nginx.conf 里面使用 lua 来在服务器端对数据做一些处理再丢给浏览器。 大家都知道 js 处理的数据太大的时候,会导致浏览器卡死,所以如果不方便通过 sql 控制输出的时候,可以使用 lua 来处理下。当然 这只是其中一个应用,使用 ngx_lua 你可以干很多事情,比如上面那个使用 js 来生成 spline 数据的函数就可以用 lua 来实现,lua 还可以和 c 结合来做一些事情。对于 location 的参数,在 ngx_lua 里面也是可以访问的,比如 ngx.var.arg_c 这样。具体还是看 wiki 吧,写不完的。
    1. openresty 还能直接访问 redis 和 memcached。
    本篇只能算是一个入门而已,openresty 在淘宝量子统计的应用非常广泛。另外在 去哪网 也有不少应用,比如我知道的安全过滤模块,和一些数据报表,都是基于 openresty 的。 附一个 highcarts 画的图