OpenResty(nginx)操做mysql的初步應用

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庫被安裝,如 mysql.lua、redis.lua、upload.lua、memcached.lua、aes.lua、md5.lua、cjson.so等等。

不管使用何種方法,都須要安裝 pcre 庫 libpcre,這是安裝nginx必須的
[root@vm5 ~]# yum install pcre-devel.x86_64

方法一

一、安裝 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

二、安裝  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

三、建立測試數據
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)

四、編輯 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 數據格式

五、測試配置文件、啓動 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

六、測試
[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,那就是沒有傳遞參數時會報錯,這只是一個測試用例,要想在線上使用須要完善它。另外若是在前面例子中不使用rds_json指令轉換輸出格式的話,默認輸出的是二進制格式(
application/x-resty-dbd-stream ),顯示在終端窗口時可能顯示數據不全,能夠將輸出定向到一個文件,用vim查看,能夠看到完整數據。通常都是配合json、csv格式使用。

方法二

一、修改 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;
便可

二、測試配置文件、重啓 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

三、測試
[root@vm5 conf]# curl localhost
[{"username":"zhangsan","age":24,"id":1}]
ok,輸出json格式數據了,結果也是對的。贊一個!

咱們稍做修改,使其支持傳遞 id 參數
修改 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,效果不錯吧!

注意:以上代碼要想用在生產環境,還須要添加一些錯誤捕獲代碼!

這裏有些代碼是參照官網上的,詳情能夠查閱官網。
相關文章
相關標籤/搜索