1. 程式人生 > >Spring Boot + Java爬蟲 + 部署到Linux(八、Nginx實現反向代理、動靜分離和websocket處理)

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 /通配的,這是因為當多個匹配都滿足時通配的優先順序最低。遵循的原則就是越精確,越匹配。同樣精確,匹配到第一個就結束了。具體的可以參考

nginx匹配規則

當這些都配完之後,發現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還有很多強大的功能,比如負載均衡啊之類的,但在這用不到。可以搜尋嘗試。