Spring Boot + Java爬蟲 + 部署到Linux(八、Nginx實現反向代理、動靜分離和websocket處理)
Nginx (engine x) 是一個高效能的HTTP和反向代理伺服器,也是一個IMAP/POP3/SMTP伺服器。所以,我們就用Nginx來實現反向代理和動靜分離的功能。
反向代理,通過搜尋、百科也可以大概知道。不過因為同為代理,所以總是和正向的代理區分不了。我的理解就是一個是對伺服器的,一個是對客戶端的。正向代理和反向代理都是客戶將請求發向代理伺服器,然後代理伺服器再將請求傳送給目標伺服器,同時獲得響應內容,再返回給客戶。正向的就是客戶端配置的,反向就是伺服器配的,對使用者透明的。
首先下載Nginx,很小的輕量應用。下載完畢之後,可以先試一下。直接開啟nginx.exe,然後一個視窗一閃而過,開啟工作管理員可以看到有nginx的程序。然後瀏覽器開啟localhost,就可以看到一個index介面了。這個就是安裝目錄下面的html/index.html。如果發現視窗(預設是80)被佔用,可以使用命令列netstat -ano |findstr ":port"來查。如果是一些特殊程序佔了,百度解決方法。如果是一般程序佔了,可以直接殺掉就行了。
開啟安裝目錄下面的conf目錄下面的nginx.conf。反向代理實現非常簡單,在檔案的 location / (代表所有的請求),把自帶的兩行去掉,加上一行“proxy_pass http://127.0.0.1:8080; ”其中http://127.0.0.1:8080就是spring boot專案的伺服器的地址。然後把spring boot啟動了,再直接訪問127.0.0.1或者localhost就可以看到效果了。
實現動靜分離也很簡單,動靜分離就是靜態內容就由nginx直接返回。動態的內容,才用代理。我們可以在location /{}的下面加上
location ~\.(js|css|png|html)$ { root D:/eCrawler/src/main/resources/static; #實際路徑為root+url }
首先~是區分大小寫的正則匹配,\是對 . 進行轉義,和後面小括號裡的組成字尾名。$表示結束位置。這個location的意思就是碰到以.js,.css,.png,.html結束的訪問都從root 下面去返回。root的內容,就是我們這些資源的根路徑,可以像這樣用絕對路徑,也可以用相對路徑(比如../)。如果是spring boot並且將靜態資源放到/src/main/resources/static位置的話,一般這樣就行了。那個註釋的意思就是,假如我們訪問的是localhost/js/jquery.js,那麼nginx會去找配置的root/js/jquery.js這個檔案,然後返回。
然後至於為啥訪問這些資源不直接用上面的location /通配的,這是因為當多個匹配都滿足時通配的優先順序最低。遵循的原則就是越精確,越匹配。同樣精確,匹配到第一個就結束了。具體的可以參考
當這些都配完之後,發現websocket用不了,建立不了連線。然後去nginx官網看了一下解決方法。就直接貼上過來了。
http {
include mime.types;
default_type application/octet-stream;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#root html;
#index index.html index.htm;
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
}
location ~\.(js|css|png|html)$ {
root G:/eCrawler/src/main/resources/static;
#實際路徑為root+url
}........................................................
其中proxy_read_timeout是超時時間,如果不設定,預設是一分鐘好像。就是保持連線這麼長的時間,雙方都沒有傳送訊息,就斷開連線。原來的我嫌慢,就設了一個小時。如果一個小時沒動靜,就強制斷開連線。同時spring boot那邊也會報相應的異常。
配置好檔案之後,在命令列下執行nginx -s reload就會重新載入配置檔案了。執行nginx -s stop 就結束了。其中-s是signal的意思。可以用nginx -h檢視更多命令。
這時候,保持著nginx和spring boot都開啟著,直接訪問localhost,就可以看到效果了。如果樣式沒有,說明靜態檔案配錯了,如果websocket沒反應,則是相關配置缺少。
Nginx還有很多強大的功能,比如負載均衡啊之類的,但在這用不到。可以搜尋嘗試。