Springcloud регистрирует имя хоста или IP

Spring Cloud

зарегистрировать имя хоста/ip

По умолчанию Eureka использует имя хоста для регистрации службы и отображения информации о службе. Если у нас есть способ IP-адреса, мы можем настроить его в файле конфигурации.eureka.instance.prefer-ip-address=true

ctrl + левая кнопка мыши в идее, нажмитеeureka.instance.prefer-ip-address=trueВойти для просмотраEurekaInstanceConfigBeanпредставит это свойство

EurekaInstanceConfigBean

/**
	 * Flag to say that, when guessing a hostname, the IP address of the server should be
	 * used in prference to the hostname reported by the OS.
	 */
	private boolean preferIpAddress = false;

PreferIpAddress: предпочитаемый IP-адрес. По умолчанию стоит false, то есть ip по умолчанию не прописан.

Должно быть какое-то место, чтобы судить, вEurekaInstanceConfigBeanИщите PreferIpAddress и находитеgetHostNameметод, Этот метод используется для возврата полученного имени хоста или ip

@Override
public String getHostName(boolean refresh) {
		if (refresh && !this.hostInfo.override) {
			this.ipAddress = this.hostInfo.getIpAddress();
			this.hostname = this.hostInfo.getHostname();
		}
		return this.preferIpAddress ? this.ipAddress : this.hostname;
}

1. Сначала мы будем судить:this.hostInfo.overrideСвойство Это свойство задается в методе setIpAddress. Метод setIpAddress соответствуетeureka.instance.ip-address=это свойство конфигурации.

То есть:eureka.instance.ip-addressа такжеeureka.instance.prefer-ip-address = trueПри этом настройка является приоритетомeureka.instance.ip-addressКонфигурация

public void setIpAddress(String ipAddress) {
		this.ipAddress = ipAddress;
		this.hostInfo.override = true;
	}

2.preferIpAddress возвращает атрибут имени хоста для значения false и возвращает атрибут ipAddress для значения true. Поиск имени хоста в EurekaInstanceConfigBean вернет имя хоста и ipAddress, которые можно получить из hostInfo; hostInfo можно получить из inetUtils.findFirstNonLoopbackHostInfo.

public EurekaInstanceConfigBean(InetUtils inetUtils) {
		this.inetUtils = inetUtils;
		this.hostInfo = this.inetUtils.findFirstNonLoopbackHostInfo();
		this.ipAddress = this.hostInfo.getIpAddress();
		this.hostname = this.hostInfo.getHostname();
}

Основное внимание уделяется этому методу InetUtils.findFirstNonLoopbackHostInfo.

public InetAddress findFirstNonLoopbackAddress() {
		InetAddress result = null;
		try {
			 // 记录网卡最小索引
			int lowest = Integer.MAX_VALUE; 
			// 获取所有网卡
			for (Enumeration<NetworkInterface> nics = NetworkInterface
					.getNetworkInterfaces(); nics.hasMoreElements();) {
				NetworkInterface ifc = nics.nextElement();
				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
					//网卡不忽略列表中
					if (!ignoreInterface(ifc.getDisplayName())) {
						for (Enumeration<InetAddress> addrs = ifc
								.getInetAddresses(); addrs.hasMoreElements();) {
							InetAddress address = addrs.nextElement();
							if (
		address instanceof Inet4Address//是IPV4
		&& !address.isLoopbackAddress()//不是回环地址(127.***)
		&& isPreferredAddress(address)) {//有推荐网卡,判断是推荐网卡内的ip
								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 {
			//都没有找到使用JDK的InetAddress获取
			return InetAddress.getLocalHost();
		}
		catch (UnknownHostException e) {
			log.warn("Unable to retrieve localhost");
		}

		return null;
}

Этот метод получитБерем все сетевые карты, берем IP-адрес сетевой карты с разумным IP-адресом, наименьшим значением индекса и не в игнор-листекак результат. Если подходящий IP не найден, звонитеInetAddress.getLocalHost()метод.

Пока резюмируем несколько гибких конфигураций для регистрации:

  • Регистрация ИП:eureka.instance.prefer-ip-address=true
  • Укажите регистрацию IP:eureka.instance.ip-address=
  • Игнорировать сетевую карту:spring.cloud.inetutils.ignored-interfaces[0]
  • Рекомендуемая сетевая карта:spring.cloud.inetutils.preferredNetworks[0]
  • Настройте хост-файл машины: когда InetUtils не может найти подходящий IP-адрес, он вызывает JDK.InetAddress.getLocalHost(). Этот метод разрешает соответствующий IP-адрес в соответствии с именем хоста машины. Таким образом, вы можете настроить имя хоста и/etc/hostsфайл, который напрямую сопоставляет имя хоста машины с действительным IP-адресом

Суммировать:

Поймите принцип регистрации имени хоста / IP, когда мы столкнемся с проблемами регистрации, будут указания по их решению.

Рекомендуемое чтение:

  1. Проблема instanceId регистрации сервиса в докере для Eureka
  2. Cannot find a way to configure Eureka client with Docker swarm mode