搭建nginx+tomcat实现动静态分离或负载均衡后,动态页面是通过nginx转发的,默认情况下tomcat日志取的ip是nginx服务器的ip,如果是在同一服务器下,就会取到127.0.0.1,而不是客户端访问IP,那么如何在tomcat中取到真实的访问IP呢?
首先,在nginx的配置文件nginx.conf中的对应动态页面的location中加
proxy_set_header X-Real-IP $remote_addr;
如下所示:
if ( $host = 'huadaninfo.com' ) {
   rewrite ^/(.*)$ https://www.huadaninfo.com/$1 permanent;
}
       location ~* \.(jsp|do|action)$
{
   # 真实的客户端IP
   proxy_set_header   X-Real-IP        $remote_addr;
   proxy_pass https://website;
   expires -1;
}
然后在tomcat server.xml中的<Host>段中的日志模式改成:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
              prefix="localhost_access_log" suffix=".txt"
              pattern="%{X-REAL-IP}i %u %t %r %s %b %D %{User-Agent}i %T" resolveHosts="false" />
其中%{X-Real-IP}要与nginx中的配置对应。
resolveHosts为true的话,tomcat会将IP地址通过DNS转换为主机名,如果是false,就直接写IP地址。
形如:
     <!--https://www.huadaninfo.com发布目录-->
     <Host name="localhost"  appBase="/usr/local/webapps"
           unpackWARs="true" autoDeploy="true">
       <!-- SingleSignOn valve, share authentication between web applications
            Documentation at: /docs/config/valve.html -->
       <!--
       <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
       -->
       <!-- Access log processes all example.
            Documentation at: /docs/config/valve.html
            Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
              prefix="localhost_access_log" suffix=".txt"
              pattern="%{X-REAL-IP}i %u %t %r %s %b %D %{User-Agent}i %T" resolveHosts="false"/>
     </Host>
这样后台日志就可以记录到真实的IP了。
注意:pattern="%{X-REAL-IP}i这里不能写pattern="%{X-Real-IP}i,必须大写,否则出错,无法访问应用,后台查错为:
18-Nov-2020 20:21:32.564 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector[HTTP/1.1-1443]]
org.apache.catalina.LifecycleException: Protocol handler initialization failed
at org.apache.catalina.connector.Connector.initInternal(Connector.java:1042)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:533)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1057)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.startup.Catalina.load(Catalina.java:724)
at org.apache.catalina.startup.Catalina.load(Catalina.java:746)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:302)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472)
Caused by: java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
环境为centos8.2,tomcat版本为9.0.39,导致错误的原因不清。