Spring Cloud封装了Netflix公司开发的Eureka模块来实现服务治理
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把自己的服务器信息 比如 服务器地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以改别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用。RPC远程调用框架核心思想:在于注册中心,因为注册中心管理每个服务与服务之间的依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
各个微服务节点通过配置启动后,会在Eureka Server中进行注册,这点Eureka Server中的服务注册表将会存储所有可用服务节点的信息,服务节点的信息可以再界面中直观看到。
是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会在服务注册表中将这个服务节点移除(默认90秒)。
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
<dependency>
<groupId>com.radish.springcloudgroupId>
<artifactId>cloud-api-commonsartifactId>
<version>${project.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
dependency>
dependencies>
(3)写YML
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名字
client:
register-with-eureka: false #表识不向注册中心注册自己
fetch-registry: false #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
(4)主启动
@EnableEurekaServer
@SpringBootApplication
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class,args);
}
}
(5)测试
(1)cloud-provider-payment8001
(2)POM
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
(3)写YML
eureka:
client:
register-with-eureka: true
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka
(4)主启动
@EnableEurekaClient
@SpringBootApplication
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args);
}
}
(5)测试
(6)自我保护机制
(1)cloud-consumer-order80
(2)POM
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
(3)写YML
spring:
application:
name: cloud-order-service
eureka:
client:
register-with-eureka: true
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka
(4)主启动
@EnableEurekaClient
@SpringBootApplication
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args);
}
}
(5)测试
微服务RPC远程调用的核心:
高可用,如果注册中心只有一个,一旦出故障便无法挽回。只有搭建Eureka注册中心集群,实现负载均衡和故障容错
要搭建注册中心集群,集群里的注册中心都是互相注册的。
添加两条
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
7001
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名字
client:
register-with-eureka: false #表示不向注册中心注册自己
fetch-registry: false #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7002.com:7002/eureka/ #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
7002
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名字
client:
register-with-eureka: false #表识不向注册中心注册自己
fetch-registry: false #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/ #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
@EnableEurekaServer
@SpringBootApplication
public class EurekaMain7002 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7002.class,args);
}
}
修改80和8001微服务的yml文件
分别测试7001和7002都成功
对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息
@Resource
private DiscoveryClient discoveryClient;
@GetMapping("/payment/discovery")
public Object discovery() {
List<String> services = discoveryClient.getServices();
for (String element : services) {
log.info("******element:" + element);
}
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance : instances) {
log.info(instance.getServiceId() + "\t" + instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri());
}
return this.discoveryClient;
}
@EnableDiscoveryClient
http://localhost:8001/payment/discovery
保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务
如果在EurekaServer首页看到这段提示,则说明Eureka进入了保护模式
为了保证EurekaClient可以正常运行,在与EurekaServer网络不通的情况下,EurekaServer不会立刻将EurekaClient服务剔除。
自我保护模式:
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生(延时、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险——因为微服务本身可能是健康的,因此不能注销这个微服务。Eureka通过自我保护模式来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生网络分区故障),那么这个节点就会进入自我保护模式。
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例
使用eureka.server.enable-self-preservation = false
可以禁用自我保护模式
Eureka客户端向服务端发送心跳的时间间隔,默认30秒
eureka.instance.lease-renewal-interval-in-seconds=30
Eureka服务端在收到最后一次心跳后等待时间上限,默认90秒
eureka.instance.lease-expiration-duration-in-seconds=90