spring.cloud.inetutils.preferredNetworks、spring.cloud.zookeeper.discovery.prefer-ip-address 源码分析
1.命令意义spring.cloud.inetutils.preferredNetworks[0]=10.10.30.*//SpringCloud注入注册中心选择的网卡spring.cloud.zookeeper.discovery.prefer-ip-address=true //使用IP作为注册中心address而不是主机名(默认是主机名称);2.源码分析2.1说明:当maven引入一下spr
·
1.配置指令意义
spring.cloud.inetutils.preferredNetworks[0]=10.10.30.* //SpringCloud注入注册中心选择的网卡
spring.cloud.zookeeper.discovery.prefer-ip-address=true //使用IP作为注册中心address而不是主机名(默认是主机名称);
2.源码分析
2.1说明:
当maven引入一下spring-cloud-starter-zookeeper-discovery,即:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<exclusions>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>spring-cloud-netflix-core</artifactId>
<groupId>org.springframework.cloud</groupId>
</exclusion>
</exclusions>
</dependency>
就默认开启(当然还有些许,不就一一列举了):
spring.cloud.zookeeper.discovery.register=true //开启网关注册
spring.cloud.zookeeper.discovery.enabled=true //启用zookeeper作为配置中心
2.2 源码
先找到spring-cloud-zookeeper-discovery-*.*.*.jar,如图:
然后打开serviceregister包下ZookeeperServiceRegistryAutoConfiguration.zookeeperDiscoveryProperties(),往下跟进去,可以看到:
public ZookeeperDiscoveryProperties(InetUtils inetUtils) {
this.hostInfo = inetUtils.findFirstNonLoopbackHostInfo();//重点在这里,继续跟进去
this.instanceHost = this.hostInfo.getHostname();
this.instanceIpAddress = this.hostInfo.getIpAddress();
}
/*继续跟下去*/
public HostInfo findFirstNonLoopbackHostInfo() {
InetAddress address = findFirstNonLoopbackAddress(); //这里也继续跟下去
if (address != null) {
return convertAddress(address);
}
HostInfo hostInfo = new HostInfo();
hostInfo.setHostname(this.properties.getDefaultHostname()); //默认localhost 一般是找不到网卡才会设置这个值
hostInfo.setIpAddress(this.properties.getDefaultIpAddress());//默认127.0.0.1 一般是找不到网卡才会设置这个值
return hostInfo;
}
继续跟下去最后来到了核心代码。
public InetAddress findFirstNonLoopbackAddress() {
InetAddress result = null;
try {
int lowest = Integer.MAX_VALUE;
/*首先是NetworkInterface.getNetworkInterfaces()
这里是获取网卡的意思,一般都是一个网卡集合,
里面有个 public static native NetworkInterface getAll()
获取网卡集合,有兴趣的同学可以研究下这个源码*/
for (Enumeration<NetworkInterface> nics = NetworkInterface
.getNetworkInterfaces(); nics.hasMoreElements();) {
NetworkInterface ifc = nics.nextElement();
/*ifc.isUp() 返回网络接口是否已启动并正在运行*/
if (ifc.isUp()) {
log.trace("Testing interface: " + ifc.getDisplayName());
if (ifc.getIndex() < lowest || result == null) {
lowest = ifc.getIndex();
}
else if (result != null) {
continue;
}
// @formatter:off
/*ignoreInterface(ifc.getDisplayName()) 是否忽略网卡
即执行 spring.cloud.inetutils.ignored-interfaces[0]=eth0 */
if (!ignoreInterface(ifc.getDisplayName())) {
for (Enumeration<InetAddress> addrs = ifc
.getInetAddresses(); addrs.hasMoreElements();) {//开始遍历网卡的接口
InetAddress address = addrs.nextElement();
/*1.address instanceof Inet4Address 只选择ipv4的ip
2.address.isLoopbackAddress()用于检查InetAddress是否为回送地
址
3. isPreferredAddress(address) 重点讲下这里面的方法们,在下个
代码块*/
if (address instanceof Inet4Address
&& !address.isLoopbackAddress()
&& isPreferredAddress(address)) {
log.trace("Found non-loopback interface: "
+ ifc.getDisplayName());
result = address;
}
}
}
// @formatter:on
}
}
}
catch (IOException ex) {
log.error("Cannot get first non-loopback address", ex);
}
if (result != null) {
return result;
}
try {
return InetAddress.getLocalHost();
}
catch (UnknownHostException e) {
log.warn("Unable to retrieve localhost");
}
return null;
}
/** For testing. */ boolean isPreferredAddress(InetAddress address) {
/*isUseOnlySiteLocalInterfaces()只使用站点本地地址,即
# 遵循 RFC 1918
# 10/8 前缀
# 172.16/12 前缀
# 192.168/16 前缀
spring.cloud.inetutils.use-only-site-local-interfaces=true
一般不会配置走这个的*/
if (this.properties.isUseOnlySiteLocalInterfaces()) {
final boolean siteLocalAddress = address.isSiteLocalAddress();
if (!siteLocalAddress) {
log.trace("Ignoring address: " + address.getHostAddress());
}
return siteLocalAddress;
}
/*this.properties.getPreferredNetworks() 指定网卡IP,也就是文章开头的那个注解在这里
实现了,这里就是获取我们配置的IP,并进行有效性匹配
spring.cloud.inetutils.preferred-networks=192.168.0.1 #可以是IP段:192.168.0.*
*/
final List<String> preferredNetworks = this.properties.getPreferredNetworks();
if (preferredNetworks.isEmpty()) {
return true;
}
for (String regex : preferredNetworks) {//进行匹配
final String hostAddress = address.getHostAddress();
if (hostAddress.matches(regex) || hostAddress.startsWith(regex)) {
return true;
}
}
log.trace("Ignoring address: " + address.getHostAddress());
return false;
}
至于 spring.cloud.zookeeper.discovery.prefer-ip-address=true ,是在最初的那个类ZookeeperDiscoveryProperties 实现,即:
public String getInstanceHost() {
if (this.preferIpAddress && StringUtils.hasText(this.instanceIpAddress)) {
return this.instanceIpAddress;
}
return this.instanceHost;
}
3.如何查看
以Linux为例
1.先登录到zookeeper的服务器上,找到zookeeper的bin下面的zkCli.sh文件,并执行它,如图:
2.执行 get 命令,不特定指定的话,SpringCloud注册的服务都是在 /services 下
更多推荐
已为社区贡献2条内容
所有评论(0)