Nginx+Tomcat整合體驗
轉載地址:https://segmentfault.com/a/1190000007803704
Nginx是一款輕量級的Web伺服器/反向代理伺服器及電子郵件(IMAP/POP3)代理伺服器。在Java的Web架構中,通常使用Tomcat和Nginx進行配合,Nginx作為反向代理伺服器,可以對後臺的Tomcat伺服器負載均衡,也可以讓Nginx處理靜態頁面的請求、Tomcat處理JSP頁面請求達到動靜分離的目的。
Nginx簡介
Nginx ("engine x") 是一個高效能的HTTP和反向代理伺服器,也是一個IMAP/POP3/SMTP伺服器,是由Igor Sysoev為俄羅斯訪問量第二的Rambler.ru站點開發的。其特點是佔有記憶體少,併發能力強,事實上nginx的併發能力確實在同類型的網頁伺服器中表現較好,中國大陸使用nginx網站使用者有:百度、京東、新浪、網易、騰訊、淘寶等。
截止到2014年12月31日,Nginx僅次於apache成為第二大web伺服器軟體,而在全球最忙碌top10000網站中使用比例更是高達42.7%。其發展速度和流行程度已經遠遠超過其它同類軟體,成為大型網站和高併發網站的首選。
Nginx由核心和一系列模組組成,核心提供web服務的基本功能,如啟用網路協議,建立執行環境,接收和分配客戶端請求,處理模組之間的互動。Nginx的各種功能和操作都由模組來實現。Nginx的模組從結構上分為核心模組、基礎模組和第三方模組。
核心模組: HTTP模組、EVENT模組和MAIL模組
基礎模組: HTTP Access模組、HTTP FastCGI模組、HTTP Proxy模組和HTTP Rewrite模組
第三方模組: HTTP Upstream Request Hash模組、Notice模組和HTTP Access Key模組及使用者自己開發的模組
這樣的設計使Nginx方便開發和擴充套件,也正因此才使得Nginx功能如此強大。Nginx的模組預設編譯進nginx中,如果需要增加或刪除模組,需要重新編譯Nginx,這一點不如Apache的動態載入模組方便。如果有需要動態載入模組,可以使用由淘寶網發起的web伺服器Tengine,在nginx的基礎上增加了很多高階特性,完全相容Nginx,已被國內很多網站採用。
開發環境搭建
下面進入正題,對Nginx和Tomcat進行整合使用。首選是開發環境的搭建,包括JDK、Tomcat和Nginx。本文的實驗環境是Ubuntu。
JDK安裝
下載JDK,並解壓到指定目錄中。
lap@lap-KVM:~$ wget http: //120.52.72.24/download.oracle.com/c3pr90ntc0td/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz
lap@lap-KVM:~$ tar zxvf jdk-7u79-linux-x64.tar.gz
lap@lap-KVM:~$ sudo mv jdk1.7.0_79/ /usr/local/jdk
配置環境變數,在/etc/profile中新增JAVA_HOME等路徑。
export JAVA_HOME=/usr/local/jdk
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
載入環境變數。
lap@lap-KVM:~$ source /etc/profile
檢視是否配置成功。
java -version
顯示以下結果則配置成功:
Tomcat安裝
第二步是Tomcat的安裝。
下載Tomcat,並解壓到指定目錄中。
lap@lap-KVM:~$ wget http://apache.fayea.com/tomcat/tomcat-8/v8.5.9/bin/apache-tomcat-8.5.9.tar.gz
lap@lap-KVM:~$ tar zxvf apache-tomcat-8.5.9.tar.gz
lap@lap-KVM:~$ sudo mv apache-tomcat-8.5.9/ /usr/local/tomcat
關於Tomcat的配置以及設定普通使用者等在這裡就不提了。直接啟動Tomcat。
lap@lap-KVM:~$ sudo /usr/local/tomcat/bin/startup.sh
若出現以下提示,表示找不到JAVA_HOME的路徑
此時需要在Tomcat的bin目錄下的catalina.sh中加入以下資訊:
再次啟動Tomcat,成功
Nginx安裝
接下來就是主角Nginx。
下載Nginx,解壓,安裝到指定目錄。
lap@lap-KVM:~$ wget http://labfile.oss.aliyuncs.com/nginx-1.7.9.tar.gz
lap@lap-KVM:~$ tar zxvf nginx-1.7.9.tar.gz
lap@lap-KVM:~$ cd nginx-1.7.9
lap@lap-KVM:~/nginx-1.7.9$ ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module
lap@lap-KVM:~/nginx-1.7.9$ # make && make install
切換到Nginx的安裝目錄下,啟動Nginx。
lap@lap-KVM:~$ cd /usr/local/nginx/
lap@lap-KVM:/usr/local/nginx$ sudo ./nginx-1.7.9/objs/nginx
此時訪問http://localhost,將可以看到Nginx的歡迎介面。(因為我不是直接在Nginx本機上訪問的,所以是用的Nginx伺服器的IP:192.168.6.86來訪問的,本文接下去的部分都是這樣。)
Nginx配置
Nginx可以通過調整配置檔案的引數,對效能進行優化。這個配置檔案就是nginx.conf。
nginx.vim
題外話,由於使用Nginx經常需要編輯nginx.conf,我們可以藉助nginx.vim來使nginx.conf語法高亮,看起來更清晰明瞭。
移動到/usr/share/vim/vim74/syntax/目錄
在/usr/share/vim/vim74/filetypr.vim中新增:
au BufRead,BufNewFile /usr/local/nginx/conf/* set ft=nginx
再開啟nginx.conf,已經有語法高亮了:
nginx.conf
nginx.conf裡面提供了很多可以調節優化的地方,這裡簡要了解http模組的幾個常用引數。這一部分內容參考實驗樓的教程。
如圖,是我的nginx.conf的配置
簡單介紹一下紅色方框內的一些配置引數。
第一個方框內的是關於日誌的設定:
log_format 定義日誌格式
access_log 設定是否儲存訪問日誌,設定為off可以降低磁碟IO而提升速度。
第二個方框內的是一些基本設定:
sendfile 指向sendfile()函式。sendfile()在磁碟和TCP埠(或者任意兩個檔案描述符)之間複製資料。sendfile()直接從磁碟上讀取資料到作業系統緩衝,因此會更有效率。
tcp_nopush 配置nginx在一個包中傳送全部的標頭檔案,而不是一個一個傳送。
tcp_nodelay 配置nginx不要快取資料,快速傳送小資料。
keepalive_timeout 指定了與客戶端的keep-alive連結的超時時間。伺服器會在這個時間後關閉連結。
第三個方框內的是關於壓縮功能的設定:
gzip 開啟壓縮功能可以減少需要傳送的資料的數量。
gzip_disable 為指定的客戶端禁用 gzip 功能。
gzip_proxied 允許或禁止基於請求、響應的壓縮。設定為any,就可以gzip所有的請求。
gzip_comp_level 設定了資料壓縮的等級。等級可以是 1-9 的任意一個值,9 表示最慢但是最高比例的壓縮。
gzip_types 設定進行 gzip 的型別。
接下來看一下http模組中的子模組server,以及server中的子模組location的配置:
其中:
listen 表示當前的代理伺服器監聽的埠,預設的是監聽80埠。
server_name 表示監聽到之後需要轉到哪裡去,localhost表示轉到本地,也就是直接到nginx資料夾內。
location 表示匹配的路徑。
root 表示到指定檔案路徑尋找檔案,可用於靜態檔案。
index 表示預設主頁,可以指定多個,按順序查詢。
deny和allow 是訪問控制設定,禁止或允許某個IP或者某個IP段訪問。也可以指定unix,允許socket的訪問。
limit_rate_after 設定不限速傳輸的響應大小。當傳輸量大於此值時,超出部分將限速傳送。
limit_rate 限制向客戶端傳送響應的速率限制。引數的單位是位元組/秒,設定為0將關閉限速。比如圖片中表示不限速部分為3m,超過了3m後限速為20k/s。
關於Nginx的更多配置解釋,可以參考這篇博文,講的非常詳細。
注意,修改完配置檔案後需要重啟nginx生效。當然,如果你的Nginx是用apt-get安裝的,可以用nginx -s reload命令重新載入配置檔案即可。
Nginx+Tomcat
接下來就進入本文的主題,將Nginx和Tomcat整合在一起使用。這部分工作其實也就是修改nginx.conf裡的配置。
JSP頁面請求交給Tomcat處理
具體的,在nginx.conf中新建一個location,用正則表示式將所有JSP的請求匹配到該location中:
其中最核心的就是"proxy_pass http://localhost:8080;"這條配置,它將匹配到的請求都轉發給Tomcat去處理。
其他的配置:
proxy_set_header Host $host; 後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IP。
client_max_body_size 10m; 允許客戶端請求的最大單檔案位元組數。
client_body_buffer_size 128k; 緩衝區代理緩衝使用者端請求的最大位元組數。
proxy_connect_timeout 90; Nginx跟後端伺服器連線超時時間。
proxy_read_timeout 90; 連線成功後,後端伺服器響應時間。
proxy_buffer_size 4k; 設定代理伺服器儲存使用者頭資訊的緩衝區大小。
proxy_buffers 6 32k; proxy_buffers緩衝區。
proxy_busy_buffers_size 64k; 高負荷下緩衝大小。
proxy_temp_file_write_size 64k; 設定快取資料夾大小。
此時訪問http://localhost/index.jsp,會發現跳轉到了Tomcat的頁面。但是你會發現,此時的頁面是這樣的:
這是因為雖然JSP的請求轉發給Tomcat的了,但是圖片、css等靜態檔案卻找不到。所以接下來我們要配置靜態檔案的路徑,完成動靜分離。
動靜分離
對於靜態檔案的請求,我們也新建一個location,將常見圖片、css、js等請求匹配到該location中
如圖所示,配置非常簡單,通過root關鍵字,將匹配到的請求都到tomcat/webapps/ROOT目錄下直接查詢。而expires 30d則表示使用expires快取模組,快取到客戶端30天。
配置完後重啟Nginx。再輸入http://localhost/index.jsp,會發現此時的Tomcat頁面已經正常顯示了。我們已經完成了JSP請求與靜態檔案請求的動靜分離。但是實際上也只是顯示這個頁面而已,當你點選頁面上的其他連結時,會顯示404,這是顯然的,因為我們只配置了ROOT目錄。
如果配置完仍然發現無法讀取靜態檔案,看看訪問http://localhost/tomcat.png時是否顯示403 forbidden。如果是的話就是因為許可權問題導致的,這裡簡單的解決辦法是把nginx.conf首行的user設為root:
當然,如果不想使用root使用者執行,可以通過修改目錄訪問許可權解決403問題,但不能把目錄放在root使用者宿主目錄下,放在任意一個位置並給它755,或者通過chown改變它的擁有者與Nginx執行身份一致也可以解決許可權問題。
負載均衡
接下來我們來實驗一下負載均衡。
在nginx.conf中,通過配置upstream,可以很輕鬆配置後臺伺服器的負載均衡:
具體的,可以在upstream中配置後臺Tomcat伺服器的地址,這裡我是配置了兩臺伺服器,分別是本機也就是192.168.6.86和192.168.6.32,其中本機安裝的是Tomcat8,另一臺安裝的是Tomcat7,以示區別。然後在location中,將請求轉發給配置好的upstream處理。這裡為了不跟前面的配置產生衝突,我新配置了一個server,監聽8888埠。
可以看到,顯示的頁面分別是Tomcat7和Tomcat8的主頁,證明請求轉發成功。
另外,你也可以在server後面加上一個權重weight,權重越大表示訪問到的機會越大,預設為1。