Nginx與Redis解決高併發問題

近期剛改版了上月上線的一個產品應用,以應對未來可能的高併發問題。

 

       初版產品採用的是Jquery,Nginx,PHP(CI框架),Memcache,Mysql這種經常使用的架構。做爲一名PHP工程師對於這種架構已經很是的熟悉了,目前站點併發並非很高,線上環境使用的是阿里雲主機,1.5G的內存,PHP併發能支持400~500左右。由於使用memcache的緣由,若是在併發特別高的狀況下,除了帶寬瓶頸之外就可能會是一直引覺得傲PHP瓶頸了。增長機器便會增長成本,對於一個剛剛上線運行的項目,要求公司擴大投入是不合理的。

 

     因而在第二次改版的過程當中咱們嘗試放棄PHP,採用OpenResty中的LuaJit模塊直接讀取redis中的數據以Json的格式返回給前端頁面展現,使用PHP腳本定時執行向redis裏面更新內容。這樣整合個前端過程就沒啥php與mysql哈事了(除後端定時執行腳本以外)。憑着nginx與redis的高併發,還怕啥呀!。下圖爲新的架構主要結構。

 

Nginx.bmp


        Redis是一個高性能的key-value數據庫。redis的出現,很大程度補償了memcache這類key-value存儲的不足,在部分場合能夠對關係數據庫起到很好的補充做用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便。
性能測試結果:SET操做每秒鐘110000 次,GET操做每秒鐘81000 次

        有了Redis做爲保障,新架構就能夠開搞了,使用到的主要關鍵詞由openResty,LuaJit,Lua,Redis,PHP,PHPRedis,JSon,JQuery等組成。讀者能夠搜索下各名詞瞭解它們的功能。下面是openResty中的Nginx配置:

nginx.conf
server {
        listen   80;

        root/home/boolean/Htdocs/lib.bincent.com;
        index index.htmlindex.htm;
        server_namelib.bincent.cn;

        #默認請求Html轉發到apache,這裏你能夠根據本身狀況配置
        location /
        {
                proxy_redirect off; 
                proxy_set_header HOST$host;  
                proxy_set_headerSERVER_ADDR $server_addr;  
                proxy_set_headerSERVER_PORT $server_port;  
                proxy_set_headerREMOTE_ADDR $remote_addr;  
                proxy_set_headerREMOTE_PORT $remote_port;  
                proxy_pass  http://lib.bincent.cn:8080;
        }

           #更新redis
        location /set_redis
        {
            internal;
            set_unescape_uri$key $arg_key;
                set_unescape_uri$val $arg_val;
                redis2_queryset $key $val;
            redis2_pass127.0.0.1:6379;
        }

           #讀取redis
        location /get_redis
        {
            internal;
            set_unescape_uri$key $arg_key;
            redis2_queryget $key;
            redis2_pass127.0.0.1:6379;
        }

           # 模擬的簡單請求
        location /json
        {
            default_typetext/html;
                 content_by_lua_file/home/boolean/Htdocs/lib.bincent.com/lua/redis.lua;
        }

}

redis.lua文件
#經過URL更新redisphp

functionsetRedis(key, val)
    localres = ngx.location.capture('/set_redis', {
                args= {
                     key= key,
                     val= val
                    }
                })
    ifres.status == 200 then
        returntrue
    else
        returnfalse
    end
end
#經過URL讀取redis
functiongetRedis(key)
    localcapture = ngx.location.capture('/get_redis', {
                args= {
                    key= key
                    }
                })
    localparser = require 'redis.parser' --require redis.parser
    localres, err = parser.parse_reply(capture.body)
   
    returnres
end
#URL參數$_GET['a']
locala = ngx.var.arg_a
if'clean' == a then
    --重置redis
    ifsetRedis('love_number', 0) then
        ngx.say("CleanRedis Is Success!")
    else
        ngx.say("CleanRedis Is failted!")
    end
else
    --讀取redis
    locallove_number = getRedis('love_number') + 1
    setRedis('love_number',love_number)
    ngx.say("CurrentLove Number Is: ", love_number)
end
相關文章
相關標籤/搜索