文章目录
一.概念
1.什么是Eureka?
Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务注册与发现功能。
- Eureka采用了C-S的架构设计,EurekaServer作为服务注册功能的服务器,他是服务注册中心.
- 而系统中的其他微服务,使用Eureka的客户端连接到EurekaServer并维持心跳连接。这样系统的维护人员就可以通过EurekaServer来监控系统中各个微服务是否正常运行,Springcloud 的一些其他模块 (比如Zuul) 就可以通过EurekaServer来发现系统中的其他微服务,并执行相关的逻辑.
Eureka包含两个组件:Eureka Server和Eureka Client。
Eureka Server:提供服务的注册与发现
Service Provider: 将自身的服务注册到Eureka中,从而使消费方能够找到。
Service Consumer:服务消费方从Eureka中获取注册服务列表,从而找到消费服务。
2.Eureka Server
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。
3.Eureka Client
Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
二.配置Eureka服务端(配置中心)
1.导入依赖
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2.配置文件
server:
port: 7001
#eureka配置
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #表示是否向eureka注册中心注册自己
fetch-registry: false #若为false,则表示自己为注册中心
service-url: #监控页面
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3.服务端启动类
@SpringBootApplication
@EnableEurekaServer //EnableEurekaServer服务端的启动类,可以接受别人注册进来
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class,args);
}
}
4.服务端测试
输入:http://localhost:7001/
三.配置Eureka客户端(将服务注册到Eureka)
1.在客户端引入依赖
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.在客户端配置文件配置Eureka
server:
port: 800
spring:
application:
name: springcloud-provider-dept
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#单机
defaultZone: http://localhost:7001/eureka
# 集群
#defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
3.客户端启动类
@SpringBootApplication
@EnableEurekaClient //在服务启动后自动注册到Eureka中
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class,args);
}
}
4.测试结果
5.配置Eureka服务的相关信息
EG1:
引入依赖
<!--完善监控信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
添加配置
#服务中的info信息配置
info:
app.name: kuang-springcloud
company.name: blog.kuang.com
效果
EG2:
服务提供者的配置类:
@SpringBootApplication
@EnableEurekaClient //在服务启动后自动注册到Eureka中
@EnableDiscoveryClient//服务发现
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class,args);
}
}
访问提供者的访问接口:
//获取一些配置的信息,得到具体的微服务
@Autowired
private DiscoveryClient discoveryClient;
//获取注册进来的微服务的相关信息
@RequestMapping("/dept/discovery")
public Object discovery(){
//获取微服务列表的清单
List<String> services=discoveryClient.getServices();
System.out.println("discovery=>services:"+services);
//提供具体的微服务名称,得到该名称的服务具有的微服务信息
List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
for (ServiceInstance instance:instances){
System.out.println(
instance.getHost()+"\t"+
instance.getPort()+"\t"+
instance.getUri()+"\t"+
instance.getServiceId()
);
}
return this.discoveryClient;
}
输入:http://localhost:8001/dept/discovery
四.自我保护机制
1.概念
自我保护机制是一种应对网络异常的安全保护措施。它的架构哲学是宁可保留不健康的微服务,也不轻易注销健康的微服务。
Eureka Server 在运行期间会统计全部服务总体的心跳数,在15分钟内是否低于应该受到的85%。如果低于,则认为是网络异常问题,应该保护,Eureka Server会将当前的实例注册信息保护起来,同时提示一个警告。
一旦进入保护模式:
Eureka Server将会不再删除服务注册表中的数据。也就是不会注销任何微服务。
Eureka server仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上,保证当前节点依然可用。
2.如何禁用自我保护机制?
修改在eureka注册中心的配置文件?
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
#关闭自我保护机制,保证不可用服务被及时踢除
peer-node-read-timeout-ms: 90000
3.效果
若某个服务在规定时间内没有发送心跳给eureka服务器,则会立刻被剔除
五.Eureka服务器端集群
1.创建三个eureka服务端(服务注册中心)
2.修改服务端7001,7002和7003的配置文件
7001
#eureka配置
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #表示是否向eureka注册中心注册自己
fetch-registry: false #若为false,则表示自己为注册中心
service-url: #监控页面
#单机就是7001自己
#defaultZone: http://eureka7001.com:7001/eureka/
#集群指向其它eureka
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
#关闭自我保护机制,保证不可用服务被及时踢除
peer-node-read-timeout-ms: 90000
7002
#eureka配置
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #表示是否向eureka注册中心注册自己
fetch-registry: false #若为false,则表示自己为注册中心
service-url: #监控页面
#单机就是7001自己
#defaultZone: http://eureka7002.com:7002/eureka/
#集群指向其它eureka
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
7003
#eureka配置
eureka:
instance:
hostname: eureka7003.com #eureka服务端的实例名称
client:
register-with-eureka: false #表示是否向eureka注册中心注册自己
fetch-registry: false #若为false,则表示自己为注册中心
service-url: #监控页面
#单机就是7001自己
#defaultZone: http://eureka7003.com:7003/eureka/
#集群指向其它eureka
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
修改客户端的配置文件
#eureka的配置
eureka:
client:
service-url:
#将客户端注册进服务端7001,7002,7003
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
3.效果
六.客户端(服务提供者)集群
1.创建两个客户端(服务提供者)
详情参考步骤三:配置Eureka客户端
2.修改客户端(服务提供者)配置文件
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#单机版
#defaultZone: http://localhost:7001/eureka
# 集群版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
3.修改客户端(服务调用者)配置类
开启调用服务时使用负载均衡算法
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced//开启负载均衡,使用自己的负载均衡算法
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
4.效果
服务调用者调用服务时使用轮询算法服务不同服务提供者的服务
七.CAP原则及Eureka与Zookeeper的对比
1.什么是CAP原则?
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency),可用性(Availability)、分区容错性(Partition tolerance)。CAP原则的精髓就是要么AP,要么CP,要么AC,但是不存在CAP。
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):保证每个请求不管成功或者失败都有响应。
分区容忍性(P):系统中任意信息的丢失或失败不会影响系统的继续运作。
2.Eureka与Zookeeper的对比
1、Zookeeper当master挂了,会在30-120s进行leader选举,这点类似于redis的哨兵机制,在选举期间Zookeeper是不可用的,这么长时间不能进行服务注册,是无法忍受的,别说30s,5s都不能忍受。这时Zookeeper集群会瘫痪,这也是Zookeeper的CP,保持节点的一致性,牺牲了A/高可用。而Eureka不会,即使Eureka有部分挂掉,还有其他节点可以使用的,他们保持平级的关系,只不过信息有可能不一致,这就是AP,牺牲了C/一致性
2、在之前的文章已经提到过Eureka有自我保护机制(15分钟内超过85%的服务节点没有心跳/down),这点我觉得确实要比Zookeeper好,即使服务不可用,也会保留当前失效的微服务,默认90秒,在这90秒Eureka不会注销微服务,在这90秒内仍然可以接受新的服务注册,只是不会同步到其他节点上。当坏掉的服务恢复的时候,会自动加入到节点上,也是高可用的一种。然后退出自我保护机制,这也是应对网络异常的一种机制
总结:Zookeeper保证CP,Eureka保证AP;Zookeeper出现网络等故障的时候导致整个服务注册瘫痪太要命了。Eureka能很好的应对网络故障导致失去节点的情况。