使用Nginx服務(wù)器如何實(shí)現(xiàn)動靜分離和反向代理
我們使用的Tomcat是一個Java的JSP/Servlet動態(tài)服務(wù)器,但并不是一個優(yōu)秀靜態(tài)資源服務(wù)器,使用Tomcat作為Java Web服務(wù)器沒有問題,但用它來提供圖片、CSS、和HTML靜態(tài)資源的話訪問效率并不高(rps不高)。
在真實(shí)的Web應(yīng)用中,JSP/Servlet的請求量相比靜態(tài)資源(如圖片、CSS、JS等等)的請求量要少得多,如果用Tomcat同時兼做動態(tài)、靜態(tài)服務(wù)器,Tomcat的短板就會凸顯。
為此,我們常常需要把靜態(tài)資源分離出來交給更高效的HTTP服務(wù)器去管理,這種作法稱為“動靜分離”。
1 Nginx服務(wù)器
1.1 Nginx簡介
(1)什么是Nginx
Nginx (engine x)是一個高性能的HTTP靜態(tài)服務(wù)器和反向代理服務(wù)器,其特點(diǎn)是占用內(nèi)存少,并發(fā)能力強(qiáng)。
Nginx服務(wù)器的官網(wǎng)下載地址為:nginx: download。
(2)Nginx的三種作用
靜態(tài)資源服務(wù)器、反向代理和負(fù)載均衡服務(wù)器。
“反向代理”是代理服務(wù)器的一種。服務(wù)器根據(jù)客戶端的請求,從其關(guān)系的一組或多組后端服務(wù)器(如Web服務(wù)器)上獲取資源,然后再將這些資源返回給客戶端,客戶端只會得知反向代理的IP地址,而不知道在代理服務(wù)器后面的服務(wù)器簇的存在。
與反向代理相反的是“前向代理”,前向代理作為客戶端的代理,將從互聯(lián)網(wǎng)上獲取的資源返回給一個或多個的客戶端,服務(wù)端(如Web服務(wù)器)只知道代理的IP地址而不知道客戶端的IP地址。
“負(fù)載均衡(Load Balance)”意思就是把任務(wù)分?jǐn)偟蕉鄠€操作單元上進(jìn)行執(zhí)行,從而共同完成工作任務(wù)。在實(shí)際環(huán)境中運(yùn)行的Web服務(wù)器(如Tomcat),面對著大量的并發(fā)請求,如果可以把請求統(tǒng)一接收并均衡平攤到多臺服務(wù)器上,就可以讓應(yīng)用程序承載更多的負(fù)荷。
1.2 Nginx安裝和運(yùn)行
Nginx的安裝包是一個zip文件,只需解壓即可使用。
通過Nginx目錄下的nginx.exe命令就可以運(yùn)行Nginx服務(wù)器,格式如下:
nginx -選項(xiàng) 參數(shù)
常用指令如下:
命令 | 描述 |
start nginx | 啟動nginx服務(wù)器 |
nginx -t | 測試配置文件是否有語法錯誤 |
nginx -s stop | 立即停止nginx服務(wù)器 |
nginx -s quit | 優(yōu)雅的退出nginx服務(wù)器 |
nginx -s reload | 重啟nginx服務(wù)器 |
Nginx在生產(chǎn)中的主要功能是 “靜態(tài)資源服務(wù)器” 和 “反向代理服務(wù)器”。Nginx服務(wù)器功能是通過配置文件“~/conf/nginx.conf”來定制的。
在控制臺中運(yùn)行nginx.exe,就可以在瀏覽器輸入localhost訪問nginx。
2 使用Nginx實(shí)現(xiàn)靜態(tài)資源服務(wù)器
假設(shè)我們把網(wǎng)站的靜態(tài)資源放置在磁盤文件夾下(例如“D:\SpringMVC_Nginx\web-static\static”),通過修改nginx的配置文件就可以用Nginx把它們以HTTP的方式公布出來。
(1)配置靜態(tài)資源服務(wù)器
修改Nginx安裝目錄下的“\conf\nginx.conf”文件。修改其中的“server”配置信息如下。
server { #添加靜態(tài)資源映射路徑 /static/ location /static/ { root D:\SpringMVC_Nginx\web-static; #設(shè)置根目錄對應(yīng)的文件夾 autoindex on; #會自動顯示資源目錄 index noindex.htm; } }
(2)重啟Nginx
通過安裝目錄下的nginx.exe程序,可以控制服務(wù)器的啟動關(guān)閉。
使用控制臺命令行進(jìn)入nginx安裝目錄,執(zhí)行以下指令重啟nginx:
nginx.exe -s reload
(3)訪問靜態(tài)資源
啟動后就能通過HTTP請求訪問靜態(tài)資源了。
3 使用Nginx實(shí)現(xiàn)對Tomcat的反向代理
通過上述配置,瀏覽器可以通過Nginx服務(wù)器提供的“http://localhost/static/......”訪問靜態(tài)資源。
同樣原理,我們希望Tomcat中的項(xiàng)目也可以由Nginx代理出去,Tomcat服務(wù)器由Nginx包裝后,對外只需要暴露Nginx服務(wù)即可,這種代理方式稱之為“反向代理”。
(1)啟動Tomcat中的項(xiàng)目(例如:http://localhost:8080/demo/)
(2)在nginx配置文件nginx.conf中的Server配置節(jié)中添加如下的配置:
server { # ……省略原有配置…… #反向代理Tomcat服務(wù)器 location /demo/ { proxy_pass http://localhost:8080/demo/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # ……省略原有配置…… }
(3)重啟nginx
nginx -s reload
這時,我們可以通過nginx服務(wù)器 http://localhost/demo/index 訪問原來Tomcat中http://localhost:8080/demo/index的頁面。
這樣就實(shí)現(xiàn)了反向代理。
4 把文件上傳到靜態(tài)資源服務(wù)器
這時,在Tomcat項(xiàng)目中,我們只要通過http://localhost/static/路徑就可以訪問靜態(tài)資源,如果要上傳文件的話,我們就應(yīng)該存放在nginx對應(yīng)的靜態(tài)資源目錄(如:上述的D:\SpringMVC_Nginx\web-static)。
因?yàn)檫@個虛擬路徑(例如:http://localhost/static/)和物理路徑都不和tomcat直接相關(guān),因此對編程帶來一些麻煩,為此我們可以采取配置的方式來統(tǒng)一處理路徑問題。
(1)配置靜態(tài)資源路徑
為了方便編程中使用,我們可以把靜態(tài)資源URL(static url)和實(shí)際存放資源的物理路徑配置在項(xiàng)目中。例如,放置在web.xml中。
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> …其他配置… <context-param> <param-name>staticUrl</param-name> <param-value>http://localhost/static</param-value> </context-param> <context-param> <param-name>staticPath</param-name> <param-value>D:\SpringMVC_Nginx\web-static\static</param-value> </context-param> </web-app>
(2)在頁面中使用
通過EL表達(dá)式“${staticUrl}”,我們可以在jsp頁面中使用靜態(tài)資源路徑。
例如:
<img src="${initParam.staticUrl}/images/1.gif" alt="" />
(3)在代碼中使用
在項(xiàng)目代碼中,我們也可以通過ServletContext對象讀取路徑參數(shù)。
例如:
request.getServletContext().getInitParameter("staticPath")
最后,注意上傳文件的保存地址,不再是Tomcat服務(wù)器的部署地址,而是Nginx服務(wù)器的靜態(tài)資源放置地址。
以下是SpringMVC保存上傳文件的示例代碼。
@RequestMapping("/save") public String save(Photo photo, MultipartFile image, HttpServletRequest req) throws IllegalStateException, IOException { if(!image.isEmpty()) { String ext = image.getOriginalFilename() .substring(image.getOriginalFilename().lastIndexOf(".")); String filename = System.currentTimeMillis()+ext; photo.setFilename(filename); photoMapper.add(photo); String path = req.getServletContext().getInitParameter("staticPath") +"/images/"+filename; image.transferTo(new File(path)); return "redirect:index"; }else { return "error"; } }
還需要注意的是,在真實(shí)的環(huán)境中,動態(tài)資源服務(wù)器(Tomcat)和靜態(tài)資源服務(wù)器(Nginx)往往不會放在同一臺機(jī)器上,這時保存文件的地址就不是本機(jī)路徑了,有可能需要在Nginx所在服務(wù)器中創(chuàng)建FTP服務(wù),然后在Java Web程序中通過FTP的方式把用戶上傳的文件再次用FTP方式上傳到Nginx服務(wù)器上。
實(shí)際應(yīng)用中也很可能直接購買各種云服務(wù)器上的靜態(tài)資源提供者服務(wù)。
5 負(fù)載均衡簡介
前面提到,Nginx還可以反向代理多臺后端的Web服務(wù)器,實(shí)現(xiàn)反向代理功能。下面用Nginx反向代理兩臺Tomcat服務(wù)器來簡單演示負(fù)載均衡的實(shí)現(xiàn)。
為了能快速啟動多個Tomcat實(shí)例,我們使用Spring Boot工具快速構(gòu)建包含Tomcat的Jar項(xiàng)目。啟動兩個功能相同的Tomcat實(shí)例,請求地址分別為:
http://localhost:8080/index
http://localhost:8090/index
配置Nginx的nginx.conf文件,增加upstream配置節(jié),并設(shè)置反向代理。請參見下方配置中紅字部分。
upstream 中配置的weight是負(fù)載均衡中各后端服務(wù)器的權(quán)重。下面配置的權(quán)重都是10,意味著兩臺服務(wù)器負(fù)載量均等。
…… upstream tomcat_server{ server 127.0.0.1:8080 weight=10; server 127.0.0.1:8090 weight=10; } server { listen 80; server_name localhost; #反向代理Tomcat服務(wù)器 location /demo/ { proxy_pass http://tomcat_server/demo/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } ……
重新加載nginx,我們監(jiān)控兩個后端服務(wù)器接收到的請求情況,發(fā)現(xiàn)兩臺服務(wù)器被輪流訪問。
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Nginx轉(zhuǎn)發(fā)丟失cookie表現(xiàn)形式及解決方案
本文主要介紹了Nginx轉(zhuǎn)發(fā)丟失cookie表現(xiàn)形式及解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01使用Nginx創(chuàng)建臨時和永久重定向的具體示例
HTTP 重定向 是將一個域名或地址指向另一個的方法,有幾種不同類型的重定向,每種對客戶端瀏覽器意味著不同的事情,最常見的兩種類型是臨時重定向和永久重定向,本文給大家介紹了使用Nginx創(chuàng)建臨時和永久重定向的具體示例,需要的朋友可以參考下2024-07-07Nginx域名轉(zhuǎn)發(fā)使用場景代碼實(shí)例
這篇文章主要介紹了Nginx域名轉(zhuǎn)發(fā)使用場景代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09詳解Nginx + Tomcat 反向代理 負(fù)載均衡 集群 部署指南
Nginx是一種服務(wù)器軟件,也是一種高性能的http和反向代理服務(wù)器,本篇文章主要介紹了Nginx + Tomcat 反向代理 負(fù)載均衡 集群 部署指南,有興趣的可以了解一下。2016-12-12