Eureka原理和CAP原理

1 Eureka

1.1 什么是Eureka注册中心

EurekaNetflix开发的服务发现组件, 本身是一个基于 REST的服务。
Spring Cloud将它集成在其子项目 spring-cloud-netflix 中, 以实现 Spring Cloud 的服务注册于发现, 同时还提供了负载均衡故障转移等能力。

1.2 Eureka注册中心三种角色

1.2.1 Eureka Server

通过 Register、 Get、 Renew等接口提供服务的注册和发现。

1.2.2 Application Service (Service Provider)

服务提供方:把自身的服务实例注册到 Eureka Server

1.2.3 Application Client (Service Consumer)

服务调用方:通过 Eureka Server 获取服务列表, 消费服务

1.3 原理图

在这里插入图片描述
Register(服务注册): 把自己的 IP 和端口注册给 Eureka
Renew(服务续约): 发送心跳包, 每 30 秒发送一次。 告诉 Eureka 自己还活着。
Cancel(服务下线): 当 provider 关闭时会向 Eureka发送消息, 把自己从服务列表中删除。 防止 consumer 调用到不存在的服务。
Get Registry(获取服务注册列表): 获取其他服务列表。
Replicate(集群中数据同步)eureka集群中的数据复制与同步。
Make Remote Call(远程调用): 完成服务的远程调用。

2 CAP

2.1 什么是CAP原则

CAP原则又称CAP定理, 指的是在一个分布式系统中, Consistency(一致性) 、Availability(可用性) 、 Partition tolerance(分区容错性) , 三者不可兼得。

原则分类 详解
C
数据一致性(Consistency)
也叫做数据原子性系统在执行某项操作后仍然处于一致的状态。 在分布式系统中, 更新操作执行成功后所有的用户都应该读到最新的值,这样的系统被认为是具有强一致性的。 等同于所有节点访问同一份最新的数据副本
A
服务可用性(Availablity)
每一个操作总是能够在一定的时间内返回结果, 这里需要注意的是一定时间内返回结果。 一定时间内指的是,在可以容忍的范围内返回结果, 结果可以是成功或者是失败
P
分区容错性(Partition-torlerance)
在网络分区的情况下, 被分隔的节点仍能正常对外提供服务(分布式集群, 数据被分布存储在不同的服务器上, 无论什么情况, 服务器都能正常被访问)

2.2 如何舍弃

定律: 任何分布式系统只可同时满足二点,没法三者兼顾

三者择其二 分析
CA, 放弃 P 如果想避免分区容错性问题的发生, 一种做法是将所有的数据(与事务相关的)都放在一台机器上。 虽然无法 100%保证系统不会出错, 单不会碰到由分区带来的负面效果。 当然这个选择会严重的影响系统的扩展性
CP, 放弃 A 相对于放弃"分区容错性"来说, 其反面就是放弃可用性。一旦遇到分区容错故障, 那么受到影响的服务需要等待一定时间, 因此在等待时间内系统无法对外提供服务
AP, 放弃 C 这里所说的放弃一致性, 并不是完全放弃数据一致性,而是放弃数据的强一致性, 而保留数据的最终一致性。 以网络购物为例, 对只剩下一件库存的商品, 如果同时接受了两个订单, 那么较晚的订单将被告知商品告罄

2.3 eureka与zookeeper区别

对比项 Zookeeper Eureka
CAP CP AP
Dubbo 集成 已支持 -
Spring Cloud 集成 已支持 已支持
kv 服务 支持 - ZK 支持数据存储,eureka不支持
使用接口(多语言能力) 提供客户端 http 多语言 ZK的跨语言支持比较弱
watch 支持 支持 支持 什么是Watch 支持?就是客户单监听服务端的变化情况。zk 通过订阅监听来实现eureka 通过轮询的方式来实现
集群监控 - metrics metrics,运维者可以收集并报警这些度量信息达到监控目的

3 eureka优雅停服

3.1 Eureka自我保护

3.1.1 自我保护的条件

一般情况下, 微服务在Eureka上注册后, 会每30秒发送心跳包,Eureka通过心跳来判断服务是否健康, 同时会定期删除超过90秒没有发送心跳服务。

3.1.2 Eureka Server收不到微服务的心跳

  • 是微服务自身的原因
  • 是微服务与 Eureka 之间的网络故障,通常(微服务的自身的故障关闭)只会导致个别服务出现故障, 一般不会出现大面积故障, 而(网络故障)通常会导致Eureka Server在短时间内无法收到大批心跳。
    考虑到这个区别,Eureka设置了一个阀值, 当判断挂掉的服务的数量超过阀值时,Eureka Server 认为很大程度上出现了网络故障, 将不再删除心跳过期的服务。

3.1.3 eureka阀值

  • 15 分钟之内是否低于85%
  • Eureka Server 在运行期间,会统计心跳失败的比例在 15 分钟内是否低于 85%这种算法叫做 Eureka Server 的自我保护模式

3.2 为什么需要eureka自我保护

  • 因为同时保留好数据坏数据总比丢掉任何数据要更好, 当网络故障恢复后,这个 Eureka节点会退出自我保护模式
  • Eureka还有客户端缓存功能(也就是微服务的缓存功能)。 即便 Eureka 集群中所有节点都宕机失效, 微服务的 ProviderConsumer都能正常通信。
  • 微服务的负载均衡策略会自动剔除死亡的微服务节点

3.3 关闭自我保护

修改 Eureka Server 配置文件

#关闭自我保护:true 为开启自我保护, false 为关闭自我保护
eureka.server.enableSelfPreservation=false
#清理间隔(从服务列表删除无用服务的时间间隔,单位:毫秒, 默认是 60*1000)
eureka.server.eviction.interval-timer-in-ms=60000

3.4 优雅停服

环境:springboot:2.1.3 springcloud:Greenwich.SR5

3.4.1 不需要在Eureka Server中配置关闭自我保护

3.4.2 添加actator的坐标依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

3.4.3 修改properties文件

###### 优雅停服######
##启用 shutdown
management.endpoint.shutdown.enabled=true
# 暴露所有端点
management.endpoints.web.exposure.include=*
#禁用密码验证
management.endpoints.shutdown.sensitive=false

3.4.4 发送关闭服务的URL请求

post请求

public static String doPost(String url,Map<String,String> param)  {
		//创建HTTPClient对象
		CloseableHttpClient httpClient = HttpClients.createDefault();
		String resultString = "";
		CloseableHttpResponse response = null;
		try{
			//创建httpget请求
			HttpPost httpPost = new HttpPost(url);
			if(MapUtils.isNotEmpty(param)) {
				List<NameValuePair> paramList= new ArrayList<>();
				param.forEach((a,b)->paramList.add(new BasicNameValuePair(a,b)));
				//模拟表单
				UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(paramList,"utf-8");
				//UrlEncodedFormEntity 来设置 body,消息体内容类似于“KEY1=VALUE1&KEY2=VALUE2&...
				httpPost.setEntity(formEntity);
			}
			//执行请求
			response = httpClient.execute(httpPost);
			if(response.getStatusLine().getStatusCode()==200) {
				System.out.println("========成功========");
				resultString = EntityUtils.toString(response.getEntity(),"utf-8");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				if(response!=null)response.close();
				httpClient.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return resultString;
	}

main方法发送

public static void main(String[] args) throws Exception {
		String url ="http://127.0.0.1:9080/actuator/shutdown";
		//该 url 必须要使用 dopost 方式来发送
		HttpClientUtil.doPost(url,null);
	}

main方法发送后,就可以在本地看到启动的服务自己就关闭了,也可以在服务注册管理页面查看

4 eureka的安全认证

4.1 在Eureka Server中添加 security 包

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

4.2 修改Eureka Server配置文件

#开启 http basic 的安全认证 没有用 需要通过下面方法来关闭或开启
#spring.security.basic.enabled=true
spring.security.user.name=user
spring.security.user.password=123456
 # 修改访问集群节点的 url
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka2:8761/eureka/

4.3 修改微服务的配置文件添加访问注册中心的用户名与密码

spring.application.name=eureka-provider
server.port=9090
#设置服务注册中心地址, 指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
#启用 shutdown
management.endpoints.shutdown.enabled=true
#禁用密码验证
management.endpoints.shutdown.sensitive=false

4.4 关闭csrf认证

Spring Cloud 2.0 以上的security默认启用了csrf检验,要在eurekaServer端配置securitycsrf检验为false

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable(); //关闭csrf
        //开启认证  若注释掉,就关闭认证了
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); 
    }
}
发布了334 篇原创文章 · 获赞 186 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/u012060033/article/details/104362583
今日推荐