起因
———-

     在最近新系統的設計中對於首頁開啟速度的問題做了一些考慮,由於頁面上還是以動態資料為主,所以簡單的靜態化資料可能並不行,所以需要從業務和技術結合的角度去考慮這個問題。由於有些資料並不敏感,其實可以放入快取並定時更新。另外就是有些本身是靜態,能否加快併發相應速度。

    這裡對動態資料想到了2種辦法:1)把Action設定成單例,請求的結果直接加在快取裡,再用一個定時執行緒去重新整理這個快取;2)讓輸出的結果頁靜態化,定時更新結果頁。
    前者控制起來非常靈活,利用雙緩衝也能讓人感覺不到緩衝時的速度下降,缺點就是要改動比較多的程式碼。後者正好相反,靜態化要依靠外層的框架配置,程式碼完全不用改動。

 

選型
———–

    目前比較流行的反向代理伺服器有squid和nginx,查了一下資料,發現nginx比較擅長反向代理和負載均衡,而squid強在自身的快取機制,另外lightd貌似多用來做圖片伺服器。經過比較感覺nginx的配置檔案簡單一些,所以決定用這個先嚐試一下。

 

效能測試
—————-

    安裝完成當然是先做一下效能測試了,這次同樣使用ab來進行壓力測試。為了做對比,這裡也啟動了一個tomcat,nginx配置成其的反向代理。我就在本機進行訪問,但測試結果令我驚歎。

    測試命令:ab -n 10000 -k -c 1000 http://localhost:8080/pscms_hlj_web/p_w_picpaths/logo.jpg

tomcat:


  1. Server Software:        Apache-Coyote/1.1 
  2. Server Hostname:        localhost 
  3. Server Port:            8080 
  4.  
  5. Document Path:          /pscms_hlj_web/p_w_picpaths/logo.jpg 
  6. Document Length:        17619 bytes 
  7.  
  8. Concurrency Level:      1000 
  9. Time taken for tests:   3.671 seconds 
  10. Complete requests:      4254 
  11. Failed requests:        0 
  12. Write errors:           0 
  13. Keep-Alive requests:    4254 
  14. Total transferred:      76035996 bytes 
  15. HTML transferred:       74951226 bytes 
  16. Requests per second:    1158.92 [#/sec] (mean) 
  17. Time per request:       862.874 [ms] (mean) 
  18. Time per request:       0.863 [ms] (mean, across all concurrent requests) 
  19. Transfer rate:          20228.99 [Kbytes/sec] received 
  20.  
  21. Connection Times (ms) 
  22.               min  mean[+/-sd] median   max 
  23. Connect:        0   33  67.4      0     261 
  24. Processing:    52  255  60.1    272     315 
  25. Waiting:       15  129  61.7    127     261 
  26. Total:         52  288 108.0    272     559 

nginx:


  1. Server Software:        nginx/0.7.67 
  2. Server Hostname:        localhost 
  3. Server Port:            8000 
  4.  
  5. Document Path:          /pscms_hlj_web/p_w_picpaths/logo.jpg 
  6. Document Length:        17619 bytes 
  7.  
  8. Concurrency Level:      1000 
  9. Time taken for tests:   0.597 seconds 
  10. Complete requests:      10000 
  11. Failed requests:        0 
  12. Write errors:           0 
  13. Keep-Alive requests:    10000 
  14. Total transferred:      179370000 bytes 
  15. HTML transferred:       176190000 bytes 
  16. Requests per second:    16744.67 [#/sec] (mean) 
  17. Time per request:       59.721 [ms] (mean) 
  18. Time per request:       0.060 [ms] (mean, across all concurrent requests) 
  19. Transfer rate:          293309.69 [Kbytes/sec] received 
  20.  
  21. Connection Times (ms) 
  22.               min  mean[+/-sd] median   max 
  23. Connect:        0    2   8.1      0      44 
  24. Processing:     0   49  19.7     48      97 
  25. Waiting:        0   44  19.8     42      93 
  26. Total:          0   51  19.4     52      99 

    nginx的效能遠遠勝出,這應該是這個頁面會被快取的原因,另外支援epoll肯定也有較高的IO效能提升。但這個測試中也發現tomcat已經很穩的掛掉了,nginx的高併發支援真不是蓋的。

 

結論
———-

    真實系統中不可能有那麼多靜態的內容,因為瀏覽器本地也會有快取,但是nginx會在很大程度上提升對併發響應的能力。對於一些不需要頻繁更新的動態內容也可以做定時快取,這樣也可以大大加快頁面的開啟速度並降低後端壓力。線上系統可以把圖片、js、css、靜態html都快取起來,後端只接受動態內容的請求,從而提速web訪問速度。

 

其他發現
————–

    其實nginx是把快取的內容經過hash後放到檔案中的,雖然測試中來看肯定是在記憶體中拿的結果,但是肯定還是有一次寫入。後來查到linux下面有一個自帶的檔案系統,在/dev/shm下面,預設是記憶體大小的一半。這樣真的可以把快取的內容指向這個檔案裡面就行了。

    另外,nginx也可以很方便的實現雙機熱備和負載均衡。負載均衡可以配置weight來調整訪問比例,系統會自動把請求進行轉向。雙機熱備會在所有節點都不可用時自動轉向,這在系統升級的時候可以做到不中斷服務。這些實現做類似如下配置即可: 


  1. upstream  testproxy  { 
  2.   server   127.0.0.1:8080 weight=10; 
  3.   server   127.0.0.1:8081 weight=10; 
  4.   server   192.168.0.11:8080 backup;