nginx+lua+redis
リリース: 2016-08-08 09:19:06
最近、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 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())}} 多くのストレステストを行った結果、nginx + lua + redis の組み合わせは確かに効率的であり、golang + redis ソリューションは実際にはそれほど変わらないことがわかりました。 。システム全体の開発からデプロイまでの方法と比較すると、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)returnendgolang コード:
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 サーバー、ab ストレス テストはすべて同じマシン上にあり、相互に影響します。興味がある場合は、個別にデプロイしてテストできます。
上記では、関連する内容も含めて nginx+lua+redis を紹介しましたが、PHP チュートリアルに興味のある友人に役立つことを願っています。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
-
2024-10-22 09:46:29
-
2024-10-13 13:53:41
-
2024-10-12 12:15:51
-
2024-10-11 22:47:31
-
2024-10-11 19:36:51
-
2024-10-11 15:50:41
-
2024-10-11 15:07:41
-
2024-10-11 14:21:21
-
2024-10-11 12:59:11
-
2024-10-11 12:17:31