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的高并发,还怕啥呀!。下图为新的架构主要结构。
?
? ?? ???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更新redis
functionsetRedis(key, val)? ??localres = ngx.location.capture('/set_redis', {? ?? ?? ?? ?? ??args= {? ?? ?? ?? ?? ?? ?? ?key= key,? ?? ?? ?? ?? ?? ?? ?val= val? ?? ?? ?? ?? ?? ???}? ?? ?? ?? ?? ??})? ??ifres.status == 200 then? ?? ???returntrue? ??else? ?? ???returnfalse? ??endend#通过URL读取redisfunctiongetRedis(key)? ??localcapture = ngx.location.capture('/get_redis', {? ?? ?? ?? ?? ??args= {? ?? ?? ?? ?? ?? ???key= key? ?? ?? ?? ?? ?? ???}? ?? ?? ?? ?? ??})? ??localparser = require 'redis.parser' --require redis.parser? ??localres, err = parser.parse_reply(capture.body)? ?? ??returnresend#URL参数$_GET['a']locala = ngx.var.arg_aif'clean' == a then? ??--重置redis? ??ifsetRedis('love_number', 0) then? ?? ???ngx.say("CleanRedis Is Success!")? ??else? ?? ???ngx.say("CleanRedis Is failted!")? ??endelse? ??--读取redis? ??locallove_number = getRedis('love_number') + 1? ??setRedis('love_number',love_number)? ??ngx.say("CurrentLove Number Is: ", love_number)end
?
?
转自:http://bbs.phpchina.com/thread-229629-1-1.html
1 楼 zhangping2056 2014-01-08 楼主接下来要考虑页面静态化与细节上面的东西了