Nginx+Geoserver部署所遇問題總結


文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/

1.背景

    該問題的最終解決離不開公司大拿whs先生的指點,先表示感謝。

    某項目的geoserver發布在一台linux上,端口為8082。使用Nginx對該geoserver服務(包括其他服務)做了一個轉發代理,Nginx監聽的端口是8081。由於8082端口沒有對外開放,所以用戶只能訪問該8081端口進行訪問。

    由於系統與Geoserver的對接是直接基於OGC服務對接,所以一切正常,但是,用戶依然發現對於Geoserver服務網站的訪問卻存在兩個問題:

    a.通過8081代理端口訪問Geoserver網站,圖層無法直接預覽。

 

    b.通過8081代理端口訪問Geoserver時,如果不加上斜杠(/),則會報空指針異常錯誤。

   

2.問題一:Geoserver服務無法預覽問題

2.1問題排查過程

       點擊預覽時錄制腳本:

     

       可見本應是8081端口請求變成了默認的80端口,導致樣式等文件無法加載,從而出現預覽為空。跟蹤源碼,發現URL的獲取方式為:

 

       再查看目前Nginx的配置為:

 

       可見,此處獲取到的URL僅為瀏覽器輸入地址的IP,而沒有端口號,所以出現了腳本中默認80端口的問題。加上端口配置,重啟Nginx服務,解決。

       配置修改為:

 

       重啟Nginx操作:

 

2.2關於proxy_set_header參數的理解

       其語法規則為:

       語法:proxy_set_header field value;默認值:

       proxy_set_header Host $proxy_host;

       proxy_set_header Connection close;

       上下文:http, server, location

       其作用為:

       允許重新定義或者添加發往后端服務器的請求頭。value可以包含文本、變量或者它們的組合。 當且僅當當前配置級別中沒有定義proxy_set_header指令時,會從上面的級別繼承配置。

       對上面問題出現我們可以這樣理解:當使用了nginx反向服務器后,在web端使用request.getRemoteAddr()(本質上就是獲取$remote_addr),取得的是nginx的地址,即$remote_addr變量中封裝的是nginx的地址,當然是沒法獲得用戶的真實ip的。

 

3.問題二:瀏覽器輸入首頁訪問地址不帶斜杠報錯問題(http://ip:8081/geoserver報錯)

3.1.一個奇怪的現象

       首先,我在本地單獨發布了一個Geoserver測試該問題,發現即使我輸入不帶斜杠,訪問時瀏覽器也會為我自動加上斜杠訪問。而服務器上的Geoserver則不會。

       最開始懷疑為瀏覽器自身補全功能,但是這又無法解釋訪問雲上地址時不補全現象。最后通過查資料確定為如下情況導致:

       以訪問http://ip:8081/geoserver為例子,在windows 系統上,一般如果服務器識別根目錄有文件夾為geoserver(沒有文件名為geoserver) 時,他們會自動給目錄加斜杠。但是,如果是linux 系統則不會,linux 系統會把它作為文件處理(不會以目錄形式處理),直接就打開geoserver文件,所以不會加上斜杠。

       因為服務器為linux系統,所以不會自動加上斜杠。

3.2從報錯信息排查起

3.2.1正常情況下,帶/時跳轉的原理

       Geoserver的web.xml中有如下配置:

    <welcome-file-list>

        <welcome-file>/index.html</welcome-file>

    </welcome-file-list>

       所以帶上/時,會自動跳轉至index.html頁面,而

       index.html中有:

 

       於是請求再度調轉為:http://192.168.**.**:8081/geoserver/web/,進入Geoserver首頁。

3.2.2沒有按照套路走,報錯發生的原因在哪里

       我們再看web.xml中的配置:

 

      

  此時因為匹配規則是/*,所以所有請求要先經過過濾器之后,才會走到歡迎頁面設置,查看源碼發現:

   

 

3.3解決方法

       經過認真思考,有兩種解決方案:

       一種是對Nginx配置進行針對性優化;

       一種方案是對Geoserver升級。

       以下分段進行分別描述。

4.針對問題二:Nginx配置優化

4.1需求描述

       整理需求為:我們需要實現在直接訪問Geoserver(不帶/)時轉發自動加上/。但是針對Geoserver/(帶上/)時轉發不再自動加上/(//現象會導致訪問404問題)。

       查找資料,Nginx的rewrite機制可以非常好的解決該需求:

       和apache等web服務軟件一樣,Nginx的rewrite的組要功能是實現RUL地址的重定向。Nginx的rewrite功能需要PCRE軟件的支持,即通過perl兼容正則表達式語句進行規則匹配的。默認參數編譯nginx就會支持rewrite的模塊,但是也必須要PCRE的支持。rewrite是實現URL重寫的關鍵指令,根據regex(正則表達式)部分內容,重定向到replacement,結尾是flag標記。

4.2Nginx相關配置總結

4.2.1語法規則

       其語法規則為:

       rewrite    <regex>    <replacement>    [flag];

        關鍵字      正則       替代內容       flag標記

 

       關鍵字:其中關鍵字error_log不能改變

       正則:perl兼容正則表達式語句進行規則匹配

       替代內容:將正則匹配的內容替換成replacement

       flag標記:rewrite支持的flag標記

       flag標記說明:

       last  #本條規則匹配完成后,繼續向下匹配新的location URI規則

       break  #本條規則匹配完成即終止,不再匹配后面的任何規則

       redirect  #返回302臨時重定向,瀏覽器地址會顯示跳轉后的URL地址

       permanent  #返回301永久重定向,瀏覽器地址欄會顯示跳轉后的URL地址

4.2.2執行順序

       a.執行server塊的rewrite指令(這里的塊指的是server關鍵字后{}包圍的區域,其它xx塊類似)
       b.執行location匹配
       c.執行選定的location中的rewrite指令
       如果其中某步URI被重寫,則重新循環執行1-3,直到找到真實存在的文件

如果循環超過10次,則返回500 Internal Server Error錯誤

4.2.3正則表達式規則

       . : 匹配除換行符以外的任意字符

       ? : 重復0次或1次

       + : 重復1次或更多次

       * : 重復0次或更多次

       \d :匹配數字

       ^ : 匹配字符串的開始

       $ : 匹配字符串的介紹

       {n} : 重復n次

       {n,} : 重復n次或更多次

       [c] : 匹配單個字符c

       [a-z] : 匹配a-z小寫字母的任意一個

       小括號()之間匹配的內容,可以在后面通過$1來引用,$2表示的是前面第二個()里的內容。正則里面容易讓人困惑的是\轉義特殊字符。

4.2.4常用變量

       $args : #這個變量等於請求行中的參數,同$query_string

       $content_length : 請求頭中的Content-length字段。

       $content_type : 請求頭中的Content-Type字段。

       $document_root : 當前請求在root指令中指定的值。

       $host : 請求主機頭字段,否則為服務器名稱。

       $http_user_agent : 客戶端agent信息

       $http_cookie : 客戶端cookie信息

       $limit_rate : 這個變量可以限制連接速率。

       $request_method : 客戶端請求的動作,通常為GET或POST。

       $remote_addr : 客戶端的IP地址。

       $remote_port : 客戶端的端口。

       $remote_user : 已經經過Auth Basic Module驗證的用戶名。

       $request_filename : 當前請求的文件路徑,由root或alias指令與URI請求生成。

       $scheme : HTTP方法(如http,https)。

       $server_protocol : 請求使用的協議,通常是HTTP/1.0或HTTP/1.1。

       $server_addr : 服務器地址,在完成一次系統調用后可以確定這個值。

       $server_name : 服務器名稱。

       $server_port : 請求到達服務器的端口號。

       $request_uri : 包含請求參數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。

       $uri : 不帶請求參數的當前URI,$uri不包含主機名,如”/foo/bar.html”。

       $document_uri : 與$uri相同。

4.2.5動態變量參數

       $1-$9存放着正則表達式中最近的9個正則表達式的匹配結果,這些結果按照子匹配的出現順序依次排列。
       $1 代表的是匹配的第一個結果。
       括號表示的是表達式定義的“組”(group),並且將匹配這個表達式的字符保存到一個臨時區域(一個正則表達式中最多可以保存9個) 上面的表達式有2個匹配組 (\w+)  和 (.*) 所有后面可以用 $1 和 $2 來用
       比如例子^/(\w+)/(.*)$ /$1/index.php last;
       對應為:/abc123/bcdfda  =>   /abc123/index.php

4.3解決該問題的最終配置

 

5.針對問題二:Geoserver升級

       進入Geoserver下載官網進行學習:http://geoserver.org/download/

 

  由於公司標准運行環境為jdk1.7.x,所以主要對Geoserver2.8.x和Geoserver2.9.x進行了對比研究,總結如下:

5.1.運行環境

       a.   2.9.x系列雖然描述為compatible with Java 8,個人理解為jdk7和jdk8應該都可以運行。 但是,分別在jdk1.7._067和雲上的1.7._079上測試過,不可運行:

 

       b.在2.8.X系列上進行了相關測試,均可以支持jdk1.7.x系列。

5.2.geoserver2.8.5版本的優點

 

 

       總結優化即是:強化了三維服務支持、集成了更多(最新)的插件、針對某些特殊情況下的數據發布(如局域網共享文件安全機制)導致的閃退等問題進行了修復。

       公司主要用到的基於本地矢量數據或者PG數據的WMS、WFS服務沒有特殊說明的優化和改動。

       但是geoserver的代碼架構還是做了不少變化。

       同時,針對不帶斜杠訪問報錯問題,2.8.5上也做了優化:

 

5.3.基於業務的測試

       a.基於公司雲上一鍵安裝環境進行測試,目前部件展示、I查詢、網格查詢正常:

     

       b基於PG測試,也是正常。

 

5.4.但是,有一個小缺點

       整個2.8.x系列,在版本chrome 63.0.3239.132上,geoserver平台在某些彈出框上會出現內容為空。但是IE(9以上)沒有這個問題。考慮到這類手動操作不常見,不影響工程同事使用。

 

6.學習上的一點感慨

       如WHS先生所說,技巧可以規避問題,知其所以然才可以解決問題。

 

                      -----歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/

                                                                         如果您覺得本文確實幫助了您,可以微信掃一掃,進行小額的打賞和鼓勵,謝謝 ^_^

                                    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM