获取当前服务器ip地址

592 阅读1分钟

一、场景

老项目有多个实例,有个定时任务需要限制只在一台机器上执行,选择在代码里限制机器执行的ip,不满足指定的ip就不执行。也有其它的方法,如设置开关、分布式的任务调度框架等等。

二、代码

方式一

/**
 * 获取本地的IP地址
 *
 * @return
 */
public static String getHostAddress() {
    InetAddress address = null;
    try {
        // PC-20140317PXKX/192.168.0.121
        address = InetAddress.getLocalHost();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    // 192.168.0.121
    return address.getHostAddress();
}

问题

  1. 这种方式需要查看服务器的hostname,如果不是ip地址格式,且在系统/etc/hosts文件中没有ip和主机名的配置,会报错java.Net.UnknownHostException,在配置文件中配置:本机ip 主机名即可
  2. 服务器的网卡地址可能是多个,这样的的话会取到本地环回地址

方式二(推荐)

/**
 * 获取该主机上所有网卡的ip
 */
public static Set<String> getHostIp() {
    Set<String> ips = new HashSet<String>();
    try {
        Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
        while (allNetInterfaces.hasMoreElements()) {
            NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
            Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
            while (addresses.hasMoreElements()) {
                InetAddress ip = (InetAddress) addresses.nextElement();
                if (ip instanceof Inet4Address
                        && !ip.isLoopbackAddress() //loopback地址即本机地址,IPv4的loopback范围是127.0.0.0 ~ 127.255.255.255
                        && !ip.getHostAddress().contains(":")) {
                    ips.add(ip.getHostAddress());
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return ips;
}

这里取到服务器的所有网卡地址,只需要判断是否包含指定ip,不包含直接return就可以限制让集群架构的定时任务在指定ip的一台实例上执行

注:如果实例部署在一台机器不同端口,还需要加上端口限制