Problem Scenario: There are two network adapters on the server. Assume that the IP address starting with 13 is available, and the IP address starting with 10 is unavailable. In this case, the Eureka Client automatically selects the IP address starting with 10 as the service IP address during service registration, so other services cannot be invoked.

Cause of the problem (refer to other blog) : Because the official Eureka Client does not detect the native IP logic, so can only read the source code. In the eureka-Client module, InstanceInfo class in com.netflix. Appinfo package encapsulates the local information, including the IP address. In the Spring, Cloud environment had the Client does not own logic realization of detecting the machine IP, but instead to Spring InetUtils tools findFirstNonLoopbackAddress () method:

public InetAddress findFirstNonLoopbackAddress() { InetAddress result = null; Int lowest = integer. MAX_VALUE; // Get all network cardsfor (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(); // Record index}else if(result ! = null) {continue;
                    }

                    // @formatter:off
                    if(! IgnoreInterface (ifc.getDisplayName()) {// Whether a network interface is ignoredfor (Enumeration<InetAddress> addrs = ifc
                                .getInetAddresses(); addrs.hasMoreElements();) {
                            InetAddress address = addrs.nextElement();
                            if(address instanceof Inet4Address && ! address.isLoopbackAddress() && ! ignoreAddress(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 {
            returnInetAddress.getLocalHost(); GetLocalhost ()} Catch (UnknownHostException e) {log.warn(UnknownHostException e)"Unable to retrieve localhost");
        }

        return null;
    }
Copy the code

Solution:

1. Ignore the specified network adapter

As you can see from the source code analysis above, Spring Cloud can definitely configure a network card ignore list. Check the documentation to see that it does exist:

Spring. Cloud. Inetutils. Ignored - interfaces [0] = # eth0 ignore eth0, support for regular expressionsCopy the code

2. Manually specify the IP address (recommended)

Add the following configuration:

Eureka.instance. ip-address= # register with IP instead of hostname eureka.instance.prefer-ip-address=trueCopy the code

Note: This configuration is configured in the service that needs to specify A fixed IP address. If there are two network cards in the server running service A, I only have one network card to use, so I need to register the service using IP registration. In this case, when another service calls service A, the access address obtained from the registry is the prefer-ip-address parameter I configured.