天天看點

如何測試Nginx的高性能

簡介

Nginx ("engine x") 是一個高性能的HTTP和反向代理伺服器,也是一個IMAP/POP3/SMTP代理伺服器;

作為一款輕量級的Web伺服器,具有占有記憶體少,并發能力強等優勢,是高連接配接并發場景下Apache的不錯的替代品;

本篇主要介紹Nginx作為Web伺服器時,相對于Apache的性能優勢;

下一篇将會介紹Nginx作為方向代理伺服器的實作;

重要特點

非阻塞:資料複制時,磁盤I/O的第一階段是非阻塞的;

事件驅動:通信機制采用epoll模型,支援更大的并發連接配接;

master/worker結構:一個master程序,生成一個或多個worker程序;

基礎架構

<a href="http://s3.51cto.com/wyfs02/M02/25/80/wKioL1NhsRCizui1AAJjCxv__qo087.jpg" target="_blank"></a>

Nginx如何實作高并發:

I/O模型采用異步非阻塞的事件驅動機制,由程序循環處理多個準備好的事件,如epoll機制;

Nginx與Apache對高并發處理上的差別:

對于Apache,每個請求都會獨占一個工作線程,當并發量增大時,也會産生大量的工作線程,導緻記憶體占用急劇上升,同時線程的上下文切換也會導緻CPU開銷增大,導緻在高并發場景下性能下降嚴重;

對于Nginx,一個worker程序隻有一個主線程,通過事件驅動機制,實作循環處理多個準備好的事件,進而實作輕量級和高并發;

部署配置

安裝

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

<code>yum -y groupinstall “Development tools”</code>

<code>yum -y groupinstall “Server Platform Development”</code>

<code>yum </code><code>install</code> <code>gcc openssl-devel pcre-devel zlib-devel</code>

<code>groupadd -r nginx</code>

<code>useradd</code> <code>-r -g nginx -s </code><code>/sbin/nologin</code> <code>-M nginx</code>

<code>tar</code> <code>xf nginx-1.4.7.</code><code>tar</code><code>.gz</code>

<code>cd</code> <code>nginx-1.4.7</code>

<code>mkdir</code> <code>-pv </code><code>/var/tmp/nginx</code>

<code>.</code><code>/configure</code> <code>\</code>

<code>  </code><code>--prefix=</code><code>/usr</code> <code>\</code>

<code>  </code><code>--sbin-path=</code><code>/usr/sbin/nginx</code> <code>\</code>

<code>  </code><code>--conf-path=</code><code>/etc/nginx/nginx</code><code>.conf \</code>

<code>  </code><code>--error-log-path=</code><code>/var/log/nginx/error</code><code>.log \</code>

<code>  </code><code>--http-log-path=</code><code>/var/log/nginx/access</code><code>.log \</code>

<code>  </code><code>--pid-path=</code><code>/var/run/nginx/nginx</code><code>.pid  \</code>

<code>  </code><code>--lock-path=</code><code>/var/lock/nginx</code><code>.lock \</code>

<code>  </code><code>--user=nginx \</code>

<code>  </code><code>--group=nginx \</code>

<code>  </code><code>--with-http_ssl_module \</code>

<code>  </code><code>--with-http_flv_module \</code>

<code>  </code><code>--with-http_stub_status_module \</code>

<code>  </code><code>--with-http_gzip_static_module \</code>

<code>  </code><code>--http-client-body-temp-path=</code><code>/var/tmp/nginx/client/</code> <code>\</code>

<code>  </code><code>--http-proxy-temp-path=</code><code>/var/tmp/nginx/proxy/</code> <code>\</code>

<code>  </code><code>--http-fastcgi-temp-path=</code><code>/var/tmp/nginx/fcgi/</code> <code>\</code>

<code>  </code><code>--http-uwsgi-temp-path=</code><code>/var/tmp/nginx/uwsgi</code> <code>\</code>

<code>  </code><code>--http-scgi-temp-path=</code><code>/var/tmp/nginx/scgi</code> <code>\</code>

<code>  </code><code>--with-pcre</code>

<code>make</code> <code>&amp;&amp; </code><code>make</code> <code>install</code>

配置

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

<code>vi</code> <code>/etc/init</code><code>.d</code><code>/nginx</code> <code># 配置服務腳本</code>

<code>#!/bin/sh</code>

<code>#</code>

<code># nginx - this script starts and stops the nginx daemon</code>

<code># chkconfig:   - 85 15</code>

<code># description:  Nginx is an HTTP(S) server, HTTP(S) reverse \</code>

<code>#               proxy and IMAP/POP3 proxy server</code>

<code># processname: nginx</code>

<code># config:      /etc/nginx/nginx.conf</code>

<code># config:      /etc/sysconfig/nginx</code>

<code># pidfile:     /var/run/nginx.pid</code>

<code># Source function library.</code>

<code>. </code><code>/etc/rc</code><code>.d</code><code>/init</code><code>.d</code><code>/functions</code>

<code># Source networking configuration.</code>

<code>. </code><code>/etc/sysconfig/network</code>

<code># Check that networking is up.</code>

<code>[ </code><code>"$NETWORKING"</code> <code>= </code><code>"no"</code> <code>] &amp;&amp; </code><code>exit</code> <code>0</code>

<code>nginx=</code><code>"/usr/sbin/nginx"</code>

<code>prog=$(</code><code>basename</code> <code>$nginx)</code>

<code>NGINX_CONF_FILE=</code><code>"/etc/nginx/nginx.conf"</code>

<code>[ -f </code><code>/etc/sysconfig/nginx</code> <code>] &amp;&amp; . </code><code>/etc/sysconfig/nginx</code>

<code>lockfile=</code><code>/var/lock/subsys/nginx</code>

<code>make_dirs() {</code>

<code>   </code><code># make required directories</code>

<code>   </code><code>user=`nginx -V 2&gt;&amp;1 | </code><code>grep</code> <code>"configure arguments:"</code> <code>| </code><code>sed</code> <code>'s/[^*]*--user=\([^ ]*\).*/\1/g'</code> <code>-`</code>

<code>   </code><code>options=`$nginx -V 2&gt;&amp;1 | </code><code>grep</code> <code>'configure arguments:'</code><code>`</code>

<code>   </code><code>for</code> <code>opt </code><code>in</code> <code>$options; </code><code>do</code>

<code>       </code><code>if</code> <code>[ `</code><code>echo</code> <code>$opt | </code><code>grep</code> <code>'.*-temp-path'</code><code>` ]; </code><code>then</code>

<code>           </code><code>value=`</code><code>echo</code> <code>$opt | </code><code>cut</code> <code>-d </code><code>"="</code> <code>-f 2`</code>

<code>           </code><code>if</code> <code>[ ! -d </code><code>"$value"</code> <code>]; </code><code>then</code>

<code>               </code><code># echo "creating" $value</code>

<code>               </code><code>mkdir</code> <code>-p $value &amp;&amp; </code><code>chown</code> <code>-R $user $value</code>

<code>           </code><code>fi</code>

<code>       </code><code>fi</code>

<code>   </code><code>done</code>

<code>}</code>

<code>start() {</code>

<code>    </code><code>[ -x $nginx ] || </code><code>exit</code> <code>5</code>

<code>    </code><code>[ -f $NGINX_CONF_FILE ] || </code><code>exit</code> <code>6</code>

<code>    </code><code>make_dirs</code>

<code>    </code><code>echo</code> <code>-n $</code><code>"Starting $prog: "</code>

<code>    </code><code>daemon $nginx -c $NGINX_CONF_FILE</code>

<code>    </code><code>retval=$?</code>

<code>    </code><code>echo</code>

<code>    </code><code>[ $retval -</code><code>eq</code> <code>0 ] &amp;&amp; </code><code>touch</code> <code>$lockfile</code>

<code>    </code><code>return</code> <code>$retval</code>

<code>stop() {</code>

<code>    </code><code>echo</code> <code>-n $</code><code>"Stopping $prog: "</code>

<code>    </code><code>killproc $prog -QUIT</code>

<code>    </code><code>[ $retval -</code><code>eq</code> <code>0 ] &amp;&amp; </code><code>rm</code> <code>-f $lockfile</code>

<code>restart() {</code>

<code>    </code><code>configtest || </code><code>return</code> <code>$?</code>

<code>    </code><code>stop</code>

<code>    </code><code>sleep</code> <code>1</code>

<code>    </code><code>start</code>

<code>reload() {</code>

<code>    </code><code>echo</code> <code>-n $</code><code>"Reloading $prog: "</code>

<code>    </code><code>killproc $nginx -HUP</code>

<code>    </code><code>RETVAL=$?</code>

<code>force_reload() {</code>

<code>    </code><code>restart</code>

<code>configtest() {</code>

<code>  </code><code>$nginx -t -c $NGINX_CONF_FILE</code>

<code>rh_status() {</code>

<code>    </code><code>status $prog</code>

<code>rh_status_q() {</code>

<code>    </code><code>rh_status &gt;</code><code>/dev/null</code> <code>2&gt;&amp;1</code>

<code>case</code> <code>"$1"</code> <code>in</code>

<code>    </code><code>start)</code>

<code>        </code><code>rh_status_q &amp;&amp; </code><code>exit</code> <code>0</code>

<code>        </code><code>$1</code>

<code>        </code><code>;;</code>

<code>    </code><code>stop)</code>

<code>        </code><code>rh_status_q || </code><code>exit</code> <code>0</code>

<code>    </code><code>restart|configtest)</code>

<code>    </code><code>reload)</code>

<code>        </code><code>rh_status_q || </code><code>exit</code> <code>7</code>

<code>    </code><code>force-reload)</code>

<code>        </code><code>force_reload</code>

<code>    </code><code>status)</code>

<code>        </code><code>rh_status</code>

<code>    </code><code>condrestart|try-restart)</code>

<code>            </code><code>;;</code>

<code>    </code><code>*)</code>

<code>        </code><code>echo</code> <code>$</code><code>"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"</code>

<code>        </code><code>exit</code> <code>2</code>

<code>esac</code>

<code>chmod</code> <code>+x </code><code>/etc/init</code><code>.d</code><code>/nginx</code> <code># 複***務腳本執行權限</code>

<code>vi</code> <code>/etc/nginx/nginx</code><code>.conf </code><code># 編輯主配置檔案</code>

<code>worker_processes  2;</code>

<code>error_log  </code><code>/var/log/nginx/nginx</code><code>.error.log;</code>

<code>pid        </code><code>/var/run/nginx</code><code>.pid;</code>

<code>events {</code>

<code>    </code><code>worker_connections  1024;</code>

<code>http {</code>

<code>    </code><code>include       mime.types;</code>

<code>    </code><code>default_type  application</code><code>/octet-stream</code><code>;</code>

<code>    </code><code>log_format  main  </code><code>'$remote_addr - $remote_user [$time_local] "$request" '</code>

<code>                      </code><code>'$status $body_bytes_sent "$http_referer" '</code>

<code>                      </code><code>'"$http_user_agent" "$http_x_forwarded_for"'</code><code>;</code>

<code>    </code><code>sendfile        on;</code>

<code>    </code><code>keepalive_timeout  65;</code>

<code>    </code><code>server {</code>

<code>        </code><code>listen       80;</code>

<code>        </code><code>server_name  xxrenzhe.lnmmp.com;</code>

<code>        </code><code>access_log  </code><code>/var/log/nginx/nginx</code><code>.access.log  main;</code>

<code>        </code><code>location / {</code>

<code>            </code><code>root   </code><code>/www/lnmmp</code><code>.com;</code>

<code>            </code><code>index  index.php index.html index.htm;</code>

<code>        </code><code>}</code>

<code>        </code><code>error_page  404              </code><code>/404</code><code>.html;</code>

<code>        </code><code>error_page  500 502 503 504  </code><code>/50x</code><code>.html;</code>

<code>        </code><code>location = </code><code>/50x</code><code>.html {</code>

<code>        </code><code>location ~ \.php$ {</code>

<code>            </code><code>root           </code><code>/www/lnmmp</code><code>.com;</code>

<code>            </code><code>fastcgi_pass   127.0.0.1:9000;</code>

<code>            </code><code>fastcgi_index  index.php;</code>

<code>            </code><code>fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;</code>

<code>            </code><code>include        fastcgi_params;</code>

<code>    </code><code>}</code>

<code>vi</code> <code>/etc/nginx/fastcgi_params</code> <code># 編輯fastcgi參數檔案</code>

<code>fastcgi_param  GATEWAY_INTERFACE  CGI</code><code>/1</code><code>.1;</code>

<code>fastcgi_param  SERVER_SOFTWARE    nginx;</code>

<code>fastcgi_param  QUERY_STRING       $query_string;</code>

<code>fastcgi_param  REQUEST_METHOD     $request_method;</code>

<code>fastcgi_param  CONTENT_TYPE       $content_type;</code>

<code>fastcgi_param  CONTENT_LENGTH     $content_length;</code>

<code>fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;</code>

<code>fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;</code>

<code>fastcgi_param  REQUEST_URI        $request_uri;</code>

<code>fastcgi_param  DOCUMENT_URI       $document_uri;</code>

<code>fastcgi_param  DOCUMENT_ROOT      $document_root;</code>

<code>fastcgi_param  SERVER_PROTOCOL    $server_protocol;</code>

<code>fastcgi_param  REMOTE_ADDR        $remote_addr;</code>

<code>fastcgi_param  REMOTE_PORT        $remote_port;</code>

<code>fastcgi_param  SERVER_ADDR        $server_addr;</code>

<code>fastcgi_param  SERVER_PORT        $server_port;</code>

<code>fastcgi_param  SERVER_NAME        $server_name;</code>

啟動服務

<code>service nginx configtest </code><code># 服務啟動前先驗證配置檔案是否正确</code>

<code>service nginx start</code>

<code>ps</code> <code>-ef |</code><code>grep</code> <code>nginx </code><code># 檢查nginx程序,尤其是worker程序是否與worker_processes值一緻</code>

<code>ss -antupl |</code><code>grep</code> <code>80 </code><code># 檢查服務端口是否啟動</code>

性能測試

測試說明

每次測試都進行3次,最後資料取平均值;

對比測試中的Apache采用event的MPM機制,最大化提高Apache的并發性能;

每次測試後,都需重新啟動服務(httpd或nginx),以防止多次測試資料不準;

測試工具:webbench

優點:比ab能更好的模拟并發請求,最大支援模拟30000并發連接配接;

測試方法

<code># 安裝wenbench</code>

<code>wget http:</code><code>//blog</code><code>.s135.com</code><code>/soft/linux/webbench/webbench-1</code><code>.5.</code><code>tar</code><code>.gz</code>

<code>tar</code> <code>xf webbench-1.5.</code><code>tar</code><code>.gz</code>

<code>cd</code> <code>webbench-1.5</code>

<code># 測試</code>

<code>webbench -c 100 -t 30 http:</code><code>//172</code><code>.16.25.112</code><code>/nginx</code><code>.html </code><code># 測試靜态檔案通路</code>

<code>webbench -c 20 -t 30 http:</code><code>//172</code><code>.16.25.112</code><code>/test_mem</code><code>.php </code><code># 測試動态檔案通路</code>

測試資料

分析趨勢圖

靜态檔案通路趨勢圖

動态檔案通路趨勢圖

總結

綜合上面測試得出的趨勢圖可以看出:

靜态檔案測試時,低并發(200以下)情況下,Nginx和Apach的處理能力相當(2000pages/sec左右),當并發數超過200後,則Apache的處理能力開始下降,而Nginx保持穩定;同時随着并發量的增大,Apache令人诟病的記憶體占用和負載開始急劇上升,與此同時,Nginx在記憶體占用和負載方面的略微提升則可以忽略不計了;

動态檔案測試時,低并發(100以下)情況下,Nginx和Apache的處理能力相當(650pages/sec左右),但Nginx的記憶體占用和負載峰值隻有Apache的50%左右;在高并發情況下(100以上),Apach的動态處理能力開始下滑,當并發達到500時,開始出現失敗的請求,說明此時已達到的Apache的處理上限了,而反觀Nginx,雖然處理動态請求會消耗更多的記憶體,但其處理能力随着并發量的上升而上升,即使并發1000動态請求,也未達到其處理能力上限;

故不管是在靜态檔案請求還是動态檔案請求方面,Nginx的性能都是強勢優于Apache的;雖然可以通過系統調優的方式提高Apache的處理性能,但和Nginx相比,還是不足以打動技術狂熱份子的吧,哈哈!

本文轉自 xxrenzhe11 51CTO部落格,原文連結:http://blog.51cto.com/xxrenzhe/1405272,如需轉載請自行聯系原作者

繼續閱讀