IT技术互动交流平台

OpenResty(nginx)操作mysql的初步应用

作者:haoyunkgq  发布日期:2013-02-20 09:13:31
OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器,它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项。
 
OpenResty 通过汇聚各种设计精良的 Nginx 模块,从而将 Nginx 有效的变成一个强大的 Web 应用服务器,这样, Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种C以及Lua 模块,快速构造出足以胜任 10K+ 并发连接响应的超高性能Web 应用系统.
 
OpenResty 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如MySQL,PostgreSQL,~Memcaches 以及 ~Redis 等都进行一致的高性能响应.
 
OpenResty 英文官网:http://openresty.org/
OpenResty 中文官网:http://openresty.org/cn/
Nginx 维基官网:http://wiki.nginx.org/
 
说明:
OpenResty的安装比较简单,这里要使用一个强大的功能,就是用nginx直接访问mysql,取出数据,返回给浏览器,有两种方法,第一种:使用 HttpDrizzleModule 模块,同时还需要安装 libdrizzle 1.0(在drizzle里),第二种:使用ngx_lua模块和lua库lua-resty-mysql(Mysql client Driver)。默认安装OpenResty时,还有一些lua库被安装,如
 
无论使用何种方法,都需要安装 pcre 库 libpcre,这是安装nginx必须的

[root@vm5 ~]# yum install pcre-devel.x86_64

方法一
 
1、安装 libdrizzle 1.0

[root@vm5 ~]# wget http://agentzh.org/misc/nginx/drizzle7-2011.07.21.tar.gz
[root@vm5 ~]# tar zxvf drizzle7-2011.07.21.tar.gz
[root@vm5 ~]# cd drizzle7-2011.07.21
[root@vm5 drizzle7-2011.07.21]# ./configure --without-server
[root@vm5 drizzle7-2011.07.21]# make libdrizzle-1.0
[root@vm5 drizzle7-2011.07.21]# make install-libdrizzle-1.0

2、安装 OpenResty

 

[root@vm5 ~]# wget http://openresty.org/download/ngx_openresty-1.2.4.14.tar.gz
[root@vm5 ~]# tar zxvf ngx_openresty-1.2.4.14.tar.gz
[root@vm5 ~]# cd ngx_openresty-1.2.4.14
[root@vm5 ngx_openresty-1.2.4.14]# ./configure --prefix=/usr/local/openresty --with-luajit --with-http_drizzle_module --with-libdrizzle=/usr/local
[root@vm5 ngx_openresty-1.2.4.14]# gmake
[root@vm5 ngx_openresty-1.2.4.14]# gmake install

3、创建测试数据

 

mysql> create table users(id int,username varchar(30),age tinyint);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into users values(1,'zhangsan',24);
Query OK, 1 row affected (0.00 sec)

mysql> insert into users values(2,'lisi',26);
Query OK, 1 row affected (0.00 sec)

4、编辑 nginx.conf 配置文件
 

worker_processes 1;
events {
        worker_connections 1024;
}
http {
        include mime.types;
        default_type application/octet-stream;
        sendfile on;
        keepalive_timeout 65;
        upstream mysql {
                drizzle_server 127.0.0.1:3306 dbname=test user=root protocol=mysql;
        }
        server {
                listen 80;
                server_name localhost;
                root html;
                index index.html index.htm;
                location = /mysql-status {
                        drizzle_status;
                }
                location / {
                        drizzle_pass mysql;
                        drizzle_query "select id,username,age from users where id=1";
                        rds_json on;
                }
                error_page 500 502 503 504 /50x.html;
                location = /50x.html {
                        root html;
                }
        }
}

红色的配置用到了 HttpDrizzleModule 和 rds-json-nginx-module 模块,前一个模块是用来和数据库交互的,后面那个是做数据格式转换的,这里使用的是 json 数据格式


5、测试配置文件、启动 nginx


[root@vm5 conf]# /usr/local/openresty/nginx/sbin/nginx -t -c /usr/local/openresty/nginx/conf/nginx.conf
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@vm5 conf]# /usr/local/openresty/nginx/sbin/nginx -c /usr/local/openresty/nginx/conf/nginx.conf
[root@vm5 conf]# netstat -ntupl
Active Internet connections (only servers)
Proto	Recv-Q	Send-Q	Local Address	Foreign Address	State		PID/Program name
tcp	0		0		0.0.0.0:3306	0.0.0.0:*		LISTEN	28013/mysqld
tcp	0		0		0.0.0.0:80		0.0.0.0:*		LISTEN	28036/nginx.conf
tcp	0		0		:::22			:::*			LISTEN	2901/sshd

6、测试

 

[root@vm5 nginx]# curl localhost
[{"id":1,"username":"zhangsan","age":24}]
[root@vm5 nginx]# curl localhost/mysql-status
worker process: 29491

upstream mysql
    active connections: 0
    connection pool capacity: 0
    servers: 1
    peers: 1

ok,效果出来了,直接用 nginx 去读 mysql 数据,而且输出的数据格式是json格式的,可用ajax折腾,而且可以web查看mysql状态,是不是很牛X啊!


再来一个可以传id参数的例子:
修改 nginx 配置文件 nginx.conf


drizzle_query "select id,username,age from users where id=$arg_id";

测试
 

[root@vm5 nginx]# curl localhost/?id=1
[{"id":1,"username":"zhangsan","age":24}]
[root@vm5 nginx]# curl localhost/?id=2
[{"id":2,"username":"lisi","age":26}]

ok,可以接收参数了,但是这么配置存在一个bug,那就是没有传递参数时会报错,这只是一个测试用例,要想在线上使用需要完善它


方法二


1、修改 nginx 配置文件 nginx.conf


worker_processes    1;
events {
        worker_connections    1024;
}
http {
        include             mime.types;
        default_type    application/octet-stream;
        sendfile                on;
        keepalive_timeout    65;
        server {
                listen             80;
                server_name    localhost;
                root     html;
                index    index.html index.htm;
                location / {
                        content_by_lua '
                                local mysql = require "resty.mysql"
                                local db,err = mysql:new()
                                if not db then
                                        ngx.say("failed to instantiate mysql: ",err)
                                        return
                                end

                                db:set_timeout(1000)
 
                                local ok,err,errno,sqlstate = db:connect{
                                        host = "127.0.0.1",
                                        port = 3306,
                                        database = "test",
                                        user = "root",
                                        password = "",
                                        max_package_size = 1024
                                }
                                if not ok then
                                        ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate)
                                        return
                                end

                                res,err,errno,sqlstate = db:query("select id,username,age from users where id=1")
                                if not res then
                                        ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
                                        return
                                end

                                local cjson = require "cjson"
                                ngx.say(cjson.encode(res))
                        ';
                }
                error_page     500 502 503 504    /50x.html;
                location = /50x.html {
                        root     html;
                }
        }
}

或者也可以将上面的lua代码放到一个以.lua为扩展名的文件里,并在nginx.conf里使用content_by_lua_file指令引用
步骤如下:

[root@vm5 lua]# mkdir /usr/local/openresty/nginx/conf/lua
[root@vm5 lua]# touch /usr/local/openresty/nginx/conf/lua/mysql.lua将上面content_by_lua指令所指的代码加入到mysql.lua
文件里,并在nginx.conf里引用如下:

content_by_lua_file conf/lua/mysql.lua;

即可


2、测试配置文件、重启 nginx 服务
 
[root@vm5 conf]# /usr/local/openresty/nginx/sbin/nginx -t -c /usr/local/openresty/nginx/conf/nginx.conf
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@vm5 conf]# killall -HUP nginx

3、测试

[root@vm5 conf]# curl localhost
[{"username":"zhangsan","age":24,"id":1}]ok,输出json格式数据了,结果也是对的。赞一个!


我们稍作修改,使其支持传递 id 参数 www.it165.net
修改 nginx 配置文件

res,err,errno,sqlstate = db:query("select id,username,age from users where id="..ngx.var.arg_id)测试配置、重启服务,略
测试结果

[root@vm5 conf]# curl localhost/?id=2
[{"username":"lisi","age":26,"id":2}]
[root@vm5 conf]# curl localhost/?id=1
[{"username":"zhangsan","age":24,"id":1}]再一次ok,效果不错吧!


注意:以上代码要想用在生产环境,还需要添加一些错误捕获代码!


Tag标签: OpenResty   mysql  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规