单节点注册中心
服务端-添加maven依赖
1.项目根pom中添加对springcloud及springboot的maven依赖
<properties>
<springcloud.version>Finchley.RELEASE</springcloud.version>
<springboot.version>2.0.3.RELEASE</springboot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${springcloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
关于springboot及springcloud的版本对应,可以参考springcloud官网的说明:
Release Train | Boot Version |
---|---|
Greenwich | 2.1.x |
Finchley | 2.0.x |
Edgware | 1.5.x |
Dalston | 1.5.x |
具体的版本号参考maven仓库:
2.在项目子pom中添加eureka依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
服务端-入口类添加注解
添加@EnableEurekaServer
注解启用服务端
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
服务端-配置
spring.application.name=single-eureka-server
server.port=8761
# springcloud集群中其他机器可以通过hostname加端口访问到对方
eureka.instance.hostname=localhost
# 是否注册到注册中心,这个应用本身就是eureka-server注册中心(默认也是eureka-client),设置为false代表在注册中心不注册自己
eureka.client.register-with-eureka=false
# 是否获取注册中心的信息,这个应用本身就是注册中心,不需要获取注册中心信息
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
各项配置的意思可以查找springcloud官方说明来了解
客户端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class,args);
}
}
spring.application.name=single-eureka-client
server.port=8861
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
注册中心集群搭建
eureka-server集群搭建的思路就是,将每个eureka-server节点注册到集群的其它节点上去,这样客户端注册到任意一个eureka-server上之后,注册信息会在注册中心集群中同步,与单节点相比,仅仅是配置需要修改,以下示例一个3节点的eureka-server集群,每个节点的代码及pom引用同上面的单节点一致,配置如下:
spring.application.name=cluster-eureka-server1
server.port=8761
# springcloud集群中其他机器可以通过hostname加端口访问到对方
eureka.instance.hostname=eureka-server1
# 是否注册到注册中心,这里配置true来注册到集群的其它eureka-server节点上
eureka.client.register-with-eureka=true
# 是否获取注册中心的信息
eureka.client.fetch-registry=true
# 配置eureka-server其它节点的地址,将此节点注册到集群中其它几个节点上
eureka.client.service-url.defaultZone=http://localhost:8762/eureka/,http://localhost:8763/eureka/
# 默认情况下,eureka间隔60s将服务清单中没有续约的服务剔除(默认90s内没有续约),本地测试,关闭保护机制,直接让它实时剔除
eureka.server.enable-self-preservation=false
spring.application.name=cluster-eureka-server2
server.port=8762
# springcloud集群中其他机器可以通过hostname加端口访问到对方
eureka.instance.hostname=eureka-server2
# 是否注册到注册中心,这里配置true来注册到集群的其它eureka-server节点上
eureka.client.register-with-eureka=true
# 是否获取注册中心的信息
eureka.client.fetch-registry=true
# 配置eureka-server其它节点的地址,将此节点注册到集群中其它几个节点上
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/,http://localhost:8763/eureka/
# 默认情况下,eureka间隔60s将服务清单中没有续约的服务剔除(默认90s内没有续约),本地测试,关闭保护机制,直接让它实时剔除
eureka.server.enable-self-preservation=false
spring.application.name=cluster-eureka-server3
server.port=8763
# springcloud集群中其他机器可以通过hostname加端口访问到对方
eureka.instance.hostname=eureka-server3
# 是否注册到注册中心,这里配置true来注册到集群的其它eureka-server节点上
eureka.client.register-with-eureka=true
# 是否获取注册中心的信息
eureka.client.fetch-registry=true
# 配置eureka-server其它节点的地址,将此节点注册到集群中其它几个节点上
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/,http://localhost:8762/eureka/
# 默认情况下,eureka间隔60s将服务清单中没有续约的服务剔除(默认90s内没有续约),本地测试,关闭保护机制,直接让它实时剔除
eureka.server.enable-self-preservation=false
客户端的代码同样和单节点示例代码一样,配置中的注册中心地址需要将eureka-server集群的3个节点全部配上:
spring.application.name=cluster-eureka-client1
server.port=8861
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
集群原理
- eureka客户端与eureka服务器默认保持30s的心跳,重新续约服务
集群保护机制
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 即会进入自我保护机制。
Eureka Server 进入自我保护机制,会出现以下几种情况:
- Eureka 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
- Eureka 仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
- 当网络稳定时,当前实例新的注册信息会被同步到其它节点中
集群二级缓存机制
- 为什么要有二级缓存?为什么不直接用ConcurrentHashMap?
如果集群数量非常大,直接用ConcurrentHashMap肯定性能受到影响,通过缓存的方式来解决这个问题,缓存使用读写分离机制,性能更佳。
问题
- 心跳机制是如何实现的?
开源注册中心对比
服务的注册与发现(Consul、zookeeper、etcd、eureka、Nacos)
参考
***拜托!面试请不要再问我Spring Cloud底层原理!
Finchley.RELEASE documentation