Analysis and resolution of redirection problems occurred after Nginx and Tomcat integration

Source: Internet
Author: User

Analysis and resolution of redirection problems occurred after Nginx and Tomcat integration

The Tomcat front-end configuration of an HTTP server should be standard for most applications, and the basic idea is that all dynamic requests are reverse-proxied to the backend tomcat,http server to handle static requests, including images, JS, CSS, HTML, and XML. This allows your application to increase the load capacity, the front-end of the HTTP server is the most mainstream use of Apache HTTP server and Nginx. Today this article is mainly about this combination of ways, the back end of the Tomcat app in the 301 jump encountered a problem.

Problem

First to clarify the problem, the front-end Nginx occupies 81 port, because 80 dry other, temporarily lazy to stop 80 of the application, temporarily modified to 81 port. Tomcat then occupies port 8080, which is configured as follows (only a segment of the server is intercepted):

Location/App1/ {Index Index.JSP index.HTML index.HTML index.sHTML;Proxy_pass http:localhost:8080/app1/;Proxy_set_headerHost$host;Proxy_set_header X-Real-IP $remote _addr;Proxy_set_header X-Forwarded-For$proxy _add_x_forwarded_for;}Location~* ^.+\.(Png|jpg|| Gif| Ico| Css| Js| Xml $ { root /home/gap/app /apache-tomcat-5.5. 14/webapps;               /span>                

The above code is just a simple example, where the processing of static content can also be used in the directory alias or Root to deal with, the effect should be the same, but the specific difference I did not understand, but this is not the focus of today. In this configuration, the problem is that when accessing http://host:81/app1/Login.do, login success requires 301 to jump to the User Center page, and then jump to the address should be http://host:81/app1/ Userindex.do, but the result is not very satisfactory, the browser actually appears the address http://host/app1/userindex.do. The problem is that the 81 port is gone, run 80 port, nature is 404. It's a big paragraph, and that's what I want to say today.

The problem arises, naturally, because we need to support SSL in this project and use the Struts1.2 framework, so we use the Secureplugin (which you would like to know to refer to Sslext Command section 2.3) for processing. Then I first suspect is not this thing in mischief, looked under the configuration file this plugin's enable is directly false. It seems that this plugin is not a problem, then it is not the application itself logic in the mischief, then it may be the server configuration problems, this time should be directly from the HTTP request to start the analysis.

First I opened Chrome and then I analyzed what happened to the request (open the Network panel in the developer tools), and the basic thing to discover was the request Login.do is fine, but the 301 redirects that occur after login.do are wrong, and an important clue is that the value of location in response in Login.do's request is http://host/usercenter.do, and the port number is lost. The specific reasons for this place will be mentioned in the back, first of all to solve the idea.

The solution can have two, the first is Nginx can use Proxy_redirect to modify the value of response location and refresh, locations can naturally be re-modified to 81 port address, The second one is to find out who has made the mistake of location, modify this place and don't be mistaken.

Solution 1: Using Nginx's Proxy_redirect

This idea is actually a bit of a problem-solving type, that is, I see here is wrong, the reason is not tangled, I let you so that you can. Maybe a lot of people are this idea, after all, solve the problem is the primary purpose.

Many people in the configuration Nginx, used to refer to the official Wiki full Example (taken from Nginx site), to do some configuration, refer to this is certainly more than the reference Baidu search out documents to be much more reliable, It is recommended that you do not understand each attribute's available reference under this official example. This configuration inside Proxy_redirect property is off, a lot of people should not ask why directly according to others to do, the reason for this conclusion is because I see too many of the integration examples of domestic people are set in this way. I also set up here, I did not want to ask why, it does not fit my style. Anyway the server is configured like this, now is the problem, we first see what this property can do.

First look at the official document Reference:proxy_redirect Description:

Sets a text that should is 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/".

The basic meaning is to modify the proxy server (that is, the nginx at this time) the value of the response in the header of the message Location Refresh , according to this explanation we will certainly solve the problem, because now the problem is this can be modified in one Location of the two Problem, the following code will solve the problem

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

This restarts sudo nginx -s reload and then the access should be OK. In fact, your Google search nginx proxy_redirect 重定向 has a lot of such examples and this solution is the same, do not elaborate, if anyone want to know can be their own reference to the Nginx official documents and combined with examples to operate under the test can be understood.

Solution 2: Find the cause of the problem, modify the place to resolve the error

According to the last idea to solve the problem, not a sense of relief, but the feeling of each place is very empty, because there are several questions not resolved, including why is 80 and not 81 or 8080 unreasonable? This location should be nginx to rewrite, modify the jump to the wrong place is not better than this idea?

First of all, to analyze the cause of the problem: Since response's Locaiton is not right, then the first thought is the location is who constructs, understand the HTTP protocol people should know, The header in request is constructed by the client (browser, etc.) and sent to the server, and the server receives the request to construct the response information back to the client. So the location of this value must be nginx or tomcat to get out of the problem, this place nginx is just a proxy server, then response must be Tomcat sent to Nginx, That means we should start with Tomcat to analyze the problem.

First I looked at Tomcat's official document, Proxy support, which is presented here as follows:

The Proxyname and ProxyPort attributes can be used if Tomcat is run behind a proxy server. These attributes modify the values returned to Web applications this call the Request.getservername () and Request.getserve Rport () methods, which is 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 F Rom the proxy server was received, rather than the server name and port to whom the client directed the original request.

This means that the ProxyPort attribute is used for my nginx to do the front-end proxy server Tomcat in the back-end processing of the dynamic request situation. Modifying the value of an attribute can be used for the two methods applied, primarily for absolute paths and redirects. If not configured, it may be amiss. So since it is not right here, I will first put the Server.xml in my HTTP connector configuration to join proxyPort="81" , restart Tomcat, and then the Nginx on the steps to comment out the changes, restart the test. The result is basically as expected, completely normal jump.

At this point in time, the problem is basically clear, but I am still on this tomcat why the default parsing port 80 is very confused. I downloaded the tomcat source to see what the question is, after reading it in popular language to express the words is this: if the default is not configured ProxyPort default is 0, and then in the construction of response if ProxyPort is 0 then do not add the port, Without adding a port, of course, the default is 80 ports, the source code is as follows:

fixme:the code below doesnt belongs to here,This was only has a senseIn Http11, not in ajp13.At this point, the Host header has been processed.Override If the proxyport/proxyhost is setStringProxyname=Connector.Getproxyname();IntProxyPort=Connector.Getproxyport();If (ProxyPort!= 0)   { Req. Setserverportproxyport}if  ( Proxyname != null)  Span class= "pun" >{ Req. ().  Setstringproxyname               /span>                

Came here to the truth, the heart also did not knot, a stone finally landed.

Summarize

In other words, Tomcat is designed to consider this proxy server and Tomcat integration situation, the 80 port is not a problem because the port is empty, the browser will default to 80 port. If nginx this proxy server is not 80 this port should need to configure the properties of ProxyPort, so you do not encounter this problem.

So, based on this, both solutions are possible, but the way to modify the Tomcat configuration file is the one I most recommend, because this idea seems to be reasonable and easy to understand. My feeling is who the matter who to solve better, nginx as proxy server you just need to do your static file parsing, and the dynamic request direction Proxy Server on it, since Tomcat constructs this information wrong, others have provided a solution, according to your situation A reasonable configuration is possible.

has always been a particularly serious person, all kinds of things are, I hope everyone in solving the problem should not be limited to solve the problem is OK, more to understand the truth of the problem will progress faster, such as this problem has a prerequisite is to understand the basic knowledge of some HTTP protocol, If you don't understand it, you may not be able to quickly figure out what's wrong with the location, and you probably won't soon know who response is. Recommended that everyone read the "HTTP authoritative guide", each Web development engineer should have the book, you can probably read it first to understand, the follow-up needs to be taken out as reference books to access information. If as a reference book, it is strongly recommended that you buy Turing launched the "HTTP Authoritative guide" electronic version, I have sold my paper books for the electronic version, bought all agreed. But incidentally said a Turing purchase also need to enter a redemption code to send silver, this experience is not good, because always forget, anxious to buy the book will forget, suggestions to improve the next AH.

This article is for learning and communication purposes only and does not represent the Turing community perspective. Non-commercial reprint please indicate as translator, source, and keep the original link of this article. Nginx Tomcat share long Weibo 3

Related tags

Analysis and resolution of redirection problems occurred after Nginx and Tomcat integration

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.