nginx+lua+redis 代替nginx+php+redis 收集數(shù)據(jù) x

今天對于數(shù)據(jù)收集的接口修改成nginx+lua+redis收集數(shù)據(jù),cron腳本處理數(shù)據(jù)交胚。

環(huán)境

使用OpenResty + redis
2核4G centos6.4

nginx配置

server {
    listen 80;
    server_name t.com;

    rewrite ^\/collect  /LUA/ last;
    rewrite ^(.*)$          /index.php?_RW_=$1 last;

    location /LUA/{
        default_type text/html;
        content_by_lua_file /web/test/lua/collect.lua;
    }
    
    location / {
        root /web/test/wwwroot;
    }

}

collect.lua 請求處理腳本

local function breakpoint()
    ngx.say('breakpoint');
    ngx.eof();
end

local function getPostFormArgv()
    local function explode(_str, seperator)
        local pos, arr = 0, {}
        for st, sp in function() return string.find(_str, seperator, pos, true) end do
            table.insert(arr, string.sub(_str, pos, st - 1))
            pos = sp + 1
        end
        table.insert(arr, string.sub(_str, pos))
        return arr
    end

    local receive_headers = ngx.req.get_headers()
    ngx.req.read_body()
    local body = ngx.req.get_body_data()

    local seperator = '--' .. string.sub(receive_headers["content-type"], 31)
    local tmp = explode(body, seperator)
    table.remove(tmp, 1)
    table.remove(tmp)

    local argv = {}
    for k, v in pairs(tmp) do
        local start_pos, end_pos, key, val = string.find(v, 'Content%-Disposition: form%-data; name="([^\"]+)"(.*)')
        argv[key] = string.gsub(val, "[\r\n]", '')
    end
    return argv
end

local function getPostJsonArgv()
    local json = require('cjson');
    ngx.req.read_body()
    local body = ngx.req.get_body_data()
    if body == nil then
        return {}
    end
    local argv = json.decode(body);
    return argv
end

local function getPostArgv()
    local receive_headers = ngx.req.get_headers()
    local argv = {}

    if receive_headers["content-type"] and string.sub(receive_headers["content-type"], 1, 20) == "multipart/form-data;" then
        argv = getPostFormArgv()
    else
        argv = getPostJsonArgv()
    end
    return argv
end


local argv;
-- 獲取post參數(shù)
argv = getPostArgv();
if (argv.running == nil) then
    ngx.say('{"code":101}');
    return
end

-- 獲取header數(shù)據(jù)

local headers = ngx.req.get_headers();
argv.mac = headers.mac;

-- 存redis
local redis = require "resty.redis"
local red = redis:new()

red:set_timeout(1000) -- 1 sec

local ok, err = red:connect("127.0.0.1", 6380)
if not ok then
    ngx.say("failed to connect: ", err)
    return
end

local json = require('cjson');
local json_string = json.encode(argv);

red:lpush('ng_running', json_string);

red:close()

ngx.say('{"code":100}');
ngx.eof();

Nginx API for Lua https://github.com/openresty/lua-nginx-module#nginx-api-for-lua

壓力測試

先用Curl測試上面代碼是否存在問題

curl http://t.com/test -H "uid:1" -H "from:curl" -X POST -d'{"a":"1","b":"2"}'

使用ab測試

ab -c 500 -n 1000 -H "uid:1" -H "from:curl" -p post.text http://t.com/test

#運(yùn)行結(jié)果
Server Software:        openresty/1.13.6.1
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /api/test
Document Length:        13 bytes

Concurrency Level:      500
Time taken for tests:   0.480 seconds
Complete requests:      2000
Failed requests:        0
Total transferred:      352000 bytes
Total body sent:        2094000
HTML transferred:       26000 bytes
Requests per second:    4166.27 [#/sec] (mean)
Time per request:       120.011 [ms] (mean)
Time per request:       0.240 [ms] (mean, across all concurrent requests)
Transfer rate:          716.08 [Kbytes/sec] received
                        4259.85 kb/s sent
                        4975.92 kb/s total

對比我用php寫的收集腳本际邻,同樣是接收數(shù)據(jù)寫入redis装哆,吞吐量在260左右罐脊,lua的方案在4200左右。

Server Software:        openresty/1.13.6.1
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /api/test2
Document Length:        24 bytes

Concurrency Level:      500
Time taken for tests:   7.617 seconds
Complete requests:      2000
Failed requests:        0
Total transferred:      386000 bytes
Total body sent:        2104000
HTML transferred:       48000 bytes
Requests per second:    262.59 [#/sec] (mean)
Time per request:       1904.128 [ms] (mean)
Time per request:       3.808 [ms] (mean, across all concurrent requests)
Transfer rate:          49.49 [Kbytes/sec] received
                        269.77 kb/s sent
                        319.26 kb/s total

ab性能指標(biāo)

參考 https://www.cnblogs.com/yueminghai/p/6412254.html

在進(jìn)行性能測試過程中有幾個(gè)指標(biāo)比較重要:

1蜕琴、吞吐率(Requests per second)

服務(wù)器并發(fā)處理能力的量化描述萍桌,單位是reqs/s,指的是在某個(gè)并發(fā)用戶數(shù)下單位時(shí)間內(nèi)處理的請求數(shù)凌简。某個(gè)并發(fā)用戶數(shù)下單位時(shí)間內(nèi)能處理的最大請求數(shù)上炎,稱之為最大吞吐率。

記壮А:吞吐率是基于并發(fā)用戶數(shù)的藕施。這句話代表了兩個(gè)含義:

a、吞吐率和并發(fā)用戶數(shù)相關(guān)

b凸郑、不同的并發(fā)用戶數(shù)下裳食,吞吐率一般是不同的

計(jì)算公式:總請求數(shù)/處理完成這些請求數(shù)所花費(fèi)的時(shí)間,即
Request per second=Complete requests/Time taken for tests

必須要說明的是芙沥,這個(gè)數(shù)值表示當(dāng)前機(jī)器的整體性能诲祸,值越大越好。

2而昨、并發(fā)連接數(shù)(The number of concurrent connections)

并發(fā)連接數(shù)指的是某個(gè)時(shí)刻服務(wù)器所接受的請求數(shù)目救氯,簡單的講,就是一個(gè)會(huì)話歌憨。

3着憨、并發(fā)用戶數(shù)(Concurrency Level)

要注意區(qū)分這個(gè)概念和并發(fā)連接數(shù)之間的區(qū)別,一個(gè)用戶可能同時(shí)會(huì)產(chǎn)生多個(gè)會(huì)話务嫡,也即連接數(shù)甲抖。在HTTP/1.1下,IE7支持兩個(gè)并發(fā)連接心铃,IE8支持6個(gè)并發(fā)連接准谚,F(xiàn)ireFox3支持4個(gè)并發(fā)連接,所以相應(yīng)的于个,我們的并發(fā)用戶數(shù)就得除以這個(gè)基數(shù)。

4暮顺、用戶平均請求等待時(shí)間(Time per request)

計(jì)算公式:處理完成所有請求數(shù)所花費(fèi)的時(shí)間/(總請求數(shù)/并發(fā)用戶數(shù))厅篓,即:
Time per request=Time taken for tests/(Complete requests/Concurrency Level)

5秀存、服務(wù)器平均請求等待時(shí)間(Time per request:across all concurrent requests)

計(jì)算公式:處理完成所有請求數(shù)所花費(fèi)的時(shí)間/總請求數(shù),即:
Time taken for/testsComplete requests

可以看到羽氮,它是吞吐率的倒數(shù)或链。

同時(shí),它也等于用戶平均請求等待時(shí)間/并發(fā)用戶數(shù)档押,即
Time per request/Concurrency Level

ab報(bào)錯(cuò)處理

apr_socket_recv: Connection reset by peer (104)

解決方法:加參數(shù) -r

參考:https://www.cnblogs.com/pengyusong/p/5737915.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末澳盐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子令宿,更是在濱河造成了極大的恐慌叼耙,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粒没,死亡現(xiàn)場離奇詭異筛婉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)癞松,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門爽撒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人响蓉,你說我怎么就攤上這事硕勿。” “怎么了枫甲?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵源武,是天一觀的道長。 經(jīng)常有香客問我言秸,道長软能,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任举畸,我火速辦了婚禮查排,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抄沮。我一直安慰自己跋核,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布叛买。 她就那樣靜靜地躺著砂代,像睡著了一般。 火紅的嫁衣襯著肌膚如雪率挣。 梳的紋絲不亂的頭發(fā)上刻伊,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼捶箱。 笑死智什,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丁屎。 我是一名探鬼主播荠锭,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼晨川!你這毒婦竟也來了证九?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤共虑,失蹤者是張志新(化名)和其女友劉穎愧怜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體看蚜,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叫搁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了供炎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渴逻。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖音诫,靈堂內(nèi)的尸體忽然破棺而出惨奕,到底是詐尸還是另有隱情,我是刑警寧澤竭钝,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布梨撞,位于F島的核電站,受9級特大地震影響香罐,放射性物質(zhì)發(fā)生泄漏卧波。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一庇茫、第九天 我趴在偏房一處隱蔽的房頂上張望港粱。 院中可真熱鬧,春花似錦旦签、人聲如沸查坪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偿曙。三九已至,卻和暖如春羔巢,著一層夾襖步出監(jiān)牢的瞬間望忆,已是汗流浹背罩阵。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留启摄,地道東北人永脓。 一個(gè)月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像鞋仍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子搅吁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容