思维导图:
引言
Spring Cloud Eureka是Spring Cloud Netflix微服务套件中的一部分,它基于Netflix Eureka做了二次封装,主要负责完成微服务架构中的服务治理功能.
服务治理是微服务架构中最为核心和基础的模块,他主要实现微服务实例的注册与发现.为什么我们需要服务治理来管理微服务实例呢?当微服务实例较少时,我们可以通过某些静态配置来进行服务的声明和调用,随着业务的发展,微服务实例个数增加时,再使用静态申明就会导致极大的维护成本.
本文会通过 使用部分:环境搭建 ,原理部分:功能体系 来介绍Eureka的简单使用.
一.环境搭建
Eureka的环境主要分为服务端和客户端.服务端也称为注册中心.每个微服务都需要向注册中心注册自己能提供的服务.客户端则会将自己的服务向注册中心注册,并向注册中心获取可以调用的服务.
1.1 搭建注册中心
我们将以单节点和双节点的方式来搭建注册中心.
1.1.1 单节点注册中心
首先使用Spring Boot搭建一个基础环境,以下是Maven引用:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
随后,在Application.class处使用@EnableEurekaServer启用EurekaServer
@SpringBootApplication
@EnableEurekaServer
public class SpringCloudServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudServerApplication.class,args);
}
}
最后,配置Eureka相关参数
## 服务名称
spring.application.name=eureka-server
##服务端口号
server.port=1111
## 是否向注册中心注册自己.单节点的注册中心不需要此功能
eureka.client.register-with-eureka=false
## 是否需要检索可用微服务.单节点的注册中心不需要此功能
eureka.client.fetch-registry=false
## Eureka服务URL
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
启动服务,进入http://localhost:1111/ 可以看到注册中心的相关信息
1.1.2 双节点注册中心
对于分布式架构来说,单节点注册中心如果出现错误将是致命性的.所以,注册中心至少 得有两个.使用多节点的注册中心式,每个注册中心会向其他注册中心注册,所以两台注册中心的配置如下:
peer1:
## 服务名称
spring.application.name=eureka-server
##服务端口号
server.port=1111
## 实例主机地址
eureka.instance.hostname=peer1
## 服务URL
eureka.client.service-url.defaultZone=http://peer2:1112/eureka/
peer2:
spring.application.name=eureka-server
server.port=1112
eureka.instance.hostname=peer2
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/
可以看到,两台服务注册中心会互相注册,所以需要将一下参数设置为true
- eureka.client.register-with-eureka
- eureka.client.fetch-registry
然后,在配置中,我们看到微服务实例地址为peer1和peer2,即eureka.instance.hostname.这是因为我在本地测试,所以还需要再host文件中做 相关映射.Window hosts文件地址:C:\Windows\System32\drivers\etc\hosts,在文件中添加两行:
127.0.0.1 peer1
127.0.0.1 peer2
我们分别启动配置不同的两个注册中心服务.进入http://localhost:1111/ 或者http://localhost:1112/可以看到如下界面:
至此,双节点注册中心搭建完毕.
1.2 服务提供者
接下来,我们尝试向注册中心注册服务.当然,Eureka客户端的Maven引用稍稍不同于Eureka服务端:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.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>
需要使用@EnableDiscoveryClient开启Eureka客户端服务
@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudClientApplication {
public static void main(String[] args){
SpringApplication.run(SpringCloudClientApplication.class,args);
}
}
最后,相关配置为:
spring.application.name=hello-client-service
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/
至现在位置,我们这个服务提供者还没有一个可供调用的服务.所以添加一个简单的Controller,用于打印当前注册中心信息的接口.
@RestController
public class HelloController {
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String index(){
ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance();
System.out.println("host:" + serviceInstance.getHost() + ",serviceId:" + serviceInstance.getServiceId());
return "hello world";
}
}
启动服务,可以看到Eureka的管理页面中有这一服务的信息了.
手动调用此接口http://localhost:8080/hello,可以看到hello world.
最后,将此producer服务提供者打包后,我们使用命令用不同的端口后再次启动此服务.
java -jar eureka-client-1.0-SNAPSHOT.jar --server.port=8081
java -jar eureka-client-1.0-SNAPSHOT.jar --server.port=8082
可以看到,页面上已有三个同名的服务了,他们的端口号分别是8080,8081,8082
1.3 服务消费者
现在,我们有了双节点的服务注册中心,和三个一样的服务提供者.接下来,我们构建具有简单的负载均衡的服务消费者来获取并调用服务.
消费者配置:
spring.application.name=consumer-service
server.port=9000
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/,http://localhost:1112/eureka/
服务消费者和服务提供者的配置完全一样.只是因为我们希望在这个消费者进行负载均衡,所以需要引入Ribbon.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
接下来,我们需要调用服务了.,这个HELLO-CLIENT-SERVICE是我服务提供者的spring.application.name=hello-client-service
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consume",method = RequestMethod.GET)
public String consume(){
return restTemplate.getForEntity("http://HELLO-CLIENT-SERVICE/hello",String.class).getBody();
}
}
接下来,多次调用http://localhost:9000/consume,可以看到,多台服务提供者都会打印以下信息.
至此,一个简单的微服务治理体系搭建完成.
二.功能体系
第一小节完成的一个简单的微服务治理体系.接下来,我们看看以上三者的功能和作用分别是什么.
在实际使用中一个微服务实例一般即是消费者也是提供者.
2.1 服务注册中心
- 服务维护:储存服务提供者注册的服务元数据
- 失效剔除:当服务提供者失效时,剔除出可用服务列表
- 服务同步:接收到一个服务提供者注册的服务时,会将此信息同步给其他注册中心
- 自我保护:服务提供者在服务注册中心注册成功后,会维护一个心跳连接,告诉注册中心自己还活着.如果统计的心跳连接失败的比例在15分钟内地域85%,注册中心将会把当前实例的信息保护起来,让其不会过期.我们将三个服务提供者关掉一个,等一会就会出现如下提示,就表示已有服务进入自我保护机制了.
2.2 服务提供者
- 服务注册:服务在启动时向注册中心注册服务
- 服务续约:注册成功后维护一个心跳连接告诉注册中心服务正常,防止被剔除.
2.3 服务消费者
- 服务获取:服务启动时,向注册中心获取服务清单,此清单没30秒更新一次.
- 服务调用:服务消费者可以根据服务信息自己选择合适的服务调用方式.注册中心有Region和Zone的概念.一个Region可能具有多个Zone,一个Zone下可能具有多个服务实例.进行服务调用时,会优先访问同一个Zone下的服务实例
- 服务下线:当服务面临重启或关闭的情况下,告诉注册中心我要下下线了.