久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

nginx和Tomcat集成后發(fā)生的重定向問(wèn)題分析和解決

 hh3755 2013-08-09

Tomcat前端配置一個(gè)HTTP服務(wù)器應(yīng)該是大部分應(yīng)用的標(biāo)配了,,基本思路就是所有動(dòng)態(tài)請(qǐng)求都反向代理給后端的Tomcat,HTTP服務(wù)器來(lái)處理靜態(tài)請(qǐng)求,,包括圖片,、js、css,、html以及xml等,。這樣可以讓你的應(yīng)用的負(fù)載能力提高很多,前端這個(gè)HTTP服務(wù)器主流用的最多的當(dāng)屬Apache HTTP Server和nginx,。今天這篇文章主要講解的是這種組合的方式的前提下,,后端的Tomcat中的app在301跳轉(zhuǎn)的時(shí)候遇到的一個(gè)問(wèn)題。

問(wèn)題

先把問(wèn)題說(shuō)清楚,,前端nginx占用81端口,,因?yàn)?0干了別的,暫時(shí)懶得停80的應(yīng)用,,暫時(shí)修改為81端口而已,。然后Tomcat占用8080端口,具體配置如下(只是截取了server中的一段):

location /app1/ {
    index index.jsp index.html index.html index.shtml;
    proxy_pass http://localhost:8080/app1/;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
}

location ~* ^. \.(png|jpg|jpeg|gif|ico|css|js|xml)$ {
    root /home/gap/app/apache-tomcat-5.5.14/webapps;
}

上面的代碼只是簡(jiǎn)單舉例,,其中處理靜態(tài)內(nèi)容的部分也可以用目錄alias或者root的方式去處理,,效果應(yīng)該一樣的,但是具體區(qū)別我也沒(méi)深入了解,,不過(guò)這不是今天的重點(diǎn),。在這個(gè)配置下出現(xiàn)的問(wèn)題就是當(dāng)訪問(wèn)http://host:81/app1/Login.do的時(shí)候,登錄成功需要301跳轉(zhuǎn)到用戶(hù)中心頁(yè)面,,然后跳轉(zhuǎn)的地址本應(yīng)該是http://host:81/app1/userindex.do,,但是結(jié)果不太盡如人意,瀏覽器實(shí)際出現(xiàn)的地址http://host/app1/userindex.do,。這里面的問(wèn)題就是81端口沒(méi)了,,跑80端口去了,自然就404了。扯了一大段,,這就是今天想說(shuō)的問(wèn)題,。

問(wèn)題出現(xiàn)了,自然得分析原因,,由于我們這個(gè)項(xiàng)目中需要支持ssl,,使用了Struts1.2的Framework,于是采用了SecurePlugIn(想了解的可以參照SSLExt Command 2.3節(jié))的插件來(lái)處理,。那么我首先懷疑是不是這個(gè)東西在作怪,,看了下配置文件這個(gè)插件的enable都直接為false??磥?lái)不是這個(gè)插件作怪了,,那么在不是應(yīng)用本身邏輯在作怪的話那么可能是服務(wù)器配置有問(wèn)題了,這個(gè)時(shí)候就應(yīng)該直接從http請(qǐng)求開(kāi)始分析了,。

首先我打開(kāi)chrome,,然后來(lái)分析這次request發(fā)生了什么(打開(kāi)開(kāi)發(fā)者工具中的Network面板),能發(fā)現(xiàn)的基本就是請(qǐng)求Login.do是沒(méi)問(wèn)題的,,但是Login.do之后發(fā)生的301重定向是錯(cuò)誤的,,一個(gè)重要的線索就是Login.do的請(qǐng)求中response中的Location的值是http://host/usercenter.do,這里丟掉了端口號(hào),。這個(gè)地方的具體原因后邊會(huì)提到,,先說(shuō)下解決思路。

解決思路可以有兩個(gè),,第一個(gè)就是nginx是可以利用proxy_redirect來(lái)修改response的Location和Refresh的值,,Location自然可以被重新修改為81端口的地址,第二個(gè)就是找到是誰(shuí)把Location搞錯(cuò)了,,修改這個(gè)地方別搞錯(cuò)Location就行了,。

解決思路1:利用nginx的proxy_redirect

這個(gè)思路其實(shí)有點(diǎn)偏重解決問(wèn)題型,就是我看到這里錯(cuò)了,,原因不糾結(jié),,我讓你好使就可以了??赡芎枚嗳硕际沁@個(gè)思路,,畢竟解決問(wèn)題是首要目的。

很多人在配置nginx的時(shí)候,,習(xí)慣參考官方wiki的Full Example (taken from Nginx site),,來(lái)做一些配置,參考這個(gè)肯定比參考baidu搜索出來(lái)的文檔要靠譜很多,,建議不了解每個(gè)屬性的可以來(lái)參照下這個(gè)官方示例,。這個(gè)配置里面proxy_redirect的屬性為off,很多人應(yīng)該沒(méi)有問(wèn)過(guò)為什么就直接根據(jù)人家來(lái)做了,之所以這樣下結(jié)論是因?yàn)槲铱吹教鄧?guó)內(nèi)人的集成例子中都是這樣設(shè)置的了,。我這里也是這樣設(shè)置的,,以前也倒是沒(méi)想起來(lái)問(wèn)下為啥,的確不太符合我的風(fēng)格,。反正服務(wù)器是這樣配置的,,現(xiàn)在是出來(lái)問(wèn)題了,我們先來(lái)看下這個(gè)屬性能做什么,。

首先看官方文檔Reference:proxy_redirect的說(shuō)明:

Sets a text that should be changed in the header fields “Location” and “Refresh” of a response from the proxied server. Suppose a proxied server returned the header field “Location: http://localhost:8000/two/some/uri/”.

基本意思就是修改代理服務(wù)器(也就是此時(shí)的nginx)的response的頭信息里面的LocationRefresh的值,,按照這個(gè)解釋的話我們的問(wèn)題肯定就迎刃而解了,因?yàn)楝F(xiàn)在遇到的問(wèn)題就是這個(gè)能夠修改的兩個(gè)中的一個(gè)Location出了問(wèn)題,,那么下面的代碼就可以解決問(wèn)題

proxy_redirect     http://host http://host:81;

這樣重啟sudo nginx -s reload然后再訪問(wèn)應(yīng)該就ok了,。其實(shí)你google搜索nginx proxy_redirect 重定向有好多這樣的例子和這個(gè)解決方式是一樣的,就不細(xì)說(shuō)了,,如果有人想了解的可以自己參照nginx官方文檔和結(jié)合例子來(lái)操作下試試就可以理解了,。

解決思路2:找到問(wèn)題原因,修改出錯(cuò)的地方解決

根據(jù)上個(gè)思路解決了問(wèn)題以后,,一點(diǎn)都沒(méi)如釋重負(fù)的感覺(jué),,反而各個(gè)地方都覺(jué)得很空的感覺(jué),因?yàn)橛泻脦讉€(gè)疑問(wèn)沒(méi)解決,,其中包括為啥是80而不是81或者8080沒(méi)道理,?這個(gè)Location是不是應(yīng)該nginx來(lái)重寫(xiě),修改掉那個(gè)跳轉(zhuǎn)錯(cuò)的地方是不是比這個(gè)思路會(huì)更好,?

那就先來(lái)分析下問(wèn)題的原因:既然response的Locaiton不對(duì),,那么首先想到的就是這個(gè)Location是誰(shuí)構(gòu)造出來(lái)的,了解HTTP協(xié)議的人應(yīng)該都知道,,request中的header都是client(瀏覽器等)構(gòu)造好發(fā)送給服務(wù)器的,,服務(wù)器收到請(qǐng)求以后構(gòu)造response信息返回給client。那么這樣Location這個(gè)值肯定就是nginx或者Tomcat給搞出的問(wèn)題了,,這個(gè)地方nginx只是一個(gè)proxy server,,那么response肯定是Tomcat發(fā)給nginx的,也就是說(shuō)我們應(yīng)該從Tomcat下手來(lái)分析這個(gè)問(wèn)題,。

首先我就看了下Tomcat的官方文檔 Proxy Support,,這里面對(duì)這個(gè)介紹如下:

The proxyName and proxyPort attributes can be used when Tomcat is run behind a proxy server. These attributes modify the values returned to web applications that call the request.getServerName() and request.getServerPort() methods, which are often used to construct absolute URLs for redirects. Without configuring these attributes, the values returned would reflect the server name and port on which the connection from the proxy server was received, rather than the server name and port to whom the client directed the original request.

意思就是proxyPort的屬性就是用來(lái)我這種nginx做前端代理服務(wù)器Tomcat在后端處理動(dòng)態(tài)請(qǐng)求的情況的。修改屬性的值可以作用于應(yīng)用的兩個(gè)方法,,主要用于絕對(duì)路徑和重定向之用,。如果不配置的話,可能會(huì)不對(duì)頭,。那么既然是這里不對(duì)頭,,我就先把server.xml中我這個(gè)http的connector的配置加入了proxyPort="81",重啟Tomcat,然后把nginx上步驟的修改注釋掉,重啟測(cè)試,。結(jié)果基本如所料,,完全正常跳轉(zhuǎn)了。

事情到了這個(gè)時(shí)候,,其實(shí)問(wèn)題基本明了了,,不過(guò)我還是對(duì)這個(gè)Tomcat為啥默認(rèn)解析了80端口很是疑惑。我下載了Tomcat的source來(lái)看下問(wèn)題究竟,,看了以后用通俗的語(yǔ)言來(lái)表述的話就是這樣:如果默認(rèn)不配置proxyPort默認(rèn)為0,,然后在構(gòu)造response的時(shí)候判斷如果proxyPort為0那么就不添加端口,不添加端口當(dāng)然就默認(rèn)走了80端口,,源代碼如下:

// FIXME: the code below doesnt belongs to here, 
// this is only have sense 
// in Http11, not in ajp13..
// At this point the Host header has been processed.
// Override if the proxyPort/proxyHost are set 
String proxyName = connector.getProxyName();
int proxyPort = connector.getProxyPort();
if (proxyPort != 0) {
    req.setServerPort(proxyPort);
}
if (proxyName != null) {
    req.serverName().setString(proxyName);
}

到了這里就真相大白了,心里也沒(méi)結(jié)了,,一塊石頭終于落地了,。

總結(jié)

也就是說(shuō)Tomcat在設(shè)計(jì)的時(shí)候是對(duì)這種代理服務(wù)器和Tomcat集成的情況做了考慮,80端口之所以沒(méi)問(wèn)題是因?yàn)閜ort為空,,瀏覽器會(huì)默認(rèn)走80端口,,如果nginx這代理服務(wù)器不是80這個(gè)端口應(yīng)該需要配置proxyPort的屬性的,這樣就不會(huì)遇到這個(gè)問(wèn)題,。

那么基于這個(gè)來(lái)總結(jié)的話,,兩種解決方式都可以,不過(guò)修改Tomcat配置文件的方式是我最推薦的,,因?yàn)檫@個(gè)思路看起來(lái)是又合理,、又易于理解。我的感覺(jué)就是誰(shuí)的事情誰(shuí)來(lái)解決比較好,,nginx作為proxy server 你就只需要做你的靜態(tài)文件的解析,,和把動(dòng)態(tài)請(qǐng)求方向代理的服務(wù)器就可以了,既然Tomcat把這個(gè)信息構(gòu)造錯(cuò)了,,人家也有提供了解決方案,,就根據(jù)你的情況合理配置就可以了。

一直以來(lái)自己是個(gè)特別較真的人,,各種事情都是,,希望每個(gè)人在解決問(wèn)題的時(shí)候不要僅限于解決了問(wèn)題就ok吧,更多的去了解問(wèn)題的真相才會(huì)進(jìn)步更快,,例如這個(gè)問(wèn)題其實(shí)有一個(gè)必要前提是需要了解一些HTTP的協(xié)議的基礎(chǔ)知識(shí),,如果不了解的話可能你不會(huì)很快判斷出Location出了問(wèn)題,你可能也不會(huì)很快知道response是誰(shuí)構(gòu)造錯(cuò)的,。建議大家都讀下《HTTP權(quán)威指南》,,每個(gè)做web開(kāi)發(fā)的工程師都應(yīng)該擁有這本書(shū),可以大概先看一遍了解,后續(xù)需要就拿出來(lái)作為工具書(shū)查閱資料,。如果作為工具書(shū)的話,,那就強(qiáng)烈推薦大家購(gòu)買(mǎi)圖靈推出的《HTTP權(quán)威指南》電子版,我都把我的紙質(zhì)書(shū)賣(mài)了換了電子版了,,買(mǎi)了都說(shuō)好啊,。不過(guò)順帶說(shuō)句圖靈購(gòu)買(mǎi)也需要輸入個(gè)兌換碼才能送銀子,這體驗(yàn)不好,,因?yàn)榭偸峭?,著急買(mǎi)書(shū)的都會(huì)忘記,建議改進(jìn)下啊,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多