EureKa在Spring Cloud全家桶中担任着服务的注册与发现的落地实现。Netflix在设计EureKa时遵循着AP原则,它基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移,功能类似于Dubbo的注册中心Zookeeper。
EureKa采用C-S的设计架构,即包括了Eureka Server(服务端),EureKa client(客户端)。
1.EureKa Server 提供服务注册,各个节点启动后,在EureKa server中进行注册;
2 EureKa Client是一个Java客户端,用于和服务端进行交互,同时客户端也是一个内置的默认使用轮询负载均衡算法的负载均衡器。在应用启动后,会向Eueka Server发送心跳(默认30秒)。如果EUR额卡 Server在多个心跳周期内没有接受到某个节点的心跳,EureKaServer将会从服务注册表中将这个服务移出(默认90秒)。
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
server:
port: 7001
eureka:
instance:
hostname: localhost 单机
# hostname: eureka7001.com #eureka服务端的实例名称 集群版使用名称区分
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#集群指向其它eureka
#defaultZone: http://eureka7002.com:7002/eureka/
#单机就是7001自己
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#server:
#关闭自我保护机制,保证不可用服务被及时踢除
#enable-self-preservation: false
#eviction-interval-timer-in-ms: 2000
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args)
{
SpringApplication.run(EurekaMain7001.class,args);
}
}
@EnableEurekaServer表示开启eureka服务端
集群配置就是将上面的配置中的集群相关注释打开,将单机配置注释
hostname: eureka7001.com #eureka服务端的实例名称 集群版使用名称区分
defaultZone: http://eureka7002.com:7002/eureka/
hostname解释:我们可以对比下单机版的配置,单机版时我们的配置是localhost,也就是127.0.0.1,此处配置的服务端的ip。那么集群版配的eureka7001.com又是什么呢?
由于我这现在是在一台机器上通过开放多个端口来模拟eureka集群,那么很显然如果我直接在hostname处使用localhost,那么就很容易引起混淆,傻傻分不清,所以我们可以给其取一个唯一的名称。
更改hosts文件将名称与ip进行映射(hosts文件地址:C:\Windows\System32\drivers\etc)
因为集群互相注册,相互守望的(解释下:假如有两台服务器7001和7002,那么7001主机中注册了7002主机,7002注册了7001;如果有多台,那么就需要将除自己外的兄弟主机注册进来),者也就有了defaultZone这个配置。
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
server:
port: 80
spring:
application:
name: cloud-order-service #服务名称
eureka:
client:
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#单机
#defaultZone: http://localhost:7001/eureka
# 集群
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ # 集群版
@SpringBootApplication
@EnableEurekaClient
public class OrderMain80
{
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class, args);
}
}
@EnableEurekaClient和@EnableDiscoveryClient
在使用服务发现的时候需要使用到上述的两种注解,@EnableEurekaClient更倾向于在使用Eureka做服务中心时,@EnableDiscoveryClient则是在使用其他如zookeeper,consul时。
注意:如果当前模块是服务调用者,我们需要将RestTemplate注入spring容器中(Eureka是基于rest的服务,服务与服务之间的额调用需要通过RestTemplate),因为Eureka本身就自带Ribbon,而我们如果希望使用Ribbon默认的负载均衡算法(轮询)的时候,可以在注入RestTemplate时使用
@LoadBalanced标注。
@Configuration
public class Config {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
配置时遇到的小坑:
当进行集群配置的时候,defaultZone的几个服务地址之间不要留空格,否则会报错如下:
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务的心跳,EurekaServer将会注销该实例(默认是90秒)。但是当网络分区发生故障(延时,卡顿,拥挤)时,微服务与EurekaServer之间的通信无法正常进行,以上的行为可能就非常危险了—因为微服务本身是健康的,此时本不应该注销这个微服务。Euerka通过“自我保护模式”来解决这个问题—当EuerkaServer节点在短时间内丢失过多的客户端是(可能发生网络分区故障),那么这个节点就会进入自我保护模式。
属于CAP中的AP。
如果在Eureka Server首页看到以下这段提示,则说明Eureka进入了自我保护模式
eureka:
server:
enable-self-preservation: true #开启保护模式,默认开启
instance:
lease-renewal-interval-in-seconds: 30 # Eureka客户端向服务端发送心跳的时间间隔(单位秒)
lease-expiration-duration-in-seconds: 90 #Eureka服务端在收到最后一次心跳后等待时间上限 ,单位为秒(默认是90秒),超时剔除服务