天天看點

Nginx+tomct 動靜分離實作負載均衡

 0.前期準備

  使用Debian環境。安裝Nginx(預設安裝),一個web項目,安裝tomcat(預設安裝)等。

  1.一份Nginx.conf配置檔案

Nginx+tomct 動靜分離實作負載均衡
1 # 定義Nginx運作的使用者 和 使用者組 如果對應伺服器暴露在外面的話建議使用權限較小的使用者 防止被入侵
  2 # user www www;
  3 
  4 #Nginx程序數, 建議設定為等于CPU總核心數
  5 worker_processes 8;
  6 
  7 #開啟全局錯誤日志類型
  8 error_log /var/log/nginx/error.log info;
  9 
 10 #程序檔案
 11 pid /var/run/nginx.pid;
 12 
 13 #一個Nginx程序打開的最多檔案描述數目 建議與ulimit -n一緻
 14 #如果面對高并發時 注意修改該值 ulimit -n 還有部分系統參數 而并非這個單獨确定
 15 worker_rlimit_nofile 65535;
 16 
 17 events{
 18     #使用epoll模型提高性能
 19     use epoll;
 20     #單個程序最大連接配接數
 21     worker_connections 65535;
 22 }
 23 
 24 http{
 25     #擴充名與檔案類型映射表
 26     include mime.types;
 27     #預設類型
 28     default_type application/octet-stream;
 29     sendfile on;
 30     tcp_nopush on;
 31     tcp_nodelay on;
 32     keepalive_timeout 65;
 33     types_hash_max_size 2048;
 34     #日志
 35     access_log /var/log/nginx/access.log;
 36     error_log /var/log/nginx/error.log;
 37     #gzip 壓縮傳輸
 38     gzip on;
 39     gzip_min_length 1k;  #最小1K
 40     gzip_buffers 16 64K;
 41     gzip_http_version 1.1;
 42     gzip_comp_level 6;
 43     gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
 44     gzip_vary on;
 45     #負載均衡組
 46     #靜态伺服器組
 47     upstream static.zh-jieli.com {
 48         server 127.0.0.1:808 weight=1;
 49     }
 50     #動态伺服器組
 51     upstream zh-jieli.com {
 52         server 127.0.0.1:8080;
 53         #server 192.168.8.203:8080;
 54     }
 55     #配置代理參數
 56     proxy_redirect off;
 57     proxy_set_header Host $host;
 58     proxy_set_header X-Real-IP $remote_addr;
 59     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 60     client_max_body_size 10m;
 61     client_body_buffer_size 128k;
 62     proxy_connect_timeout 65;
 63     proxy_send_timeout 65;
 64     proxy_read_timeout 65;
 65     proxy_buffer_size 4k;
 66     proxy_buffers 4 32k;
 67     proxy_busy_buffers_size 64k;
 68     #緩存配置
 69     proxy_cache_key '$host:$server_port$request_uri';
 70     proxy_temp_file_write_size 64k;
 71     proxy_temp_path /dev/shm/JieLiERP/proxy_temp_path;
 72     proxy_cache_path /dev/shm/JieLiERP/proxy_cache_path levels=1:2 keys_zone=cache_one:200m inactive=5d max_size=1g;
 73     proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;
 74 
 75     server{
 76         listen 80;
 77         server_name erp.zh-jieli.com;
 78         location / {
 79             index index; #預設首頁為 /index
 80             #proxy_pass http://jieli;
 81         }
 82         location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 83             proxy_cache cache_one;
 84             proxy_cache_valid 200 304 302 5d;
 85             proxy_cache_valid any 5d;
 86             proxy_cache_key '$host:$server_port$request_uri';
 87             add_header X-Cache '$upstream_cache_status from $host';
 88             proxy_pass http://static.zh-jieli.com;
 89             #所有靜态檔案直接讀取硬碟
 90             #           root /var/lib/tomcat7/webapps/JieLiERP/WEB-INF ;
 91             expires 30d; #緩存30天
 92         }
 93         #其他頁面反向代理到tomcat容器
 94         location ~ .*$ {
 95             index index;
 96             proxy_pass http://zh-jieli.com;
 97         }
 98     }
 99     server{
100         listen 808;
101         server_name static;
102         location / {
103 
104         }
105         location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
106             #所有靜态檔案直接讀取硬碟
107             root /var/lib/tomcat7/webapps/JieLiERP/WEB-INF ;
108             expires 30d; #緩存30天
109         }
110     }
111 }      
Nginx+tomct 動靜分離實作負載均衡

  基本配置這個檔案,就可以實作負載了。但是裡面的各種關系要了解就比較麻煩了。這篇部落格,也不是教學篇,是記錄一下,友善以後自己看了。

  2.基礎講解

  現在假使有一台電腦192.168.8.203這台電腦,上面部署了Tomcat,裡面8080端口有J2EE的服務,通過浏覽器可以正常浏覽網頁。現在有一個問題tomcat是一個比較全面的web容器,對靜态網頁的處理,應該是比較費資源的,特别是每次都要從磁盤讀取靜态頁面,然後傳回。這中間會消耗Tomcat的資源,可能會使那些動态頁面解析性能影響。秉承Linux哲學,一個軟體隻做一件事的原則。Tomcat就應該隻處理JSP動态頁面。這裡就用到以前了解的Nginx來進行反向代理。第一步代理,實作動靜網頁分離。這個很簡單的。

Nginx+tomct 動靜分離實作負載均衡
1      worker_processes 8;
 2         
 3         pid /var/run/nginx.pid;
 4         
 5         worker_rlimit_nofile 65535;
 6         
 7         events{
 8             use epoll;
 9             worker_connections 65535;
10         }
11         
12         http{
13             include mime.types;
14             default_type application/octet-stream;
15             sendfile on;
16             tcp_nopush on;
17             tcp_nodelay on;
18             keepalive_timeout 65;
19             types_hash_max_size 2048;
20 
21             proxy_redirect off;
22             proxy_set_header Host $host;
23             proxy_set_header X-Real-IP $remote_addr;
24             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
25             client_max_body_size 10m;
26             client_body_buffer_size 128k;
27             proxy_connect_timeout 65;
28             proxy_send_timeout 65;
29             proxy_read_timeout 65;
30             proxy_buffer_size 4k;
31             proxy_buffers 4 32k;
32             proxy_busy_buffers_size 64k;
33         
34             server{
35                 listen 80;
36                 server_name xxx.com;
37                 location / {
38                     index index; 
39                 }
40                 location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
41                     proxy_pass http://192.168.8.203:8080;
42                     expires 30d; 
43                 }
44                 location ~ .*$ {
45                     index index;
46                     proxy_pass http://192.168.8.203:8080;
47                 }
48             }
49         }      
Nginx+tomct 動靜分離實作負載均衡

  修改nginx的配置檔案 /etc/nginx/nginx.conf 預設有個配置檔案的。其實大部分都差不多,關鍵還是server段的設定。這裡我設定server段如上所示,其他段複制就可以了。server段裡面的解釋如下:第35行為監聽本機80端口。37-39行表示預設首頁,這裡的預設首頁我是index.jsp 對應到我項目中是一個index。 這裡根據需要可以改為 

index index.jsp index.html index.htm index.php      

   具體可參考其他文章。 關鍵的第40行,這個是正則比對,網上也有很多介紹。這裡比對我項目中用到的所有靜态網頁字尾。第41行是代理位址。這裡我代理到我的web應用中。expires 30d緩存為30天,這裡的緩存是對應到前端頁面,使用者的Cache-Control字段,

Nginx+tomct 動靜分離實作負載均衡

   第44行中那個正則是比對無字尾的頁面。我項目中jsp頁面是無字尾的。這裡可以根據需要進行修改。同樣代理到192.168.8.203:8080這裡。到這裡你可能會問,我艹,這有毛意思啊?當然不是這樣了。簡單的實作靜動分離,我們可以把第41行進行修改,改為

root   /var/lib/tomcat7/webapps/JieLiERP/WEB-INF      

  表示不代理,直接從本地磁盤拿。通過查tomcat日志可以看到靜态頁面是沒有通路到的。但這樣又有一個問題。這樣的靈活性不好,對下面要講到的記憶體緩存和叢集部署來說都是不友好的,是以又有了下面的這種寫法。再寫一個server段。

Nginx+tomct 動靜分離實作負載均衡
1     server{
 2         listen 808;
 3         server_name static;
 4         location / {
 5 
 6         }
 7         location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 8             #所有靜态檔案直接讀取硬碟
 9             root /var/lib/tomcat7/webapps/JieLiERP/WEB-INF ;
10             expires 30d; #緩存30天
11         }
12     }      
Nginx+tomct 動靜分離實作負載均衡

  這次監聽808端口,然後上上面的代碼41行就可以修改為 proxy_pass http://192.168.8.203:808了,到這裡就實作了動靜分離了。如果多台伺服器,就修改對應的ip就可以了。如果發現連接配接不上的,要檢查一下防火牆,權限等外部問題,這個配置是這樣的。

  如果單純這樣的話,我們會發現頁面直接傳輸過于占用帶寬。對應web的優化,這裡想到的是通過對頁面進行gzip壓縮,然後傳到使用者那裡,再解壓,這樣可以有效的減少帶寬。這裡就會用到Nginx 的gzip子產品了。預設的Nginx是內建有gzip子產品的。隻需在http段增加下面配置即可。

Nginx+tomct 動靜分離實作負載均衡
1     gzip on;
2     gzip_min_length 1k;  #最小1K
3     gzip_buffers 16 64K;
4     gzip_http_version 1.1;
5     gzip_comp_level 6;
6     gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
7     gzip_vary on;      
Nginx+tomct 動靜分離實作負載均衡

  給個首頁看看效果

Nginx+tomct 動靜分離實作負載均衡
Nginx+tomct 動靜分離實作負載均衡

  不要在意請求數不一樣,那兩個請求是谷歌插件來的。不用覺得我在騙你。

  作為假使有很多人通路的網站來說,緩存肯定是很重要的東西了。一開始是想通過插件,讓Nginx和Redis進行合成,然後Nginx使用Redis來緩存的,但是發現配置起來很麻煩,還要自己下載下傳插件,重新編譯Nginx,比較麻煩,是以這裡覺得用Nginx自帶的緩存也是不錯的選擇。雖然效率比不上redis,但是有還是比沒有好。Nginx預設的緩存是磁盤檔案系統的緩存,而不是像Redis那樣的記憶體級别的緩存。一開始我以為Nginx就隻有這樣。後來查了寫資料,才知道是我太天真了,對Linux不是很了解導緻的。Linux的一切皆檔案。原來我們可以把檔案緩存到記憶體對應的Linux檔案系統中。我說的可能比較難以了解,請自行搜尋/dev/shm 這個檔案目錄。我們把檔案緩存到這個檔案目錄裡,其實就相當與記憶體的緩存了。隻不過還是靠檔案系統管理。是以比不上自定義格式的Redis那樣的記憶體緩存。

  在http段進行基本配置

1 #緩存配置
2     proxy_cache_key '$host:$server_port$request_uri';
3     proxy_temp_file_write_size 64k;
4     proxy_temp_path /dev/shm/JieLiERP/proxy_temp_path;
5     proxy_cache_path /dev/shm/JieLiERP/proxy_cache_path levels=1:2 keys_zone=cache_one:200m inactive=5d max_size=1g;
6     proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;      
Nginx+tomct 動靜分離實作負載均衡
1         location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
 2             proxy_cache cache_one;
 3             proxy_cache_valid 200 304 302 5d;
 4             proxy_cache_valid any 5d;
 5             proxy_cache_key '$host:$server_port$request_uri';
 6             add_header X-Cache '$upstream_cache_status from $host';
 7             proxy_pass http://192.168.8.203:808;
 8 
 9             expires 30d; #緩存30天
10         }      
Nginx+tomct 動靜分離實作負載均衡

  經過這兩個的配置就基本能實作了,這裡說幾個注意項,也是困擾我很久的問題。上面第一段代碼第6行,proxy_ignore_headers 如果web項目中的html的head頭裡面指定

1 <meta http-equiv="pragma" content="no-cache">
2 <meta http-equiv="cache-control" content="no-cache">
3 <meta http-equiv="expires" content="0">      

  這些不緩存的話,就要加上proxy_ignore_headers的配置項了。還有一點就是/dev/shm下面的檔案系統權限預設隻給root使用者,是以要chmod 777 -R /dev/shm 這樣不是很安全的做法,如果實際上線可以給定某個使用者組,關于使用者組的設定是配置的第一行

user www www;      

  上面第二段代碼的第6行是增加一個header字段友善檢視是否擊中緩存。

  我們rm -rf /dev/shm/JieLiERP/proxy_* 下面的所有檔案(注意這裡如果是進行多次測試的話要nginx -s reload 重新讀取配置或重新開機服務,因為你rm -rf隻是删除了緩存檔案,但是緩存的結構資訊還在nginx程序裡面,結構還在,如果不重新開機的話,是會出現通路不到的)

Nginx+tomct 動靜分離實作負載均衡

  是以要記得重新開機哦。下面是運作效果

  第一次通路

Nginx+tomct 動靜分離實作負載均衡

  第二次通路,在浏覽器中Ctrl+Shift+R 強制重新整理

Nginx+tomct 動靜分離實作負載均衡

  到這裡就可以看到效果了。我們檢視一下/dev/shm這個裡面

Nginx+tomct 動靜分離實作負載均衡

  到這裡已經快結束了。最後也是比較關鍵的一個技術點,就是叢集,叢集,叢集。這個就要用到upstream了,看到最開頭的配置檔案了嗎,就是那個

#負載均衡組
#靜态伺服器組
upstream static {
    server 127.0.0.1:808 weight=1;
    server 192.168.8.203:808 weight=1;
}      
#動态伺服器組
upstream dynamic {
    server 127.0.0.1:8080;
    #server 192.168.8.203:8080;
}      

  上面那個就是叢集組了。upstream是關鍵字,static 和 dynamic是兩個伺服器叢集組的名稱。以第一個為例,server 127.0.0.1:808 是伺服器位址,後面的weight=1 是權重。有多個就寫多個。親測試過,叢集中的一個壞了,不影響系統運作。至于更多的輪詢規則,可以參考網上更多的資料。這裡不多說。至于怎麼使用呢? proxy_pass http://192.168.8.203:808 改為 proxy_pass http://static; 這樣即可實作均衡。

  到這裡就結束了。把上面各個部分根據自己需求配置起來就可以實作單機房負載均衡了。 上面這種做法有一個缺點就是在前面的那一台nginx如果當機,後面是以機器就失去了被通路的能力了,是以需要在前面實作多個nginx多機房的負載。關于這個就是另外一個話題了。目前還沒有研究。以後有機會再說了。

  上面動态伺服器組如果是那種需要儲存使用者狀态的話,會有問題,就是session問題,比如我在server1進行登入後,下一次動态伺服器組進行輪詢後可能配置設定到server2,就會造成要重新登入。治标的辦法是,配置輪詢規則,根據使用者請求的IP進行Hash,然後配置設定對應的伺服器。具體配置如下:

1 upstream dynamic{
2     ip_hash;
3     server 127.0.0.1:8080;
4     server 192.168.0.203:8080;
5 }      

  這樣就可以實作一個使用者對應一個伺服器節點。這樣就不會有重複登入的問題。另一種治本的辦法是,利用緩存系統進行session的統一存儲管理。具體的做法我還沒有試驗過,參考資料有相關的文章,可以了解一下。

  參考資料:

  http://www.ha97.com/5194.html Nginx配置檔案nginx.conf中文詳解

  http://saiyaren.iteye.com/blog/1956692 nginx cache靜态化+tmpfs 高性能cdn方案

  http://www.oschina.net/question/35243_180072 Nginx配置了proxy_cache為什麼不能産生緩存檔案

  http://www.ttlsa.com/nginx/nginx-enforce-cache/ nginx強制緩存

  http://www.cnblogs.com/dudu/p/4597351.html 解決nginx反向代理緩存不起作用的問題

  http://blog.csdn.net/akon_vm/article/details/8494620 緩存nginx伺服器的靜态檔案

  http://www.cnblogs.com/lengfo/p/4260363.html 基于nginx tomcat redis分布式web應用的session共享配置

  本文位址: http://www.cnblogs.com/wunaozai/p/5001742.html

     本片文章是經過作者允許轉載的,隻是參考借鑒。如果文章中有什麼錯誤,希望到家要自己及時糾正。

繼續閱讀