项目中遇到的问题总结(二)

CAP理论

CAP理论是分布式系统中非常重要的理论,它指出,在分布式系统中,最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)这三个特性中的两个,无法同时满足三个特性。

具体来说,CAP理论解释了在分布式系统中,由于网络分区、机器故障等因素,分布式系统中的不同节点可能处于不同的状态,因此在设计分布式系统时需要考虑如何处理这些状态。CAP理论提出了三个特性,分别是一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance):

  1. 一致性(Consistency):在分布式系统中,所有节点之间的数据保持一致,即任何时刻所有节点的数据都是相同的。

  2. 可用性(Availability):在分布式系统中,任何时刻都可以访问所有节点的数据,即系统具有高可用性,不会因为某些节点故障而无法使用。

  3. 分区容错性(Partition Tolerance):在分布式系统中,即使网络分区或者机器故障等因素导致节点之间无法通信,系统仍然可以继续运行。一个分布式系统里面,节点组成的网络本来应该是连通的。然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域。数据就散布在了这些不连通的区域中。这就叫分区。

CAP理论指出,在分布式系统中,最多只能同时满足其中的两个特性,无法同时满足三个特性。这是因为当一个节点发生故障或者网络分区时,系统需要在一致性和可用性之间做出取舍。如果选择保证一致性,那么就必须停止服务,等待故障恢复或者网络连接恢复后才能继续提供服务,从而降低了系统的可用性;如果选择保证可用性,那么就必须放弃一致性,容忍节点之间的数据不一致,从而降低了系统的一致性。

在实际的分布式系统中,需要根据实际需求来选择CAP理论中的两个特性,并进行权衡。例如,对于金融系统等对一致性要求非常高的系统来说,可以选择保证一致性和分区容错性,从而牺牲可用性。而对于大规模互联网应用来说,可以选择保证可用性和分区容错性,从而容忍节点之间的数据不一致。

Nacos中保证的是CP还是AP

Nacos既支持CP模式,也支持AP模式,可以根据实际需求进行配置。

在Nacos中,通过配置nacos.core.cluster.switch参数来选择使用CP模式还是AP模式。如果将该参数设置为nacos,则使用AP模式;如果将该参数设置为raft,则使用CP模式。

具体来说,Nacos的AP模式是指,即使出现网络分区或者节点故障等情况,仍然可以继续提供服务,保证了系统的可用性。而Nacos的CP模式是指,保证了数据一致性和分区容错性,可以满足金融等对数据一致性要求比较高的场景。

举个例子,如果我们的应用对数据一致性有较高的要求,比如金融领域的资金交易系统,那么我们可以将Nacos配置为CP模式。在CP模式下,Nacos会将所有的数据同步到所有的节点上,保证了数据的一致性,但是在节点故障或者网络分区时,可能会导致系统的可用性降低。为了保证高可用性,可以使用多个节点进行部署,通过负载均衡来实现高可用性。

如果我们的应用对数据一致性要求不高,比如互联网应用,那么我们可以将Nacos配置为AP模式。在AP模式下,Nacos可以容忍节点之间的数据不一致,保证了系统的可用性。但是在节点故障或者网络分区时,可能会导致不同节点之间的数据不一致,需要应用程序自己处理。

例如,以下是一个使用AP模式的Nacos配置文件示例:

# 使用AP模式
nacos.core.cluster.switch=nacos

在上述配置中,将nacos.core.cluster.switch参数设置为nacos,就可以使用AP模式了。如果要使用CP模式,只需要将该参数设置为raft即可。

这个配置是在哪里配置

这个配置可以在Nacos的配置文件中进行设置。具体来说,可以在conf/application.properties文件中设置该参数的值,从而选择使用CP模式还是AP模式。

例如,如果要将Nacos配置为CP模式,可以在conf/application.properties文件中添加如下配置:

# 使用CP模式
nacos.core.cluster.switch=raft

如果要将Nacos配置为AP模式,可以在conf/application.properties文件中添加如下配置:

# 使用AP模式
nacos.core.cluster.switch=nacos

需要注意的是,在修改Nacos的配置文件之后,需要重启Nacos才能生效。另外,为了避免配置文件被误修改或篡改,建议在生产环境中使用安全的配置管理工具来管理Nacos的配置文件。

Nacos 默认使用 AP 还是 CP

Nacos默认使用的是AP模式。当然,用户可以根据实际需求进行配置,将Nacos配置为CP模式或者AP模式。在默认情况下,Nacos默认使用AP模式,即nacos.core.cluster.switch参数默认值为nacos。

AP模式下,Nacos集群中的各个节点之间通过异步通信来保持数据的最终一致性。这种模式下,如果节点之间出现网络分区,一些节点可能会发生数据不一致的情况,但是Nacos会优先保证服务的可用性,因此该模式适合于互联网应用等对数据一致性要求不高的场景。

CP模式下,Nacos集群中的各个节点之间通过一致性协议来保证数据的一致性。这种模式下,如果节点之间出现网络分区,一些节点可能会被暂时禁用,以保证数据的一致性,但是也会导致一些服务不可用。因此,该模式适合于对数据一致性要求比较高的场景,比如金融领域的应用。

这里是指的 Nacos 集群的 AP 和 CP 吗

是的,这里所说的Nacos默认使用AP模式是指Nacos集群的AP模式,默认情况下使用的是异步通信来保持数据的最终一致性。而如果将Nacos配置为CP模式,则会使用一致性协议来保证数据的一致性。Nacos的AP和CP模式都是针对Nacos集群的,而不是针对单个实例的。在Nacos集群中,所有的实例都应该使用相同的模式,才能保证数据的一致性和集群的正确运行。

你觉得注册中心应该是CP还是AP?

我觉得大部分情况下,注册中心应该是AP,如果注册中心是CP的,那么表示,当我们向注册中心注册实例或移除实例时,都要等待注册中心集群中的数据达到一致后,才算注册或移除成功,而这是比较耗时的,随着业务应用规模的增大,应用频繁的上下线,那么就会导致注册中心的压力比较大,会影响到服务发现的效率以及服务调用了,而如果注册中心是AP的,那么注册中心集群不管出现了什么情况,都是可以提供服务的,就算集群节点之间数据出现了不一致,对于业务应用而言,可能拉取到了一个已经下线了的服务节点,但是现在一般的微服务框架或组件都提供了服务容错和重试功能,也可以避免这个问题,而如果是AP,对于注册中心而言就不需要消耗太多的资源来实时的保证数据一致性了,保证最终一致性就可以了,这样注册中心的压力会小一点,另外像Zookeeper来作为注册中心,因为Zookeeper保证的就是CP,但是如果集群中如果大多数节点挂掉了,就算还剩下一些Zookeeper节点,这些节点也是不能提供服务的,所以这个也不太合适,所以综合来看,注册中心应该保证AP会更好,就像Euraka、Nacos他们默认保证的就是AP。

总结:AP,大部分情况下不会要求数据严格一致性,保证最终一致性即可(异步通信),如果是CP的话,等待数据一直比较耗时。

Nacos服务是如何判定服务实例的状态?

在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false(客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)。

Nacos中的负载均衡底层是如何实现的?

Nacos中的负载均衡是通过客户端实现的,而底层实现则是通过Ribbon来实现的。具体来说,Nacos Client中集成了OpenFeign和Ribbon两个组件,Ribbon负责实现客户端的负载均衡,而OpenFeign则基于Ribbon实现了服务的调用和负载均衡。

在Nacos中,客户端使用Nacos Client来订阅服务实例的信息,并定期从Nacos Server获取最新的服务实例列表。客户端在获取到服务实例列表之后,会将这些实例传递给Ribbon,Ribbon会根据负载均衡策略,选择一个最优的服务实例进行请求。当服务实例发生变化时,Nacos Client会及时通知Ribbon,Ribbon会重新选择服务实例,从而实现动态的负载均衡。

Nacos支持多种负载均衡策略,包括轮询、随机、权重等策略。用户可以根据实际需求,在Nacos Client中配置不同的负载均衡策略。例如,在使用Ribbon作为负载均衡器时,可以在配置文件中添加如下配置:

# 使用轮询策略
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule

在上述配置中,将ribbon.NFLoadBalancerRuleClassName参数设置为com.netflix.loadbalancer.RoundRobinRule,就可以使用轮询策略了。如果要使用其他的负载均衡策略,只需要将该参数设置为对应的类名即可。

你可能感兴趣的:(java,运维,微服务)