1.1 服务注册与发现(Eureka)
1.1.1 什么是Eureka
Eureka是Netflix的一个子模块,也是核心模块之一,Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移,服务注册与发现对于微服务来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符就可以访问服务,不需要修改服务调用的配置文件,类似于dubbo的注册中心,如zookeeper;
1.1.2 Dubbo与Eureka实现原理
1.1.2.1 Dubbo基础框架
1.1.2.2 Eureka的基础框架
l 实现原理:
1、 SpringCloud封装了NetFlix公司开发的Eureka模块来实现服务注册和发现(对照zookeeper)
2、 Eureka采用了C-S的架构设计,EurekaServer作为服务注册功能的服务器,是服务注册中心
3、 而系统中的其他微服务,使用Eureka的客户端连接到EurekaServer并维持心跳连接,这样系统的维护人员就可以通过EurekaServer来监控系统中个人微服务是否运行,SpringCloud的一些其他模块(如Zuul)就可以通过EurekaServer来发现系统中的其他服务,并执行相关的逻辑。
4、 Eureka包含两个组件,Eureka Server和Eureka Client
5、 Eureka Server提供服务注册服务,各个节点启动后,会在EurekaServer中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点信息可以在界面中看到。
6、 Eureka Client是一个Java客户端,用于简化EurekaServer的交互,客户端同时也具备一个内置使用轮询负载算法的负载均衡,在应用启动后,将会向EurekaServer发送心跳(默认周期为30秒),如果Eureka Server在多个心跳周期没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除掉(默认周期90秒)
l 三大角色
Eureka Server:提供服务的注册与发现。--->(zookeeper)
Service Provider:将自身服务注册到Eureka中,从而使消费方能够找到。
Service Consumer:服务消费方从Eureka中获取注册服务列表,从而找到消费服务。
1.1.2.3 构建一个Eureka模块
1、 构建模块
2、 引用依赖
3、 修改配置文件
4、 配置启动类(开启服务)
1.1.2.4 构建模块
构建一个springcloud-eureka-7001,步骤和上面一样
1.1.2.5 引用依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!--热部署工具包(不需要重启项目)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
1.1.2.6 修改配置
server:
port: 7001
#Eureka配置
eureka:
instance:
hostname: localhost
client:
#是否向eureka注册中心注册自己(这里是服务端不用注册自己)
register-with-eureka: false
#如果为false表示自己是注册中心
fetch-registry: false
#监控页面
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
1.1.2.6.1 配置启动类(启动服务)
@SpringBootApplication
@EnableEurekaServer //eureka服务端启动类,接收其他服务注册进来
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class, args);
}
}
说明:核心注解引入@EnableEurekaServer
1.1.2.6.1.1.1.1 启动服务访问页面
页面中可以看到没有注册的服务,下面可以注册服务了。
1.1.2.6.1.1.1.2 注册服务
1、在其他模块或者其他项目加上eureka引用包,这里我们用springcloud-provider-dept-8001的模块引入:
a、pom中引入依赖包:
<!--引用eureka 注册-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
b、application.yml配置文件引入:
#eureka配置,服务注册到注册中心
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
c、启动类中添加核心注解@EnableEurekaClient:
@SpringBootApplication
@EnableEurekaClient //加上这个核心注解就会自动注册到eureka中
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class, args);
}
}
d、启动服务:
可以看到8001服务注册进来了。
e、优化显示状态
加上:
instance:
#修改服务状态的默认描述信息
instance-id: springcloud-provider-dept8001
再去访问页面:
f、优化显示info信息
<!--完善eureka监控信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置文件加上:
#info配置
info:
app.name: springcloud
company.name: mycompany.com
重启访问:
1.1.2.6.2 实现服务发现机制
a、启动类增加核心注解@EnableDiscoveryClient:
@SpringBootApplication
@EnableEurekaClient //加上这个核心注解就会自动注册到eureka中
@EnableDiscoveryClient //服务发现
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class, args);
}
}
b、新增一个服务接口(通过discovery获取服务信息)
@Autowired
private DiscoveryClient discoveryClient;
/**
* 获取微服务列表注册后的消息清单
*
* @return
*/
@GetMapping(value = "/dept/discovery")
public Object discovery(){
List<String> services = discoveryClient.getServices();
log.info("the discovery is services={}", services);
//获取微服务信息,通过微服务idapplicationName
List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
instances.forEach(obj ->{
System.out.println(
obj.getHost() + "\n" +
obj.getPort() + "\n" +
obj.getUri() + "\n" +
obj.getServiceId() + "\n"
);
});
return this.discoveryClient;
}
c、访问接口
1.1.2.6.3 Eureka集群搭建
1、将配置的springcloud-eureka-7001单机注册服务复制三份,分别创建三个模块,如:
springcloud-eureka-7002、springcloud-eureka-7002、springcloud-eureka-7003,如下图:
1、 修改对应的端口,如:7001、7002、7003
eureka配置为了将hostname: localhost中的localhost区分出来,可以在本地host文件配置一下,以区分不同的注册服务中心,如
2、 修改集群配置
3、 集群实现原理
7001服务关联7002和7003服务,7002服务关联7001和7003服务,7003则关联7001和7002服务;以保证任何一台注册服务挂掉后而不受影响
4、 注册服务提供者配置修改:
5、 启动服务可以看到相互挂载的服务
6、 启动springcloud-provider-dept-8001服务,可以看到三个集群注册中心都注册了这个服务:
9、关掉其中任意一个服务都不会正常影响服务的运营,这里需要说明一下的是,eureka在服务关闭或者挂掉后由于eureka的保护机制,服务挂掉后并不会将注册的服务给注销移除掉,依旧会对服务进行保护,当服务再次起来后,可以继续使用;
1.1.2.6.4 Eureka与zookeeper
1.1.2.6.4.1.1.1 CAP原则
1、 ACID是什么:
A(Atomicity) 原子性
C(Consistency) 一致性
I(Isolation) 隔离性
D(Durability) 持久性
2、 CAP是什么:
C(Consistency) 一致性
A(Availability) 可用性
P(Partition tolerance) 分区容错性
3、 CAP核心理论
a、 一个分布式系统不可能同时满足一致性、可用性、分区容错性三个需求,三者不可兼得;
b、 根据CAP原理,将NoSQL数据库分成满足CA原则、CP原则、AP原则三大类:
CA:单点集群,满足一致性、可用性,通常可扩展性较差;
CP:满足一致性、分区容错性的系统,通常性能不是特别高;
AP:满足可用性、分区容错性系统,通常对一致性要求低些;
1.1.2.6.4.1.1.2 Eureka与zookeeper对比
1、 Zookeeper保证的是CP原则:
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性,但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举,问题在于选举leader的时间太长,一般在30-120s,且选举期间整个zk集群是不可用的,这样导致在选举期间注册服务瘫痪,在云部署的环境下,因为网络问题使得zk集群失去master节点是较大概率会发生的事件,虽然服务最终能修复,但是漫长的选举时间导致注册长期不可用时不能容忍的。
2、 Eureka保证的是AP原则:
Eureka看明白了这一点,因为在设计时就优先保证可用性,Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务,而Eureka的客户端在向某个Eureka注册时,如果发现连接失败,则会自动切换至其他节点,只要有一台Eureka还在,就能保住注册服务的可用性,只不过查到的信息可能不是最新的,除此之外,Eureka还在一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
1、 Eureka不再从注册列表中移除因为长时间没有收到心跳而应该过期的服务:
2、 Eureka仍然能够接受新服务的注册与查询请求,但是不会被同步到其他节点上(即保证当前节点依然可用)
3、 当网络稳定时,当前实例新的注册信息会被同步到其他节点中;
所以,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不像zookeeper那样使整个注册服务瘫痪。
本文暂时没有评论,来添加一个吧(●'◡'●)