Eureka服务注册与发现
Eureka介绍及原理
理解
==Eureka就像一个物业管理公司,其他微服务就像小区的住户,每个住户入住时都要向物业管理公司注册,并定时向物业公司交管理费==
介绍
- Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
- Eureka主管服务注册与发现,在微服务中,以后了这两者,只需要使用服务的标识符(==就是那个在每个服务的yml文件中取得服务名称==),就可以访问到服务,不需要修改服务调用的配置文件
- Eureka遵循AP原则(高可用,分区容错性),因为使用了自我保护机制所以保证了高可用
原理
- Eureka使用的是C-S结构(客户端-服务端)
- 两大组件:Eureka Server(提供注册服务)、 Eureka Client(JAVA客户端,负责发送心跳)
- 系统中的其他微服务使用Eureka客户端连接到Eureka服务端维持心跳连接(即注册)。SpringCloud的其他模块可以通过Eureka Server 来发现系统中的微服务并加以调用
Eureka服务注册中心构建
加入服务端依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency>
配置yml
- ==理解:物业公司肯定不向自己注册自己,并肯定知道自己在哪,不用参加检索==
server: port: 7001 eureka: instance: hostname: localhost client: register-with-eureka: false #false表示不向注册中心注册自己 fetch-registry: false #false表示自己就是注册中心,职责是维护实例,不参加检索 service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置eureka server的交互地址,即对外暴露的地址
添加启动类
- ==注意:要在类前加@EnableEurekaServer标注==
package com.XXX; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class Eureka7001_APP { public static void main(String[] args) { SpringApplication.run(Eureka7001_APP.class,args); } }
验证是否构建成功
启动主程序,访问该服务地址即可
向Eureka注册中心注册微服务
增加依赖
在要注册的微服务的pom.xml文件中增加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
修改yml
- 在application.yml中增加以内容,将客户端注册到服务列表内
- ==理解:小区用户要找到物业管理处的地址进行注册==
eureka: client: service-url: defaultZone: http://localhost:7001/eureka
主启动类增加注解
- 增加@EnableEurekaClient注解
@SpringBootApplication @EnableEurekaClient public class Provider8001_APP { public static void main(String[] args) { SpringApplication.run(Provider8001_APP.class,args); } }
actuator与微服务注册完善
主机名称与服务名称的修改
- 修改服务名称,在yml中eureka节点下添加如下内容
eureka: instance: instance-id: dept8001 #修改别名 prefer-ip-address: true #显示IP地址
info内容的详细信息修改
作用
在查看Eureka时点击进入某个微服务的info时,能给查看者一些必要的信息,可以帮助查看者快速的了解该微服务,开发中十分有意义。
修改方法
- ==当前工程==添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
- ==总的父工程==的build节点下添加如下内容
<build> <finalName>microservicecloud</finalName> <resources> <resource> <!--允许扫描该路径下的资源文件--> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <delimiters> <!--指定动态获取以$标志开头结尾的信息--> <delimit>$</delimit> </delimiters> </configuration> </plugin> </plugins> </build>
- 在==当前工程== 的application.yml文件添加回显信息
info: author: XXX build-version: $project.version$
Eureka的自我保护
介绍
Eureka的自我保护机制主要是为了网络异常时保持高可用设计的,当在Eureka中注册的微服务超过设定是时间内(默认90秒)没有向Eureka服务端发送心跳,该微服务会进入自我保护模式。在自我保护模式中,Eureka会保护服务注册表中的信息,不会注销任何服务实例,直至收到的心跳数恢复至阈值以上,该微服务退出自我保护模式。
理解
好死不如赖活:Eureka的设计哲学是宁可保留错误的服务信息,也不盲目注销可能健康的服务。所以异常的服务不会被注销,而是进入了自我保护模式。
自我保护模式的开关
在Eureka Server模块下的yml文件中添加配置信息即可,true表示打开自我保护模式;false表示关闭自我保护模式(不推荐)
server: enable-self-preservation: false
Eureka的服务发现
介绍
系统中的微服务可以通过Eureka的服务发现去获得在Eureka中注册的服务的信息,这是一个对外暴露的接口。
使用方法(provider中)
- 注入DiscoveryClient 对象(spring包下的),在controller方法中获取
@Autowired private DiscoveryClient discoveryClient; @ResponseBody @GetMapping("/provider/discovery") public Object discovery(){ List<String> list = discoveryClient.getServices(); System.out.println(list); List<ServiceInstance> insList = discoveryClient.getInstances("MICROSERVICECLOUD-DEPT"); for (ServiceInstance si:insList) { System.out.println(si.getHost() +"," + si.getServiceId() +"," +si.getPort() +"," +si.getUri() +"," +si.getMetadata()); } return this.discoveryClient; }
- 在主启动类中加入@EnableDiscoveryClient注解
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient public class Provider8001_APP { public static void main(String[] args) { SpringApplication.run(Provider8001_APP.class,args); } }
使用方法(consumer中)
在controller方法中使用restTemplate对象调用provider中暴露的URL 并获得返回对象即可
@GetMapping("/discovery") public Object discovery() { return restTemplate.getForObject(URL_PREFIX+"/provider/discovery",Object.class); }
Eureka的集群配置
集群
集群就是在不同的机器上配置相同的服务来构建要一个大的运算整体
实现集群
- 新建N个Eureka Server模块
- 每个模块的pom.xml中加入与单个Eureka Server相同的依赖
- 每个模块加入主程序(记得加@EnableEurekaServer注解)
- 修改hosts文件(Win7的路径是C:\Windows\System32\drivers\etc)
127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com 127.0.0.1 eureka7003.com
- 修改Eureka Server模块的application.yml文件,加入集群,主要修改两个地方:
- hostname:修改为hosts文件中映射的地址
- service-url下的defaultZone节点:填入集群中另外的server服务端的地址
server: port: 7001 eureka: instance: hostname: eureka7001.com #hostname为hosts文件中映射的地址 client: register-with-eureka: false #false表示不向注册中心注册自己 fetch-registry: false #false表示自己就是注册中心,职责是维护实例,不参加检索 service-url: #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置eureka server的交互地址 defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #其他两个服务端的地址
- 修改Eureka Client模块的application.yml文件,使其向集群注册服务
- service-url下的defaultZone节点:填入集群中需要向其注册server服务端的地址
eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
- 访问地址
http://eureka7001.com:7001 http://eureka7002.com:7002 http://eureka7003.com:7003
- ==注:defaultZone中eureka/后缀是必须的,如果删除,Server类不会报错,但是Client注册时会报404错误==
Eureka与Zookeeper对比
CAP设计原则不同
Eureka遵守AP,Zookeeper遵守CP(C:强一致性,A:高可用,P:分区容错性,三者只能选其二,高并发下P必选)
网络波动下两者的处理对比
Zookeeper | Eureka |
---|---|
当网络出现故障时,剩余zk集群会发起投票选举新的leader,但是此过程会持续30~120s,此过程对于高并发来说十分漫长,会导致整个注册服务的瘫痪,这是不可容忍的 | 在15分钟内85%的节点都没有心跳,则注册中心 会认为客户端与之出现了网络故障,则会进入自动保护模式。1.Eureka不会移除没有收到心跳的服务;2.新的服务仍能在服务端注册,但是暂时不会被同步到其他节点上直到网络稳定 |
结论
Eureka可以很好的应对网络故障导致部分节点失去连接的情况,而不会像zookeeper那样导致整个注册服务系统的瘫痪。