in the microservice architecture. The Netflix Service Discovery component eureka can be easily integrated in spring cloud. Eureka includes server and client. The server side can be provided in the form of a cluster, and each server can achieve high availability by synchronizing the service status registered in other servers.
When an Eureka client registers with the server, it will provide its own metadata information, including host, port, health check URI and other information. The Eureka server determines whether the current instance is normal by listening to the heartbeat information of different instances of the same service. If the heartbeat information fails, the instance will be automatically removed.
To call services registered in Eureka, instead of using EurekaClient directly, you can use declarative rest client :feign, or Spring RestTemplate to more conveniently call services registered in Eureka.
2. Examples
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class EurekaServiceApplication { public static void main(String[] args) { SpringApplication.run(EurekaServiceApplication.class, args); } }
<?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.example</groupId> <artifactId>eureka-service</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/libs-snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </project>
server.port=8761 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false logging.level.com.netflix.eureka=OFF logging.level.com.netflix.discovery=OFF
package demo; import java.util.Arrays; import java.util.List; import java.util.Random; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author Spencer Gibb */ @SpringBootApplication @EnableDiscoveryClient @RestController public class HelloServerApplication { @RequestMapping("/greeting") public String hello() { List<String> greeting = Arrays.asList("Hi there","Greetings","Salutations"); Random rand = new Random(); int randomNum = rand.nextInt(greeting.size()); return greeting.get(randomNum); } public static void main(String[] args) { SpringApplication.run(HelloServerApplication.class, args); } }
<?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>org.test</groupId> <artifactId>feign-eureka-hello-server</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>feign-eureka-hello-server</name> <description>Demo project for Spring Cloud</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
spring: application: name: HelloServer server: port: 7111 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: leaseRenewalIntervalInSeconds: 10 metadataMap: instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}}
package demo; import static org.springframework.web.bind.annotation.RequestMethod.GET; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author Spencer Gibb */ @SpringBootApplication @RestController @EnableFeignClients public class HelloClientApplication { @Autowired HelloClient client; @RequestMapping("/greeting") public String hello() { return client.hello(); } public static void main(String[] args) { SpringApplication.run(HelloClientApplication.class, args); } @FeignClient("HelloServer") interface HelloClient { @RequestMapping(value = "/greeting", method = GET) String hello(); } }
The service id in FeignClient should be consistent with the value of spring.application.name in the User server configuration information
<?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>org.test</groupId> <artifactId>feign-eureka-hello-client</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>feign-eureka-hello-client</name> <description>Demo project for Spring Cloud</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
spring: application: name: HelloClient server: port: 7211 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: leaseRenewalIntervalInSeconds: 10 metadataMap: instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}} endpoints: restart: enabled: true shutdown: enabled: true health: sensitive: false
3.
Start Start the
Eureka server -> user server -> user client
and other applications in the following order. After all applications are started, visit http://localhost:7211/greeting through the interface, and you can access the return value of the method in the user-server normally. The process is to access the hello method in the user client project through the interface. The user client obtains the registered HelloServer instance from the Eureka server through the service id specified in @FeignClient, that is, the user server, and then calls the hello method in the user server, and returns the call result to user client, and finally return to the interface
4. Eureka cluster
1. Modify the configuration file corresponding to Eureka-server
spring: application: name: eureka-server-clustered profiles: primary server: port: 8011 eureka: instance: hostname: eureka-primary client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://eureka-secondary:8012/eureka/,http://eureka-tertiary:8013/eureka/ --- spring: application: name: eureka-server-clustered profiles: secondary server: port: 8012 eureka: instance: hostname: eureka-secondary client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://eureka-tertiary:8013/eureka/,http://eureka-primary:8011/eureka/ --- spring: application: name: eureka-server-clustered profiles: tertiary server: port: 8013 eureka: instance: hostname: eureka-tertiary client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://eureka-primary:8011/eureka/,http://eureka-secondary:8012/eureka/
2. Modify the configuration file corresponding to the user-server
spring: application: name: UserServer server: port: 7111 eureka: client: serviceUrl: defaultZone: http://eureka-secondary:8012/eureka/ instance: leaseRenewalIntervalInSeconds: 10 metadataMap: instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}}
Note: application.name has been modified, and the serviceid corresponding to feignclient also needs to be modified
3. Modify the configuration file corresponding to user-client
spring: application: name: UserClient server: port: 7211 eureka: client: serviceUrl: defaultZone: http://eureka-primary:8011/eureka/,http://eureka-secondary:8012/eureka/,http://eureka-tertiary:8013/eureka/ instance: leaseRenewalIntervalInSeconds: 10 metadataMap: instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}} endpoints: restart: enabled: true shutdown: enabled: true health: sensitive: false
3. If on the same machine, modify the hosts
# 127.0.0.1 localhost # ::1 localhost 127.0.0.1 localhost 127.0.0.1 eureka-primary 127.0.0.1 eureka-secondary 127.0.0.1 eureka-tertiary
Start Eureka-server user-server user-client in turn, where Eureka-server is started with
java -jar eureka-server-clustered-0.0.1-SNAPSHOT.jar --spring.profiles.active=primary java -jar eureka-server-clustered-0.0.1-SNAPSHOT.jar --spring.profiles.active=secondary java -jar eureka-server-clustered-0.0.1-SNAPSHOT.jar --spring.profiles.active=tertiary
Start three times, at this time Eureka-server provides services in the form of a cluster, you can close any one or two to test the high availability of Eureka