eureka的高可用
微服务架构中最核心的部分是服务治理,服务治理最基础的组件是注册中心。随着微服务架构的发展,出现了很多微服务架构的解决方案,其中包括我们熟知的Dubbo和Spring Cloud。
关于注册中心的解决方案,dubbo支持了Zookeeper、Redis、Multicast和Simple,官方推荐Zookeeper。Spring Cloud支持了Zookeeper、Consul和Eureka,官方推荐Eureka。
两者之所以推荐不同的实现方式,原因在于组件的特点以及适用场景不同。简单来说:
ZK的设计原则是CP,即强一致性和分区容错性。他保证数据的强一致性,但舍弃了可用性,如果出现网络问题可能会影响ZK的选举,导致ZK注册中心的不可用。
Eureka的设计原则是AP,即可用性和分区容错性。他保证了注册中心的可用性,但舍弃了数据一致性,各节点上的数据有可能是不一致的(会最终一致)。
Eureka采用纯Java实现,除实现了注册中心基本的服务注册和发现之外,极大的满足注册中心的可用性,即使只有一台服务可用,也可以保证注册中心的可用性。
本文将聚焦到Eureka的内部实现原理,先从微服务架构的部署图介绍Eureka的总体架构,然后剖析服务信息的存储结构,最后探究跟服务生命周期相关的服务注册机制、服务续约机制、服务注销机制、服务剔除机制、服务获取机制、和服务同步机制。
Eureka总体架构
组件调用关系
服务提供者
1、启动后,向注册中心发起register请求,注册服务
2、在运行过程中,定时向注册中心发送renew心跳,证明“我还活着”。
3、停止服务提供者,向注册中心发起cancel请求,清空当前服务注册信息。
服务消费者
1、启动后,从注册中心拉取服务注册信息
2、在运行过程中,定时更新服务注册信息。
3、服务消费者发起远程调用:
a> 服务消费者(北京)会从服务注册信息中选择同机房的服务提供者(北京),发起远程调用。只有同机房的服务提供者挂了才会选择其他机房的服务提供者(青岛)。
b> 服务消费者(天津)因为同机房内没有服务提供者,则会按负载均衡算法选择北京或青岛的服务提供者,发起远程调用。
注册中心
1、启动后,从其他节点拉取服务注册信息。
2、运行过程中,定时运行evict任务,剔除没有按时renew的服务(包括非正常停止和网络故障的服务)。
3、运行过程中,接收到的register、renew、cancel请求,都会同步至其他注册中心节点。
这次我们就不讲的那么全面了,先说一下eureka怎么做高可用
建一个父工程
删除掉src目录
POM文件依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<modules>
<module>demo111</module>
<module>myeureka</module>
<module>cloud-consumber8082</module>
<module>myeureka1</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.atnicong</groupId>
<artifactId>springcloud-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-parent</name>
<description>Demo project for Spring Boot</description>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
需要注意的是: springboot的版本和cloud版本有对应关系的这点一定要注意,可以去cloud官网去看看 这里我就不多说了
本次用的是springboot 2.2.2 对应的cloud为H版的
在父工程建一个子工程 myeureka
pom依赖添加:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
application.yml文件
server:
port: 8761
spring:
application:
name: my-eureka
eureka:
instance: #定义Eureka实例
hostname: eureka-server1 #Eureka实例所在的主机名
#eureka默认情况下,把自己当做客户端来注册自己,所以我们要禁用它
client:
register-with-eureka: false #表示是否将自己注册到Eureka Server上,默认为true
fetch-registry: false #表示是否从Eureka Server上获取注册信息,默认为true
service-url:
defaultZone: http://eureka-server:8762/eureka/
然后就是启动类了
package com.nicong.myeureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class MyeurekaApplication {
public static void main(String[] args) {
SpringApplication.run(MyeurekaApplication.class, args);
}
}
就是在我们平常的基础上加了一个
@EnableEurekaServer注解
导入 eureka客户端
另外一个eureka工程:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
server:
port: 8762
spring:
application:
name: myeureka1
eureka:
instance: #定义Eureka实例
hostname: eureka-server #Eureka实例所在的主机名
#eureka默认情况下,把自己当做客户端来注册自己,所以我们要禁用它
client:
register-with-eureka: false #表示是否将自己注册到Eureka Server上,默认为true
fetch-registry: false #表示是否从Eureka Server上获取注册信息,默认为true
service-url:
defaultZone: http://eureka-server1:8761/eureka/
package com.nicong.myeureka1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class eurekaApplication {
public static void main(String[] args) {
SpringApplication.run(eurekaApplication.class);
}
}
到这里我们发现两个工程没有什么区别
唯一的不一样就是yml的配置文件
![](https://img2020.cnblogs.com/blog/2130377/202110/2130377-20211006174921715-1551748429.png)
defaultZone 的url路径 IP和端口号为对方的,如果有多个eureka集群那么这个 url用逗号分隔就可以了
总结起来就是8个字:
相互注册,互相守望
好了就到这里 后面有问题可以交流 qq359073594