使用 Nginx 部署 Java web 服務(wù)
比較早之前,部署 Java web 服務(wù)只是單純使用 Tomcat 做 Web 服務(wù)器,前后端代碼融合在一個(gè)工程之中。Tomcat 啟動(dòng)后對(duì)外提供一個(gè)端口接收和相應(yīng) http請(qǐng)求。隨著 Nginx 的越來(lái)越流行,同時(shí)加上其優(yōu)秀的反響代理和負(fù)載均衡功能,我們?cè)诰€上的 Java web 通常會(huì)結(jié)合二者,即使用 Nginx + Tomcat 的方式來(lái)部署 Java web 服務(wù)。最近兩年,隨著微服務(wù)化和前后端工程分離思想的流行,使用 Spring Boot 和 Vue 框架進(jìn)行 Java web 開發(fā)的人的人越來(lái)越多。由于前后端分離后需要解決請(qǐng)求跨域的問(wèn)題,往往會(huì)使用 Nginx 做一層反向代理,這樣可以減少一些代碼風(fēng)險(xiǎn)。所以,目前主流的 Java web開發(fā)模式是:
- 基于 Vue 等優(yōu)秀的前端框架完成頁(yè)面開發(fā);
- 使用 Spring Boot 等 java web 框完成后端服務(wù)開發(fā);
- 前端工程打包后是一堆靜態(tài)文件,可以直接由 Nginx 進(jìn)行代理訪問(wèn);后端服務(wù)啟動(dòng)后會(huì)占用端口等待請(qǐng)求,Nginx 將使用反向代理功能將前端發(fā)起的 http 請(qǐng)求轉(zhuǎn)到對(duì)應(yīng)的后臺(tái)服務(wù)去處理。如果在多臺(tái)機(jī)器上部署了相同的服務(wù),還可以使用 Nginx 中的負(fù)載均衡功能,將請(qǐng)求均勻分發(fā)到上游的服務(wù),實(shí)現(xiàn)系統(tǒng)的高可用性。
1. 部署前端
前端框架如 Vue 打包出來(lái)往往是靜態(tài)的文件 index.html 加上一個(gè) static 目錄。static 目錄下有 fonts、css、js、img等靜態(tài)資源目錄。前端的訪問(wèn)是從 index.html 開始的。假設(shè)服務(wù)器上打包出的前端代碼放到/root/test-web目錄下,對(duì)應(yīng)部署前端的配置如下:
...
http{
server {
# 監(jiān)聽8080端口
listen 8080;
# 指定域名,不指定也可以
server_name www.xxx.com;
# 瀏覽器交互調(diào)參,打開gzip壓縮、緩存等等
gzip on;
...
location / {
root /root/test-web;
# 也可以簡(jiǎn)單使用 index index.html
try_files $uri $uri/ /index.html;
}
# vue 頁(yè)面中向后臺(tái) java 服務(wù)發(fā)送請(qǐng)求
...
}
}
...
2. 部署java后臺(tái)服務(wù)
Nginx 部署 Java Web 服務(wù)時(shí),主要用到是 Nginx 的代理轉(zhuǎn)發(fā)功能,對(duì)于不同類型的接口而言,可能會(huì)有不同的轉(zhuǎn)發(fā)邏輯。如果是使用 spring cloud 這樣的微服務(wù)框架,每個(gè)服務(wù)可能會(huì)部署多個(gè)會(huì)這分開部署在不同機(jī)器,在 Nginx 同樣只需要使用 proxy_pass 指令將 http 請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的上游服務(wù)上即可,同時(shí)負(fù)載均衡模塊也在 java web 后臺(tái)服務(wù)中用到的比較多。最后是在java web 的開發(fā)中,也常常會(huì)涉及到 websocket 協(xié)議,因此 Nginx 在部署 java web 服務(wù)時(shí)也會(huì)用到 websocket 代理轉(zhuǎn)發(fā)。所以 Nginx 在部署 Java Web 服務(wù)時(shí)的基本配置大概如下:
...
http{
server {
# 監(jiān)聽8080端口
listen 8080;
# 指定域名,不指定也可以
server_name www.xxx.com;
# 參數(shù)調(diào)優(yōu)
client_max_body_size 20m;
client_body_buffer_size 128k
...
# 如果使用多個(gè)后臺(tái)服務(wù),可以配置負(fù)載均衡
...
# 訪前端的 vue 頁(yè)面
location / {
...
}
# vue 頁(yè)面中向后臺(tái) java 服務(wù)發(fā)送請(qǐng)求
location /xxxx {
proxy_pass http://xxxx:xx/xxx;
}
# 配置多種方向代理,不同類型接口有不同的轉(zhuǎn)發(fā)方式
...
# 如果有,則配置websocket代理
location /xxxy {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://xxxxx:xx/yyy;
}
}
}
...
如果涉及的服務(wù)較多, Nginx 的配置往往會(huì)拆成多個(gè)文件進(jìn)行編寫,這樣就用到了前面提到的 include 指令。
3. 小結(jié)
總結(jié) Nginx 部署 java 服務(wù),主要是使用 proxy_pass 指令進(jìn)行端口轉(zhuǎn)發(fā),因?yàn)槎际?http 請(qǐng)求的轉(zhuǎn)發(fā),所以配置會(huì)比較簡(jiǎn)單。但是如果服務(wù)較多時(shí), Nginx 需要編寫多個(gè) server 指令塊或者多個(gè) location 塊去匹配不同的 URL并轉(zhuǎn)發(fā)到對(duì)應(yīng)的上游服務(wù)。往往大型網(wǎng)站使用的服務(wù)較多時(shí),會(huì)使用 include 指令對(duì) Nginx 的配置進(jìn)行拆分,不同的配置處理不同服務(wù)的轉(zhuǎn)發(fā),這樣會(huì)更簡(jiǎn)潔明了,方便網(wǎng)站運(yùn)維人員管理和修改 Nginx 配置。