Nginx Lua Redis

WBOY
WBOYOriginal
2016-08-08 09:19:061177Durchsuche
Vor Kurzem verwende ich nginx+lua+redis, um ein System zur Unterstützung von Anwendungen mit hoher Parallelität und hohem Datenverkehr aufzubauen. Während der Entwicklung dachte ich plötzlich, ob Golang den gleichen Effekt erzielen könnte. Also habe ich einen einfachen Code zum Vergleich geschrieben. Ich werde nicht auf Details eingehen. Im Internet gibt es viele Einführungen zum Erstellen von Anwendungen mit hoher Parallelität. Ich verwende openresty+lua+redis. Veröffentlichen Sie zuerst die Testergebnisse. Bei der Maschine handelt es sich um die neue Low-Profile-Air, die 2013 herausgebracht wurde – (1,3 GHz Intel Core i5, 4 GB 1600 MHz DDR3), Befehl: 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-Code: -- 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-Code: 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())}} nach vielen Mal Nach Stresstests haben wir festgestellt, dass die Kombination von Nginx + Lua + Redis tatsächlich effizient ist und die Lösung von Golang + Redis nicht viel anders ist. Verglichen mit der Art und Weise, wie das gesamte System entwickelt und bereitgestellt wird, ist Golang möglicherweise besser geeignet und entspricht eher den Entwicklungsgewohnheiten. Schließlich ist die Entwicklung und das Testen von Nginx + Lua etwas umständlich. Zusätzliche Verbindungspoolnutzung und Testergebnisse

Nach dem letzten Test hatte ich das Gefühl, dass es in diesem Code Raum für Verbesserungen gibt, also habe ich überprüft, wie man den Redis-Verbindungspool in Golang verwendet (Tatsächlich handelt es sich um die Verwendung von Redigo) und um die Verwendung des Redis-Verbindungspools in Lua (tatsächlich handelt es sich um die Verwendung von rest.redis).

Zuerst zu den Ergebnissen gehen:

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

Dann schauen Sie sich Golang an:

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-Code:

-- 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-Code:

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 fügt nicht nur einen Thread-Pool hinzu, sondern legt auch die Anzahl der CPU-Kerne fest.

Dieser Test ist jedoch nicht sehr streng. Redis, Nginx, der Golang-HTTP-Server und der AB-Stresstest befinden sich alle auf demselben Computer und beeinflussen sich gegenseitig. Wenn Sie interessiert sind, können Sie es separat bereitstellen und testen.

Das Obige hat Nginx Lua Redis vorgestellt, einschließlich einiger Aspekte davon. Ich hoffe, es wird für Freunde hilfreich sein, die sich für PHP-Tutorials interessieren.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn