Eureka cluster deployment and pit stepping records (attention, attention!!!)

Posted by kingman65 on Wed, 22 Dec 2021 01:40:50 +0100

1, Eureka cluster deployment

It is recommended to deploy in strict accordance with the steps first, otherwise it is easy to cause problems. The possible problems will be described below

1. Create a maven project, pom example is as follows

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.iceberg.eurekatest</groupId>
    <artifactId>eureka-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2. Annotate the Application class and open eureka

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

3. Add two configuration files application-peer1 yaml

spring:
  application:
    name: eureka-server

server:
  port: 8001

eureka:
  client:
    #Register yourself with Eureka Server
    register-with-eureka: true
    #Get registration information from Eureka Server
    fetch-registry: true
    serviceUrl:
      defaultZone: "http://peer2:8002/eureka/"
  instance:
    prefer-ip-address: false
    hostname: "peer1"

application-peer2.yaml

spring:
  application:
    name: eureka-server

server:
  port: 8002

eureka:
  client:
    #Register yourself with Eureka Server
    register-with-eureka: true
    #Get registration information from Eureka Server
    fetch-registry: true
    serviceUrl:
      defaultZone: "http://peer1:8001/eureka/"
  instance:
    prefer-ip-address: false
    hostname: "peer2"

4. Add two mappings in host
127.0.0.1 peer1
127.0.0.1 peer2

5. Add - dspring. To the startup parameter of SpringBoot profiles. Active = peer1, and then start the project.


Then change to peer2 and start the project (two in total)

6. Precautions
(1) When the first eureka is started, the following exceptions will be reported

2019-07-29 15:49:57.335  WARN 15416 --- [nfoReplicator-0] c.n.discovery.InstanceInfoReplicator     : There was a problem with the instance info replicator

com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
	at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.9.12.jar:1.9.12]
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.12.jar:1.9.12]
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) ~[eureka-client-1.9.12.jar:1.9.12]
	at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) ~[eureka-client-1.9.12.jar:1.9.12]
	at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) ~[eureka-client-1.9.12.jar:1.9.12]
	at com.netflix.discovery.DiscoveryClient.register(DiscoveryClient.java:847) ~[eureka-client-1.9.12.jar:1.9.12]
	at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:121) ~[eureka-client-1.9.12.jar:1.9.12]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_212]
	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) [na:1.8.0_212]
	at java.util.concurrent.FutureTask.run(FutureTask.java) [na:1.8.0_212]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_212]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_212]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_212]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_212]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_212]

This exception means that the configured Eureka server is not found (because you haven't started yet). It will be normal after the second Eureka server is started
(2) In the eureka stand-alone configuration, the register with eureka and fetch registry options are false, but the cluster version of eureka uses service discovery, so it needs to be changed to true to register itself with the server and obtain the client information
7. After startup, the browser accesses localhost:8001 and localhost:8002
See the figure below to indicate success

 

2, Possible pitfalls during cluster deployment

1. Instead of adding host, use localhost directly
Some friends may not know how to change the host or simply be lazy. They directly replace the previous peer1 and peer2 with localhost. The configuration file is as follows
application-peer1.yaml

spring:
  application:
    name: eureka-server

server:
  port: 8001

eureka:
  client:
    #Register yourself with Eureka Server
    register-with-eureka: true
    #Get registration information from Eureka Server
    fetch-registry: true
    serviceUrl:
      defaultZone: "http://localhost:8002/eureka/"
  instance:
    prefer-ip-address: false
    hostname: "localhost"

application-peer2.yaml

spring:
  application:
    name: eureka-server

server:
  port: 8002

eureka:
  client:
    #Register yourself with Eureka Server
    register-with-eureka: true
    #Get registration information from Eureka Server
    fetch-registry: true
    serviceUrl:
      defaultZone: "http://localhost:8001/eureka/"
  instance:
    prefer-ip-address: false
    hostname: "localhost"

There are two situations:
(1) Deploy two eureka on a single machine, and then access http://localhost:8001/ 


You can see that the registered replicas column is empty. Why is it like this?
Let's look at the resolvePeerUrls() method of peereeurekanodes in eureka's source code. This method is used to obtain the available address from the configured serviceUrl

protected List<String> resolvePeerUrls() {
    InstanceInfo myInfo = applicationInfoManager.getInfo();
    String zone = InstanceInfo.getZone(clientConfig.getAvailabilityZones(clientConfig.getRegion()), myInfo);
    List<String> replicaUrls = EndpointUtils
            .getDiscoveryServiceUrls(clientConfig, zone, new EndpointUtils.InstanceInfoBasedUrlRandomizer(myInfo));

    int idx = 0;
    while (idx < replicaUrls.size()) {
	//This place is the culprit
        if (isThisMyUrl(replicaUrls.get(idx))) {
            replicaUrls.remove(idx);
        } else {
            idx++;
        }
    }
    return replicaUrls;
}

public boolean isThisMyUrl(String url) {
    final String myUrlConfigured = serverConfig.getMyUrl();
    if (myUrlConfigured != null) {
        return myUrlConfigured.equals(url);
    }
    return isInstanceURL(url, applicationInfoManager.getInfo());
}

//Judge whether the hostnam of the url is consistent with the current hostname. If so, ignore it directly
public boolean isInstanceURL(String url, InstanceInfo instance) {
    String hostName = hostFromUrl(url);
    String myInfoComparator = instance.getHostName();
    if (clientConfig.getTransportConfig().applicationsResolverUseIp()) {
        myInfoComparator = instance.getIPAddr();
    }
    return hostName != null && hostName.equals(myInfoComparator);
}

Through the isInstanceURL() method, eureka will remove the url with the same hostname, and we happen to configure localhost. Therefore, although you start two eureka, they will not regard themselves as clusters
(2) Multi machine (or multi virtual machine) deployment
If you start two eureka on different hosts and configure localhost, you will always see com netflix. discovery. shared. transport. Transportexception: cannot execute request on any known server this error because it cannot find another eureka through localhost

2. Instead of using a domain name, use IP registration
eureka provides an option to enable the registered address of eureka to use IP instead of domain name. The configuration item is eureka instance. prefer-ip-address=true
(1) Single machine multi network card deployment
Here is an explanation of what is multi network card. After we install vmware, it will create some virtual network cards for us. For example, it creates two virtual addresses for me


Multi network card means that you can see multiple IP addresses by using the ipconfig command (only my own definition, not academic definition)
In this case, the registered IP of eureka may be different from your actual IP. For example, the instance info of eureka I just started shows that the IP is 192.168 157.1. In this case, his registered IP is also 192.168 157.1. In order for him to register the actual IP, we need to pass eureka instance. ip-address=10.60. 44.136 specify the following


Then the question comes, if your peer1 IP address is 10.60 44.136, serviceurl in peer2 The url in the defaultzone must also be 10.60 44.136, what is the IP address of peer2? Also use 10.60 44.136 will cause the previous problem, which is eliminated by eureka, so you need to change an IP and still represent the local one, such as 127.0 0.1, the configuration file is as follows: application-peer1 yaml

spring:
  application:
    name: eureka-server

server:
  port: 8001

eureka:
  client:
    #Register yourself with Eureka Server
    register-with-eureka: true
    #Get registration information from Eureka Server
    fetch-registry: true
    serviceUrl:
      defaultZone: "http://127.0.0.1:8002/eureka/"
  instance:
    prefer-ip-address: true
    hostname: "localhost"
    ip-address: "10.60.44.136"

application-peer2.yaml

spring:
  application:
    name: eureka-server

server:
  port: 8002

eureka:
  client:
    #Register yourself with Eureka Server
    register-with-eureka: true
    #Get registration information from Eureka Server
    fetch-registry: true
    serviceUrl:
      defaultZone: "http://10.60.44.136:8001/eureka/"
  instance:
    prefer-ip-address: true
    hostname: "localhost"
    ip-address: "127.0.0.1"

The results after running are shown in the figure below

 

(2) Single network card deployment
Just now, multiple network cards mean that ipconfig has multiple IPS. A single network card means that there is only one IP. According to the previous description, when there is only one IP, your single machine cannot deploy the cluster successfully (it will be ignored), so it is omitted~

(3) Multi machine deployment
There's nothing to say about this. ip is specified as the ip that can access each other. As long as it is configured correctly, it's OK

3, Summary

1. Single machine pseudo cluster deployment
Method 1: each eureka instance uses a different domain name to map to the same IP
Method 2: each eureka instance uses different IPs, but these IPS should all represent local IP addresses

2. The domain name or IP can also be used for multi machine deployment, but do not use localhost. Ensure that instances can find each other through the domain name or IP

The above is a summary of my deployment of eureka cluster. I hope it will be helpful to you~

Topics: Java Maven Spring Boot eureka