标签:inf 运行 service 直接 aws 联系 rgs gap plugin
上图简要描述了Eureka的基本架构,由3个角色组成:
通过spring boot 搭建 Eureka-Server
1.pom文件引入依赖,在SpringBoot(2.0.1)项目的基础上添加以下依赖
<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>Finchley.SR3</spring-cloud.version> </properties> <dependencyManagement> <dependencies> <dependency> <!-- SpringCloud 所有子项目 版本集中管理. 统一所有SpringCloud依赖项目的版本依赖--> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <build> <plugins> <plugin><!-- SpringBoot 项目打jar包的Maven插件 --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2. 配置文件application.yml
server: port: 7001 # eureka注册中心,不会盲目清楚已经注册的服务列表内的任何微服务,这是他的自我保护机制, # 当微服务长时间没有客户端请求,即没有心跳,便会启动自我保护, eureka: instance: #Eureka实例名,集群中根据这里相互识别 hostname: eureka7001.com client: registerWithEureka: false #表示是否注册Eureka服务器,因为自身作为服务注册中心,所以为false fetchRegistry: false #是否从eureka上获取注册信息,因为自身作为服务注册中心,所以为false serviceUrl: #http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #集群版 defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
3. 主启动类注解
@EnableEurekaServer // Eureka服务端注解 @SpringBootApplication public class EurekaServerApp {public static void main(String[] args) { SpringApplication.run(EurekaServerApp.class,args); log.info("服务启动成功"); } }
如上便完成了Eureka-Server的基本配置,接下去创建Service Provider
1.pom文件引入依赖与上面保持一致即可。
2. 配置文件application.yml
server: port: 8001 spring: application: name: cloud-provider #服务注册到Eureka上使用的名称 eureka: client: service-url: # 集群情况下如下,如果是单机版,只需要配置单机版Eureka地址 defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ instance: instance-id: cloud-provider-8001 prefer-ip-address: true #访问路径显示IP地址 info: # 在Eureka上点击服务时会跳转到个404页面,可配置这里让他跳转到服务简介的一个页面,信息如下配置 app.name: wuzz company.name: www.wuzz.com build.artifactId: server-provider build.version: 1.0
3. 主启动类注解
@EnableEurekaClient @SpringBootApplication @EnableDiscoveryClient public class EurekaServerProviderApp { private final static Logger log = LoggerFactory.getLogger(EurekaServerProviderApp.class); public static void main(String[] args) { SpringApplication.run(EurekaServerProviderApp.class,args); log.info("服务启动成功"); } }
如上便完成了Eureka-Server的基本配置,这样Eureka的服务的基本架构也基本完成。这里可以添加一个服务发现的Controller。
@RestController public class TestController { @Autowired//服务发现 private DiscoveryClient client; @GetMapping("/hello") public String helloEureka(){ return "Hello Eureka Provider"; } /** * 服务发现 * @return */ @RequestMapping(value ="/discovery",method= RequestMethod.GET) public Object discovery() { List<String> list = client.getServices(); List<ServiceInstance> instances = client.getInstances(""); for(ServiceInstance instance : instances) { System.out.println(instance.getHost()); } return this.client; } }
下面来说说Eureka的一些基本问题:
众所周知,Eureka在CAP理论当中是属于AP , 也就说当产生网络分区时,Eureka保证系统的可用性,但不保证系统里面数据的一致性, 举个例子。当发生网络分区的时候,Eureka-Server和client端的通信被终止,server端收不到大部分的client的续约,这个时候,如果直接将没有收到心跳的client端自动剔除,那么会将可用的client端剔除,这不符合AP理论,所以Eureka宁可保留也许已经宕机了的client端 , 也不愿意将可以用的client端一起剔除。 从这一点上,也就保证了Eureka程序的健壮性,符合AP理论。
自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。
默认情况下,当eureka server在一定时间内没有收到实例的心跳,便会把该实例从注册表中删除(默认是90秒),但是,如果短时间内丢失大量的实例心跳,便会触发eureka server的自我保护机制,比如在开发测试时,需要频繁地重启微服务实例,但是我们很少会把eureka server一起重启(因为在开发过程中不会修改eureka注册中心),当一分钟内收到的心跳数大量减少时,会触发该保护机制。可以在eureka管理界面看到Renews threshold和Renews(last min),当后者(最后一分钟收到的心跳数)小于前者(心跳阈值)的时候,触发保护机制,会出现红色的警告:
EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY‘RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.
从警告中可以看到,eureka认为虽然收不到实例的心跳,但它认为实例还是健康的,eureka会保护这些实例,不会把它们从注册表中删掉。
该保护机制的目的是避免网络连接故障,在发生网络故障时,微服务和注册中心之间无法正常通信,但服务本身是健康的,不应该注销该服务,如果eureka因网络故障而把微服务误删了,那即使网络恢复了,该微服务也不会重新注册到eureka server了,因为只有在微服务启动的时候才会发起注册请求,后面只会发送心跳和服务列表请求,这样的话,该实例虽然是运行着,但永远不会被其它服务所感知。所以,eureka server在短时间内丢失过多的客户端心跳时,会进入自我保护模式,该模式下,eureka会保护注册表中的信息,不在注销任何微服务,当网络故障恢复后,eureka会自动退出保护模式。自我保护模式可以让集群更加健壮。
但是我们在开发测试阶段,需要频繁地重启发布,如果触发了保护机制,则旧的服务实例没有被删除,这时请求有可能跑到旧的实例中,而该实例已经关闭了,这就导致请求错误,影响开发测试。所以,在开发测试阶段,我们可以把自我保护模式关闭,只需在eureka server配置文件中加上如下配置即可:
eureka.server.enable-self-preservation=false
但在生产环境,不会频繁重启,所以,一定要把自我保护机制打开,否则网络一旦终端,就无法恢复。
当然关于自我保护还有很多个性化配置,这里不详细说明
因此Eureka Server可以很好的应对因网络故障导致部分节点失联的情况,而不会像ZK那样如果有一半不可用的情况会导致整个集群不可用而变成瘫痪
著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。在此Zookeeper保证的是CP, 而Eureka则是AP。
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。
Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中
因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。
情景一
Eureka Client 启动的时候,会主动去全量获取一次注册信息,如果这个时候Eureka Server集群
已经宕机,那么Eureka Client端是不可用的。
情景二
如果Eureka Client 启动时全量获取注册信息成功,在之后的运行过程当中,Eureka Server集群宕机了
那么这个时候,Eureka Client是不受影响的
标签:inf 运行 service 直接 aws 联系 rgs gap plugin
原文地址:https://www.cnblogs.com/wuzhenzhao/p/9466752.html