当前位置: 代码迷 >> 综合 >> 源码分析 spring.cloud.inetutils.preferredNetworks、spring.cloud.zookeeper.discovery.prefer-ip-address
  详细解决方案

源码分析 spring.cloud.inetutils.preferredNetworks、spring.cloud.zookeeper.discovery.prefer-ip-address

热度:62   发布时间:2024-02-09 06:27:08.0

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的ip2.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,也就是文章开头的那个注解在这里                    实现了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 下

  相关解决方案