识别Tomcat上的服务器(HttpServletRequest.getLocalAddr()失败)

时间:2013-02-08 19:48:05

标签: java apache tomcat

在Apache背后设置Tomcat,如何轻松确定服务器的id(理想情况下是IP地址)?

具体情况是在负载均衡器后面设置了多个服务器,因此传入请求主机名是非唯一的,并且不足以识别特定服务器以进行日志记录。遗憾的是,使用HttpServletRequest.getLocalAddr()会返回相同的主机名而不是预期的IP地址(我假设这与这个非常老的问题有关:https://issues.apache.org/bugzilla/show_bug.cgi?id=46082)。

是否有办法让getLocalAddr()按照文档记录执行,或者是否需要查询服务器IP地址的其他方法?

3 个答案:

答案 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中已修复。在此处查看问题和答案:

https://stackoverflow.com/a/57725039/9602527