java网络编程中ipv4和ipv6导致的机器名长短问题

使用了Java网络编程,涉及到ipv4和ipv6的问题,在hadoop集群中由于机器配置不一,会导致不同机器获取的机器名长短不一,从而引发一系列问题,如“hadoop或yarn集群任务数据本地化很差(后面会写篇文章进行分析)”。

FQDN是Fully Qualified Domain Name的缩写, 含义是完整的域名。例如, 一台机器主机名(hostname)是www, 域后缀(domain)是example.com, 那么该主机的FQDN应该是www.example.com.。其实FQDN最后是以”.”来结尾的, 但是大部分的应用和服务器都允许忽略最后这个点。

Linux下用户可以通过hostname命令查看并设置主机名. 用户也可以通过

hostname -f

命令得到该主机的FQDN。

java文档中的说法是:

java.net.preferIPv4Stack (default: false)
If IPv6 is available on the operating system, the underlying native socket will be an IPv6 socket. This allows Java(tm) applications to connect too, and accept connections from, both IPv4 andIPv6 hosts.
在支持 IPv4 映射地址的 IPv6 网络堆栈中,可以使用 IPv6 套接字来连接到 IPv4 和 IPv6 主机以及接受来自这些主机的连接。

If an application has a preference to only use IPv4 sockets, then this property can be set to true. The implication is that the application will not be able to communicate with IPv6 hosts.

java.net.preferIPv6Addresses (default: false)
If IPv6 is available on the operating system, the default preference is to prefer an IPv4-mapped address over an IPv6 address. This is for backward compatibility reasons—for example, applications that depend on access to an IPv4-only service, or applications that depend on the %d.%d.%d.%d representation of an IP address.

This property can be set to try to change the preferences to use IPv6 addresses over IPv4 addresses. This allows applications to be tested and deployed in environments where the application is expected to connect to IPv6 services.

经过测试,如果系统启用了ipv6(在最新的linux内核中默认是启动了ipv6),使用

InetAddress.getLocalHost().getHostName()

获取到的机器名是完整的机器名如 search001.sqa.site.net ,而在ipv4的机器上获取到的是短机器名如search001.sqa。如果在ipv4的机器上想获取到完整的机器名,则使用

java -Djava.net.preferIPv4Stack=true TestHost.java

来运行程序。在jdk中也有此类“bug”的描述。

如果使用

InetAddress.getLocalHost().getCanonicalHostName()

则无论ipv4还是ipv6都能获取到完整的机器名。其实,getCanonicalHostName只是尽最大可能获取FQDN,意味着根据底层系统配置可能不能返回FQDN。


关于IPV6(介绍:
1. 查看linux系统是否支持ipv6:

ip address list  | grep inet6
ifconfig | grep inet6
cat /proc/sys/net/ipv6/conf/all/disable_ipv6

2. 通过设置运行时参数来禁用ipv6,不需要重启系统:

echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/lo/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6

或者,通过命令:

sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
sysctl -w net.ipv6.conf.lo.disable_ipv6 = 1
sysctl -w net.ipv6.conf.eth0.disable_ipv6 = 1

相反:设置为0就可以启用ipv6。

发表评论

电子邮件地址不会被公开。 必填项已用*标注