首頁  >  文章  >  後端開發  >  nginx+lua+redis

nginx+lua+redis

WBOY
WBOY原創
2016-08-08 09:19:061139瀏覽
最近在使用nginx+lua+redis做一個系統,來支撐高並發高訪問量的應用。開發時突然想到golang是不是也可以達到同樣的效果。於是寫了個簡單的程式碼比較一下。 具體就不多做介紹了,網路上很多關於nginx+lua+redis構建高並發應用的介紹。我使用的是openresty+lua+redis。 先貼上測試結果,機器就是2013年新出的低配air——(1.3 GHz Intel Core i5, 4 GB 1600 MHz DDR3), 指令:ab -n 1000 -c 100 http://localhost :8880/openresty+lua+redis: Concurrency Level: 100 Time taken for tests: 0.458 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 689000 bytes HTML transferred: 533000 bytes Requests per second: 2183.67 [#/sec] (mean) Time per request: 45.794 [ms] (mean) Time per request: 0.458 [ms] (mean, across all concurrent requests) Transfer rate: 1469.29 [Kbytes/sec] received golang+redis: Concurrency Level: 100 Time taken for tests: 0.503 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 650000 bytes HTML transferred: 532000 bytes Requests per second: 1988.22 [#/sec] (mean) Time per request: 50.296 [ms] (mean) Time per request: 0.503 [ms] (mean, across all concurrent requests) Transfer rate: 1262.05 [Kbytes/sec] received lua代碼:-- redis 配置localparams={host='127.0.0.1',port=6379,}localred=redis:new()localok,err=red:connect(params.host,params.port)ifnotokthenngx.say("failed to connect: ",err)returnendlocalposition_key=ngx.var.position_keylocalcontent=red:get(position_key)ngx.print(content)golang代碼:packagemainimport("fmt""github.com/garyburd/redigo/redis""log""net/http""time")funcgetConn()(redis.Conn,error){conn,err:=redis.DialTimeout("tcp",":6379",0,1*time.Second,1*time.Second)iferr!=nil{fmt.Println(err)}returnconn,err}funcindexHandler(whttp.ResponseWriter,r*http.Request){conn,err:=getConn()iferr!=nil{http.Error(w,err.Error(),http.StatusInternalServerError)return}result,err:=conn.Do("get","content_1")iferr!=nil{http.Error(w,err.Error(),http.StatusInternalServerError)return}fmt.Fprintf(w,"Hello, %q",result)}funcmain(){http.HandleFunc("/",indexHandler)err:=http.ListenAndServe(":8880",nil)iferr!=nil{log.Fatal("ListenAndServe: ",err.Error())}}經過多次壓測之後發現,nginx + lua + redis的組合確實高效,golang + redis的方案其實也差不了多少。相對於整個系統從開發到部署的方式來說,golang可能更合適,更符合開發的習慣,畢竟nginx + lua 這種方案開發和測試都略顯彆扭。 補充連接池的使用和測試結果

上次測試完之後,覺得這個代碼還有提高的空間,於是查了下怎麼在golang中使用redis連接池(其實就是redigo的使用),還有lua中怎麼使用redis連線池(其實就是rest.redis的使用)。

先上結果:

openresty + lua + redis Concurrency Level: 100 Time taken for tests: 0.284 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 687000 bytes HTML transferred: 531000 bytes Requests per second: 3522.03 [#/sec] (mean) Time per request: 28.393 [ms] (mean) Time per request: 0.284 [ms] (mean, across all concurrent requests) Transfer rate: 2362.93 [Kbytes/sec] received

再看golang:

golang + redis Concurrency Level: 100 Time taken for tests: 0.327 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 650000 bytes HTML transferred: 532000 bytes Requests per second: 3058.52 [#/sec] (mean) Time per request: 32.696 [ms] (mean) Time per request: 0.327 [ms] (mean, across all concurrent requests) Transfer rate: 1941.44 [Kbytes/sec] received

lua程式碼:

-- redis 配置localparams={host='127.0.0.1',port=6379,}localred=redis:new()localok,err=red:connect(params.host,params.port)ifnotokthenngx.say("failed to connect: ",err)returnendlocalposition_key=ngx.var.position_keylocalcontent=red:get(position_key)ngx.print(content)localok,err=red:set_keepalive(10000,100)ifnotokthenngx.say("failed to set keepalive: ",err)returnend

golang程式碼:

packagemainimport("flag""fmt""github.com/garyburd/redigo/redis""log""net/http""runtime""time")var(pool*redis.PoolredisServer=flag.String("redisServer",":6379",""))funcindexHandler(whttp.ResponseWriter,r*http.Request){t0:=time.Now()conn:=pool.Get()t1:=time.Now()fmt.Printf("The call took %v to run.\n",t1.Sub(t0))deferconn.Close()result,err:=conn.Do("get","content_1")iferr!=nil{http.Error(w,err.Error(),http.StatusInternalServerError)return}fmt.Fprintf(w,"Hello, %q",result)}funcnewPool(serverstring)*redis.Pool{return&redis.Pool{MaxIdle:3,IdleTimeout:240*time.Second,Dial:func()(redis.Conn,error){c,err:=redis.Dial("tcp",server)iferr!=nil{returnnil,err}returnc,err},TestOnBorrow:func(credis.Conn,ttime.Time)error{_,err:=c.Do("PING")returnerr},}}funcmain(){runtime.GOMAXPROCS(runtime.NumCPU())flag.Parse()pool=newPool(*redisServer)http.HandleFunc("/",indexHandler)err:=http.ListenAndServe(":8880",nil)iferr!=nil{log.Fatal("ListenAndServe: ",err.Error())}}

golang中除了加入了執行緒池,還設定了cpu核數。

不過這個測試並不十分嚴謹,redis,nginx,golang http server,ab壓測都在一台機器,相互之間會有影響。有興趣的可以自己分開部署測試下。

以上就介紹了nginx+lua+redis,包含了方面的內容,希望對PHP教程有興趣的朋友有幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn