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