使用Nginx負載均衡單頁應用,解決刷新404異常

接前篇:Nginx+Tomcat實現Web服務器的負載均衡
採用Nginx的反向代理搭建了一個負載均衡的web服務器,然後部署了一套自己的web應用,在使用中呢,還是發現了一些問題:
自己的應用採用前後的端分離開發,後端用java編寫,前端使用VUE開發,而搭建的負載均衡,實際上是對前端的負載均衡,後臺java還是一個單獨的服務器運行的,這裏只看vue的前端

項目正常訪問地址 http://10.50.200.66:11180 完全沒有問題,正常登錄,正常使用
比如,正常登錄首頁,展示:
應用登錄首頁
但是如果,對應用瀏覽器刷新(F5)的時候,就會發現有問題了,瀏覽器提示404異常:
vue刷新異常
其實這問題主要在於VUE,當vue項目的vue-router的mode爲history路由模式時,若服務器未進行相應的配置,就會發生這種情況。

前端路由,即由前端來維護一個路由規則。實現有兩種,一種時利用url的hash,也就是常說的錨點(#),JS通過hashChange事件來監聽url的改變,IE7及以下需要輪詢;另一種是HTML5的History模式,它使url看起來像普通網站那樣,以“/”分割,沒有#,但頁面並沒有跳轉,不過使用這種模式需要服務端的支持,服務端在接受到所有請求後,都指向index.html文件,或設置404頁面爲index.html。不然刷新時頁面會出現404。1

那怎麼解決呢?

其實也比較簡單,一種是不要使用history模式,但是不推薦這樣做!另一種,就是把自己的vue項目copy一份放到nginx服務器的應用目錄下,配置nginx,在訪問不到其他地址,如上圖 /nfs-qd/main/home這樣的地址的時候,強制映射到vue單頁應用項目的index.html即可。
具體如下,修改nginx配置

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        # 將訪問請求轉向至服務器集羣,mycluster和http中upstream mycluster 對應
        proxy_pass http://mycluster;
        # nginx服務器本身的應用服務路徑,把自己的vue應用copy一份到這個路徑下
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        # URL 匹配不到任何靜態資源,就強映射到本地應用的index.html,這樣就解決了頁面刷新404問題
        try_files $uri $uri/ /index.html;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

這樣配置還有一個好處

nginx服務器本身也能提供資源服務了,前篇簡單nginx反向代理的時候,客戶端並不知道nginx服務器資源是否其本身提供還是nginx服務器請求其他服務器提供的,這裏nginx服務器仍然是反向代理,同時它也提供web資源;
另外nginx在沒有配置本身的服務功能時候,vue項目的favicon.ico圖標在客戶端訪問nginx服務器是訪問不到的,但是當配置nginx提供服務時候,這個問題也解決了。

另外還有一個要說的

上面是使用tomcat作爲web容器對外提供服務,實際上沒有必要,對應vue這樣的單頁應用沒必要使用tomcat,使用前面說的apache http server就行,這個要比tomcat輕量,當然更好的還是使用nginx就行,它本身也能發佈靜態頁應用,方法正如本文介紹的,在目錄 /usr/shar/nginx/html下放入自己的vue單頁應用即可,這樣更好了!
之所以用tomcat,是爲了將來的java後臺服務提供web容器環境。

還有什麼要說的?

有沒有發現nginx做反向代理和負載均衡很簡單?真的是這樣嗎?
前面有說到,上面演示的都是對vue前端做的負載均衡,這樣真的有用嗎?真正的壓力是在前端嗎?
好像不是,壓力是在後臺呀,java部分,後臺只有那麼一臺服務器,所有前端的響應都是來自一臺後臺,真正要做的是對java後臺負載均衡纔對!
那麼爲什麼不對java後臺負載均衡呢?

那是後端不跟前臺一樣,有一個問題不解決,就無法負載均衡,那就是用戶session的共享問題-- 一個用戶在服務器A上登錄後,經過負載均衡後,後面的請求可就不能還在服務器A上了,到了服務器B上,如何知道當前用戶已經登錄了,還是沒登錄呢?

關注博主,後續博文吧!



  1. 《Vue.js實戰》 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章