过程:

浏览器------》代理--------》真实应用服务器

浏览器发送请求给代理,代理发送请求给应用服务器,代理将应用服务器返回的内容返回给浏览器。


情景再现:

在有代理的情况下,request.getServerName(),并不能得到真正代理服务器的地址,如果nginx没有配置 proxy_set_header Host $Host,那么得到的地址是127:0.0.1,为什么呢?


原因分析:

通过查看Tomcat的源码得知,request首先会判断http heder中的host,如果没有,那么就获取本机的ip地址,因为代理服务器没在发送给真实服务器的header中,没有配置host,所以得到的是127.0.0.1,而如果将代理发送给应用服务器请求header中把host配置成代理服务器自身的ip地址,就可以得到代理服务器的ip地址。


源码分析的具体过程:

因为项目使用的是maven,所以查看源码比较方便

ServletRequest-----HttpServletRequestImpl------HttpServerExchange

以下是servlet3.0的源码:

 /** 
     * Return the host that this request was sent to, in general this will be the 
     * value of the Host header, minus the port specifier. 
     * <p/> 
     * If this resolves to an IPv6 address it will not be enclosed by square brackets. 
     * Care must be taken when constructing URLs based on this method to ensure IPv6 URLs 
     * are handled correctly. 
     * 
     * @return The host part of the destination address 
     */ 
    public String getHostName() { 
        String host = requestHeaders.getFirst(Headers.HOST); 
        if (host == null) { 
            host = getDestinationAddress().getAddress().getHostAddress(); 
        } else { 
            if (host.startsWith("[")) { 
                host = host.substring(1, host.indexOf(']')); 
            } else if (host.indexOf(':') != -1) { 
                host = host.substring(0, host.indexOf(':')); 
            } 
        } 
        return host; 
    }

解决方案

nginx中配置proxy_set_header Host $Host


发布评论
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

tomcat nginx 负载均衡详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。