在Apache背后设置Tomcat,如何轻松确定服务器的id(理想情况下是IP地址)?
具体情况是在负载均衡器后面设置了多个服务器,因此传入请求主机名是非唯一的,并且不足以识别特定服务器以进行日志记录。遗憾的是,使用HttpServletRequest.getLocalAddr()
会返回相同的主机名而不是预期的IP地址(我假设这与这个非常老的问题有关:https://issues.apache.org/bugzilla/show_bug.cgi?id=46082)。
是否有办法让getLocalAddr()
按照文档记录执行,或者是否需要查询服务器IP地址的其他方法?
答案 0 :(得分:2)
在我们的项目中,我们使用JMX获取所有配置信息。 它需要几个步骤,因为它就像在server.xml文件中导航一样 此链接包含以下信息:http://oss.wxnet.org/mbeans.html
如果您想要的只是IP,那可能有点过头了,但我想我会把它扔出去。
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
Set<ObjectName> theConnectors = mbeanServer.queryNames(
new ObjectName("Catalina:type=Connector,*"),
null);
if (theConnectors != null)
{
for (ObjectName nextConnectorName : theConnectors)
{
InetAddress theInetAddress = (InetAddress) mbeanServer.getAttribute(
nextConnectorName,
"address");
if (theInetAddress != null)
{
ipAddress = theInetAddress.getHostAddress();
}
if (!StringUtil.isEmpty(ipAddress))
{
// found the IP address
break;
}
}
}
答案 1 :(得分:1)
对于我的情况,解决方案是直接获取服务器的IP地址,而不是尝试通过HttpServleRequest获取本地地址。
我通过以下方式缓存IP以便在我的过滤器中使用:
private static final String serverIp;
static {
String addressString = null;
try
{
InetAddress address = InetAddress.getLocalHost();
addressString = address.getHostAddress();
} catch (Exception e)
{
logger.error("Exception while attempting to determine local ip address",e);
}
if (addressString != null) serverIp = addressString;
else serverIp = "unknown";
}
答案 2 :(得分:1)
我最近(在原始问题的几年之后)也遇到了类似的问题,并且找到了这个问题和答案。在我的情况下,问题在于ServletRequest#getLocalAddr()
实现正在返回远程地址而不是本地地址。该问题是由Tomcat v9.0.22中的回归引起的。在v9.0.23中已修复。在此处查看问题和答案: