Eureka
“ Eureka ”来源于古希腊词汇,意为“发现了”。在软件领域, Eureka是一个开源的服务注册与发现的组件,和其他Netflix公司的服务组件(例如负载均衡、熔断器、网关等) 一起被Spring Cloud 社区整合为Spring Cloud Netflix 模块。
本节将从以下4个方面来讲解服务注册与发现模块Eureka :
1)Eureka 简介;2)编写一个Eureka 注册和发现的例子;3)深入理解Eureka;4)编写高可用的Eureka Server
一、Eureka 简介
什么是Eureka?
Eureka 是一个用于服务注册和发现的组件,最开始主要应用于亚马逊公司旗下的云计算服务平台AWS;Eureka 分为Eureka Server 和Eureka Client, Eureka Server 为Eureka 服务注册中心, Eureka Client 为Eureka 客户端
为什么选择Eureka?
1)Eureka 完全开源, 经历了Netflix 公司的生产环境的考验,以及3年时间的不断迭代,在功能和性能上都非常稳定可以放心使用;
2)Eureka 是Spring Cloud 首选推荐的服务注册与发现组件, 与Spring Cloud 其他组件可以无缝对接;
3)Eureka 和其他组件,如负载均衡组件Ribbon 、熔断器组件Hystrix、熔断器监控组件Hystrix Dashboard 组件、熔断器聚合监控Turbine 组件,以及网关Zuul 组件相互配合, 能够很容易实现服务注册、负载均衡、熔断和智能路由等功能。这些组件都是由Netflix 公司开源的称为Netflix OSS 组件;Netflix OSS 组件由Spring Cloud 整合为Spring Cloud Netflix 组件,是Spring Cloud 构架微服务的核心组件,也是基础组件。
Eureka 的基本架构
Eureka 的基本架构如下图所示:
主要包括以下3 种角色:
1)Register Service :服务注册中心,它是一个Eureka Server ,提供服务注册和发现的功能;
2)Provider Service :服务提供者,它是一个Eureka Client ,提供服务;
3)Consumer Service :服务消费者,它是一个Eureka Cient ,消费服务。
服务消费的基本过程如下:
1)需要一个服务注册中心Eureka Server ,服务提供者Eureka Client 向服务注册中心Eureka Server 注册,将自己的信息(比如服务名和服务的IP 地址等)通过REST API的形式提交给服务注册中心Eureka Server ;
2)服务消费者Eureka Client 也向服务注册中心 Eureka Server 注册,同时服务消费者获取一份服务注册列表的信息, 该列表
包含了所有向服务注册中心Eureka Server 注册的服务信息;
3)获取服务注册列表信息之后,服务消费者就知道服务提供者的IP 地址,可以通过Http远程调度来消费服务提供者的服务。
二、编写 Eureka Server
由于本案例有多个Spring Boot 工程,为了方便管理,采用 Maven 多 Module 的结构,所以需要创建一个Maven 主工程,本案例最终完整项目的结构如下:
创建完主Maven 工程之后,在主Maven 的pom 文件下,引入eureka-client 和eureka-server两个Module 工程共同所需的依赖,包括版本为1 . 5 . 3.RELEASE 的Spring Boot 依赖,版本为Dalston.SRI 的Spring Cloud 依赖,指定Java 版本为1.8 ,编码为UTF-8;主 Maven 的pom 文件代码如下:POM.xml
<?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.forezp</groupId>
<artifactId>chapter5-2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>eureka-client</module>
<module>eureka-server</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
创建完主Maven 工程且配置完主工程的pom文件后,创建一个Module 工程,命名为eureka-server。采用Spring Initializr 的方式构建, 作为服务注册中心Eureka Server 的工程, 其工程目录结构如下:
在 eureka-server 工程的pom文件引入相关的依赖, 包括继承了主Maven 工程的pom 文件,引入了Eureka Server的起步依赖spring-cloud-starter-eureka-server,以及Spring Boot 测试的起步依赖spring-boot-starter-test ;最后还引入了Spring Boot 的Maven 插件spring-boot-maven-plugin , 有了该插件, 即可使用Maven 插件的方式来启动Spring Boot 工程。具体代码如下:
<?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.forezp</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.forezp</groupId>
<artifactId>chapter5-2</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/>
</parent>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在工程的配置文件application.yml 中做程序的相关配置, 首先通过server.port 指定Eureka Server 的端口为8761 ,在默认情况下, Eureka Server 会向自己注册,这时需要配置 eureka.client.registerWithEureka 和 eureka.client. fetchRegistry 为false ,防止自己注册自己。配置文件application.yml 的代码如下:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
在工程的启动类 EurekaServerApplication 加上注解@EnableEurekaServer , 开启 Eureka Server 的功能。代码如下:
EurekaServerApplication.java :
package com.forezp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
到此为止, Eureka Server 的所有搭建工作已经完成;
启动程序启动类 EurekaServerApplication 的main 方法,启动程序;在浏览器上访问Eureka Server 的主界面 http://localhost:8761, 在界面上的Instances currently registered with Eureka 这一项上没有任何注册的实例,没有是正常的,
因为还没有Eureka Client 客户端向注册中心Eureka Server 注册实例。Eureka Server 的主界面如下图:
三、编写 Eureka Client
在主Maven 工程中创建一个新的Module 工程,命名为eureka-client , 该工程作为Eureka Client 的工程向服务注册中心Eureka server 注册,目录结构如下图:
eureka-client 工程创建完之后, 在其pom文件中引入相关的依赖,其pom 文件继承了主工程的pom文件, 并且需要引入Eureka Client 客户端所需的依赖spring-cloud-starter-eureka,引入Web 功能的起步依赖spring-boot- starter-web,
以及Spring Boot 测试的起步依赖spring-boot-starter-test , 具体代码如下:Pom.xml
<?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.forezp</groupId>
<artifactId>eureka-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-client</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.forezp</groupId>
<artifactId>chapter5-2</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
在工程的配置文件bootstrap.yml 做Eureka Client 客户端的相关配置,配置了程序名为eureka-client ,程序端口为8762 ,服务注册地址为 http://localhost:8761/eureka/ ,代码如下:bootstrap.yml
server:
port: 8762
spring:
application:
name: eureka-client
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
在程序的启动类 EurekaClientApplication 加上注解@EnableEurekaClient 开启Eureka Client功能,其代码如下:EurekaClientApplication.java
package com.forezp;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
启动Eureka Client 工程, 启动成功之后, 在控制台会打印出如下信息:
INFO 3536 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-CLIENT/jianghaok.digitalchina.com:eureka-client:8762 - registration status: 204
以上的日志信息说明Eureka Client 客户端已经向Eureka Server 注册了;在浏览器上打开
Eureka Server 主页 :http://localhost:8761/, 主页显示如下图所示:
在上图中, 在主页上的Instances currently registered with Eureka 选项中己经有一个实例被注册, Application 为EUREKA-CLIENT, Staus 为UPC 在线) , 端口为8762 ;这就说明Eureka Client己成功向Eureka Server 注册。
在eureka-client 工程中写一个API 接口。新建一个类Hi Controller , 在H iController 类加上@RestController 注解,开启RestController 的功能。@ GetMapping 注解表明是一个Get 请求,其请求地址映射为“ /hi ”,其中@Value(”$ {server. port }”)向配置文件读取配置的端口信息。其完整代码如下:HiController.java
package com.forezp.web;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HiController {
@Value("${server.port}")
String port;
@GetMapping("/hi")
public String home(@RequestParam String name) {
return "hi " + name + ",i am from port:" + port;
}
}
在浏览器上访问:http: //localhost:8762/hi?name=forezp ,浏览器显示如下的信息:
————————————————————————————————————————————