搭建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,导致错误的原因不清。