使用lua調用mongoDB 執行個體

來源:互聯網
上載者:User

引言
公司需要做一個類似站長統計的項目,給了很多種方案;其中有個方案就是利用ngx_lua(openResty) 調用mongodb 來做日誌的儲存;在項目之前啟動之前,自己研究了這個方案的可行性,編寫寫了一個demo。

1.準備
(1)看過openresty的都應該知道,openresty只提供redis 的module模組,沒有提供mongoDB的驅動模組(不懂openresty;可以看下openresty最佳實現);所以我們這邊要先提供一個驅動,去中文論壇找了一番;發現了幾個不錯的結合lua 的mongodb的libarary項目:
在github上有lua-resty-mongol、還有wuxianglong的lua-mongo等項目;綜合考慮了之後,打算用lua-resty-mongol 這個項目;因為這個項目本身就是為了相容openresty設計的。
(2)這個demo本身是基於openresty中編寫的,所以在你的系統上需要安裝openresty,我這裡用的是centos 6.5 的系統,至於具體的下載 安裝,這裡就不詳細介紹了;如果有需要的話可以看看這篇文章http://www.52yunwei.cn/?p=415;
(3) 前面說到過 lua-resty-mongol 項目,我們要下載github下的這個項目;下載後編譯,
make install
把解壓的包 解壓到 lualib/resty/中下
如果你的openresty預設安裝的話是在/usr/local/openresty/lialib 下,我這邊的路徑是在 opt/openresty/lualib/resty 下;
(4)就是對應的mongodb 服務,我這裡的mongodb 服務是在自己的虛擬機器中,如果沒有的話,先去官網下載一個mongodb,然後啟動
這裡就不詳細介紹了

2.執行個體
(1).之前lua-resty-mongol 項目還要有一個配置項,就是要在nginx.conf 中配置上 你mongol 的預設初始化路徑

# 之前說過了,你要是是預設的openresty的話  這裡就可以配置是/usr/local/openresty/lialib/?/了# lua_package_path        '/opt/opentresty/lualib/?/init.lua;;';

(2). 對於ngx中的整個nginx.conf 配置如下

user  nginx;worker_processes  4;pid                             /opt/logs/nginx/nginx.pid;error_log               /opt/logs/nginx/error.log;events {    use epoll;    worker_connections  10240;}http {        include       mime.types;        #default_type           'text/html';        #定義日誌格式        #default_type           'application/octet-stream';        #指定lua_mongol 初始化預設路徑        default_type            'text/plain';        lua_package_path        '/opt/opentresty/lualib/?/init.lua;;';        charset                         utf-8;        error_log               /opt/logs/nginx/error.log;        access_log              off;        #log_format  main  '$remote_addr\t$uid_got$uid_set\t$http_host\t$time_iso8601\t$request\t$status\t$body_bytes_sent\t$http_referer\t$request_time\t$http_user_agent';        #log_format  tick '$msec^A$remote_addr^A$u_domain^A$u_url^A$u_title^A$u_referrer^A$u_sh^A$u_sw^A$u_cd^A$u_lang^A$http_user_agent^A$u_utrace^A$u_account';        log_format tick '$msec ^A^ $remote_addr ^A^ $u_domain ^A^ $u_url ^A^ $u_title ^A^ $u_referrer ^A^ $u_sh ^A^ $u_sw ^A^ $u_cd ^A^ $u_lang ^A^ $http_user_agent ^A^ $u_utrace ^A^ $u_account';        client_max_body_size 100m;        sendfile        on;        keepalive_timeout  60;        fastcgi_intercept_errors on;        proxy_connect_timeout 60;        proxy_send_timeout 90;        proxy_read_timeout 1800;        large_client_header_buffers 4 128k;        proxy_ignore_client_abort on;        gzip on;        gzip_min_length 10k;        gzip_buffers 4 16k;        gzip_comp_level 2;        gzip_types text/plain text/javascript application/javascript application/x-javascript text/css  application/xml application/octet-stream;        gzip_vary on;        #userid        userid                          on;        userid_name                     UUID;        userid_path                     /;        userid_expires                  max;        include _ext.conf;        include apps/*.conf;  }

(3).配置需要的location
從上面是nginx.conf 中可以看出,我這裡的server都是在apps子檔案夾建立,我在apps 檔案中有個叫
_mongo.conf 的設定檔,裡面配置這lua 調用mongodb 的location

server {        listen   8081;        server_name 192.168.1.128;        #關閉lua_code 緩衝        lua_code_cache off;        location /lua {                content_by_lua_file  /opt/openresty/lualib/resty/mongol/test_lua.lua;        }        location /lua_mongo {                content_by_lua_file /opt/openresty/lualib/resty/mongol/test_mongol.lua;        }        location /lua_test {                set $test "hello world";                #使用acess 階段做准入條件處理                access_by_lua '                        if (ngx.var.test =="hello world") then                                 ngx.say("驗證通過"..ngx.var.test)                        else                                 ngx.log(ngx.ERR,"驗證失敗","")                        end                ';                #業務處理                content_by_lua '                        ngx.header.content_type ="text/plain";                        local a, b =1;                        ngx.say(ngx.var.test..a);                ';        }}

location lua_mongo 中content_by_lua_file 是lua調用了mongodb具體操作
執行在/opt/openresty/lualib/resty/mongol/下的test_mongol.lua 檔案,該檔案的內容是:

local mongo =require "resty.mongol"local json = require "cjson"--擷取連線物件local conn =mongo:new()conn:set_timeout(1000)--擷取串連用戶端local ok,err =conn:connect("192.168.1.128",27017)if not ok then         ngx.say("connect failed"..err)end --擷取資料庫local db = conn:new_db_handle("leo")--使用者授權local ok ,err = db:auth("zjf","zjf123456")if ok then         ngx.say("user auth success"..ok)end --擷取集合local coll = db:get_col("leonardo")--擷取document集合local cursor = coll:find({})--json 轉碼--function json_decode( str )        local json_value =nil        pcall(function (str) json_value = json.decode(str) end, str)        return json_value end--迴圈 for index,item in cursor:pairs() do        ngx.say('資料: '..index)        if not item['url'] then                 ngx.say('資料:'..item["title"])        else                ngx.say('資料:'..item["title"]..item['url'])                ngx.say(json_decode(item['url']))        endend--擷取單個集合local res =coll:find_one({key = 150})if res then         ngx.say(res['title'])end--插入集合local bson1 ={title ='哈哈',url = 'www.baidu.com',key = 300};--插入table 表中 local docs ={bson1};local rsOk,err =coll:insert(docs,0,0)if err then         ngx.say('error--'..err)else         ngx.say('ok---- '..rsOk)end--刪除操作local deOk,err = coll:delete({title ='你好'},0,0)if err then         ngx.say('delete error--'..err)else        ngx.say('delete ok--'..deOk)end--關閉串連if conn then         conn:close()end 

到這裡一個完整的例子就寫好了 。
(4).啟動mongodb 服務,啟動nginx 服務

[root@leoleo apps]# curl 192.168.1.128:8081/lua_mongo資料: 1資料:哈哈www.baidu.comnil資料: 2資料:哈哈www.baidu.comnil資料: 3資料:哈哈www.baidu.comnilok---- -1delete ok---1[root@leoleo apps]# 

這個demo 就這樣寫好了

3.後話**
使用lua_nginx+mongodb這個方案最後被我們項目組否決了,原因呢。
雖然用lua 可以實現將網頁上收集到使用者操作行為通過的nginx寫入mongodb中;但是lua 直接操作mongodb 有很多缺陷,比如這裡是當執行個體,就是每次寫入都要擷取一個串連執行個體,開啟一個串連;網頁上的行為收集是一個高並發的,顯然這個demo 這樣的是不滿足的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.