分布式系统
Wei Jieyang Lv4

理论

CAP

CAP理论概述

  • 一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

(强)一致性 Consistency

  • 一致性指“all nodes see the same data at the same time”,即更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致,所以,一致性,说的就是数据一致性。分布式的一致性
  • 一致性是因为有并发读写才有的问题,因此在理解一致性的问题时,一定要注意结合考虑并发读写的场景。
  • 对于一致性,可以分为从客户端和服务端两个不同的视角。
    • 从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。
    • 从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。

三种一致性

  1. 对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性
    • CAP中说,不可能同时满足的这个一致性指的是这个强一致性
  2. 如果能容忍后续的部分或者全部访问不到,则是弱一致性
  3. 如果经过一段时间后要求能访问到更新后的数据,则是最终一致性

可用性 Availability

  • 可用性指“Reads and writes always succeed”,即服务一直可用,而且是正常响应时间。
  • 对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。所以,一般我们在衡量一个系统的可用性的时候,都是通过停机时间来计算的。
1
  • 通常我们描述一个系统的可用性时,我们说淘宝的系统可用性可以达到5个9,意思就是说他的可用水平是99.999%,即全年停机时间不超过 (1-0.99999)36524*60 = 5.256 min,这是一个极高的要求。
  • 好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。一个分布式系统,上下游设计很多系统如负载均衡、WEB服务器、应用代码、数据库服务器等,任何一个节点的不稳定都可以影响可用性。

分区容错性 Partition tolerance

  • 分区容错性指“the system continues to operate despite arbitrary message loss or failure of part of the system”,即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
  • 分区容错性扩展性紧密相关。在分布式应用中,可能因为一些分布式的原因导致系统无法正常运转。好的分区容错性要求能够使应用虽然是一个分布式系统,而看上去却好像是在一个可以运转正常的整体。比如现在的分布式系统中有某一个或者几个机器宕掉了,其他剩下的机器还能够正常运转满足系统需求,或者是机器之间有网络异常,将分布式系统分隔未独立的几个部分,各个部分还能维持分布式系统的运作,这样就具有好的分区容错性。
  • 简单点说,就是在网络中断,消息丢失的情况下,系统如果还能正常工作,就是有比较好的分区容错性。

如何取舍

  1. CA: 优先保证一致性和可用性,放弃分区容错。 这也意味着放弃系统的扩展性,系统不再是分布式的,有违设计的初衷。
  2. CP: 优先保证一致性和分区容错性,放弃可用性。在数据一致性要求比较高的场合(譬如:zookeeper,Hbase) 是比较常见的做法,一旦发生网络故障或者消息丢失,就会牺牲用户体验,等恢复之后用户才逐渐能访问。
  3. AP: 优先保证可用性和分区容错性,放弃一致性。NoSQL中的Cassandra 就是这种架构。跟CP一样,放弃一致性不是说一致性就不保证了,而是逐渐的变得一致。

注册中心

eureka、zookeeper、consul、nacos等

注册中心作用:

  1. 微服务数量众多,要进行远程调用就需要知道服务端的ip地址和端口,注册中心帮助我们管理这些服务的ip和端口。
  2. 微服务会实时上报自己的状态,注册中心统一管理这些微服务的状态,将存在问题的服务踢出服务列表,客户端获取到可用的服务进行调用。

eureka

  • 服务发现框架

  • 本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。

  • Spring Cloud Eureka 是对Netflix公司的Eureka(它实现了服务治理的功能)的二次封装,集成在自己的子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

  • 为什么要用eureka呢,因为分布式开发架构中,任何单点的服务都不能保证不会中断,因此需要服务发现机制,某个节点中断后,服务消费者能及时感知到保证服务高可用。

https://www.cnblogs.com/jing99/p/11576133.html

https://blog.csdn.net/qq_18153015/article/details/108415307

【原理解析】

  • Eureka包含两个组件,分为客户端和服务端
    • 客户端提供服务注册与注销、服务发现的功能
      • Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个**服务节点移除(默认90秒)**。
      • Eureka Client分为两个角色,分别是:
        1. Application Service(Service Provider): 服务提供方,是注册到Eureka Server中的服务。
        2. Application Client(Service Consumer): 服务消费方,通过Eureka Server发现服务,并消费。
        3. Application Service和Application Client不是绝对上的定义,因为Provider在提供服务的同时,也可以消费其他Provider提供的服务;Consumer在消费服务的同时,也可以提供对外服务。
    • 服务端提供服务治理的功能。
      • Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
      • Eureka Server本身也是一个服务,默认情况下会自动注册到Eureka注册中心。
      • 如果搭建单机版的Eureka Server注册中心,则需要配置取消Eureka Server的自动注册逻辑。毕竟当前服务注册到当前服务代表的注册中心中是一个说不通的逻辑。
      • Eureka Server通过Register、Get、Renew等接口提供服务的注册、发现和心跳检测等服务。
1、Eureka架构

a、Eureka Server架构原理:

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

b、Eureka Server缓存架构

1
  • 为避免读写冲突,Eureka采用多层缓存的架构。
  • 服务注册时,Eureka服务端会将服务实例更新到注册实例列表缓存(register)和读写缓存(readWriteCacheMap)中,然后Eureka服务端每隔30秒会将读写缓存(readWriteCacheMap)的数据更新到只读缓存(readOnlyCacheMap)中。
  • 消费者从Eureka服务端获取实例列表时,是直接从只读缓存(readOnlyCacheMap)中获取。

c、Eureka健康检查,自我保护机制

  • 为防止因为Eureka服务器网络问题,导致大部分服务实例被踢除,Eureka在进行服务定时更新时,会进行健康检查。
  • 健康检查流程:
    • 当过期的服务数量比例超过阈值(可配置,默认为0.85)时,Eureka会启动自我保护机制,不会进行服务踢除操作

d、Eureka分区

为避免跨机房调用的网络消耗,Eureka支持通过配置实现优先使用本机房服务实例,当本机房实例不可用时,再使用其它机房的服务实例。

1
  • Eureka的分区概念分为区域(region)和机房(zone)。
  • 如上图,区域(region)是北京,机房分为zone-1和zone-2。消费者(Consumer-1)调用服务时,会优先调用zone-1里面的服务提供者(Service-1),只有zone-1里面的服务提供者(Service-1)不可用,才会去调用zone-2里面的服务提供者(Service-2)。
2、功能原理

a、服务发现原理

  • eureka server可以集群部署,多个节点之间会进行(异步方式)数据同步,保证数据最终一致性,
  • Eureka Server作为一个开箱即用的服务注册中心,提供的功能包括:服务注册、接收服务心跳、服务剔除、服务下线等。
  • 需要注意的是,Eureka Server同时也是一个Eureka Client,在不禁止Eureka Server的客户端行为时,它会向它配置文件中的其他Eureka Server进行拉取注册表、服务注册和发送心跳等操作。
1
2
3
4
5
/* eureka server端通过appName和instanceInfoId来唯一区分一个服务实例,服务实例信息是保存在哪里呢?其实就是一个Map中:*/

/* 第一层的key是appName,第二层的key是instanceInfoId */
private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry
= new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();

b、服务注册

  • Service Provider启动时会将服务信息(InstanceInfo)发送给eureka server,eureka server接收到之后会写入registry中,服务注册默认过期时间DEFAULT_DURATION_IN_SECS = 90秒。InstanceInfo写入到本地registry之后,然后同步给其他peer节点,对应方法:

    com.netflix.eureka.registry.peerawareinstanceregistryimpl#replicateToPeers

c、写入本地registry

  • 服务信息(InstanceInfo)保存在Lease中,写入本地registry对应方法:

    com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#register

  • Lease统一保存在内存的ConcurrentHashMap中,在服务注册过程中,首先加个读锁,然后从registry中判断该Lease是否已经存在,如果存在则比较lastDirtyTimestamp时间戳,取二者最大的服务信息,避免发生数据覆盖。使用InstanceInfo创建一个新的InstanceInfo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (existingLastDirtyTimestamp > registrationLastDirtyTimestamp) {
// 已存在Lease则比较时间戳,取二者最大值
registrant = existingLease.getHolder();
}
Lease<InstanceInfo> lease = new Lease<InstanceInfo>(registrant, leaseDuration);
if (existingLease != null) {
// 已存在Lease则取上次up时间戳
lease.setServiceUpTimestamp(existingLease.getServiceUpTimestamp());
}
public Lease(T r, int durationInSecs) {
holder = r;
registrationTimestamp = System.currentTimeMillis(); // 当前时间
lastUpdateTimestamp = registrationTimestamp;
duration = (durationInSecs * 1000);
}

d、同步给其他peer节点

  • InstanceInfo写入到本地registry之后,然后同步给其他peer节点,对应方法:

    com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#replicateToPeers

  • 如果当前节点接收到的InstanceInfo本身就是另一个节点同步来的,则不会继续同步给其他节点,避免形成“广播效应”;InstanceInfo同步时会排除当前节点。

  • InstanceInfo的状态有依以下几种:

  • Heartbeat, Register, Cancel, StatusUpdate, DeleteStatusOverride,默认情况下同步操作是批量异步执行的,同步请求首先缓存到Map中,key为requestType+appName+id,然后由发送线程将请求发送到peer节点。

  • Peer之间的状态是采用异步的方式同步的,所以不保证节点间的状态一定是一致的,不过基本能保证最终状态是一致的。结合服务发现的场景,实际上也并不需要节点间的状态强一致。在一段时间内(比如30秒),节点A比节点B多一个服务实例或少一个服务实例,在业务上也是完全可以接受的(Service Consumer侧一般也会实现错误重试和负载均衡机制)。所以按照CAP理论,Eureka的选择就是放弃C,选择AP。

  • 如果同步过程中,出现了异常怎么办呢,这时会根据异常信息做对应的处理,如果是读取超时或者网络连接异常,则稍后重试;如果其他异常则打印错误日志不再后续处理。

e、服务续约

  • Renew(服务续约)操作由Service Provider定期调用,类似于heartbeat。主要是用来告诉Eureka Server Service Provider还活着,避免服务被剔除掉。
  • renew接口实现方式和register基本一致:首先更新自身状态,再同步到其它Peer,服务续约也就是把过期时间设置为当前时间加上duration的值。
  • 注意:服务注册如果InstanceInfo不存在则加入,存在则更新;而服务预约只是进行更新,如果InstanceInfo不存在直接返回false。

f、服务下线

  • Cancel(服务下线)一般在Service Provider shutdown的时候调用,用来把自身的服务从Eureka Server中删除,以防客户端调用不存在的服务,eureka从本地”删除“(设置为删除状态)之后会同步给其他peer,对应方法:

    com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#cancel

g、服务失效剔除

  • Eureka Server中有一个EvictionTask,用于检查服务是否失效。

  • Eviction(失效服务剔除)用来定期(默认为每60秒)在Eureka Server检测失效的服务,检测标准就是超过一定时间没有Renew的服务。默认失效时间为90秒,也就是如果有服务超过90秒没有向Eureka Server发起Renew请求的话,就会被当做失效服务剔除掉。

    • 失效时间可以通过eureka.instance.leaseExpirationDurationInSeconds进行配置,
    • 定期扫描时间可以通过eureka.server.evictionIntervalTimerInMs进行配置。
  • 服务剔除#evict方法中有很多限制,都是为了保证Eureka Server的可用性:

  • 比如自我保护时期不能进行服务剔除操作、过期操作是分批进行、服务剔除是随机逐个剔除,剔除均匀分布在所有应用中,防止在同一时间内同一服务集群中的服务全部过期被剔除,以致大量剔除发生时,在未进行自我保护前促使了程序的崩溃

3、Eureka Server/Client流程

a、服务信息拉取

  • Eureka consumer服务信息的拉取分为全量式拉取增量式拉取,eureka consumer启动时进行全量拉取,运行过程中由定时任务进行增量式拉取,如果网络出现异常,可能导致先拉取的数据被旧数据覆盖(比如上一次拉取线程获取结果较慢,数据已更新情况下使用返回结果再次更新,导致数据版本落后),产生脏数据。对此,eureka通过类型AtomicLong的fetchRegistryGeneration对数据版本进行跟踪,版本不一致则表示此次拉取到的数据已过期。
  • fetchRegistryGeneration过程是在拉取数据之前,执行fetchRegistryGeneration.get获取当前版本号,获取到数据之后, 通过fetchRegistryGeneration.compareAndSet来判断当前版本号是否已更新
  • 注意:如果增量式更新出现意外,会再次进行一次全量拉取更新。

b、Eureka Server的伸缩容

  • Eureka Server是怎么知道有多少Peer的呢?

    • Eureka Server在启动后会调用EurekaClientConfig.getEurekaServerServiceUrls来获取所有的Peer节点,并且会定期更新。
    • 定期更新频率可以通过eureka.server.peerEurekaNodesUpdateIntervalMs配置。
  • 这个方法的默认实现是从配置文件读取,所以如果Eureka Server节点相对固定的话,可以通过在配置文件中配置来实现。

  • 如果希望能更灵活的控制Eureka Server节点,比如动态扩容/缩容,那么可以override getEurekaServerServiceUrls方法,提供自己的实现,比如我们的项目中会通过数据库读取Eureka Server列表。

  • eureka server启动时把自己当做是Service Consumer从其它Peer Eureka获取所有服务的注册信息。然后对每个服务信息,在自己这里执行Register,isReplication=true从而完成初始化。

c、Service Provider

  • Service Provider启动时首先时注册到Eureka Service上,这样其他消费者才能进行服务调用,除了在启动时之外,只要实例状态信息有变化,也会注册到Eureka Service。
    • 需要注意的是,需要确保配置eureka.client.registerWithEureka=true。register逻辑在方法AbstractJerseyEurekaHttpClient.register中,Service Provider会依次注册到配置的Eureka Server Url上,如果注册出现异常,则会继续注册其他的url。
  • Renew操作会在Service Provider端定期发起,用来通知Eureka Server自己还活着。
    • 这里instance.leaseRenewalIntervalInSeconds属性表示Renew频率。默认是30秒,也就是每30秒会向Eureka Server发起Renew操作。这部分逻辑在HeartbeatThread类中。
    • 在Service Provider服务shutdown的时候,需要及时通知Eureka Server把自己剔除,从而避免客户端调用已经下线的服务,逻辑本身比较简单,通过对方法标记@PreDestroy,从而在服务shutdown的时候会被触发。

d、Service Consumer

  • Service Consumer这块的实现相对就简单一些,因为它只涉及到从Eureka Server获取服务列表和更新服务列表。
  • Service Consumer在启动时会从Eureka Server获取所有服务列表,并在本地缓存。需要注意的是,需要确保配置eureka.client.shouldFetchRegistry=true。由于在本地有一份Service Registries缓存,所以需要定期更新,定期更新频率可以通过eureka.client.registryFetchIntervalSeconds配置。
4、属性值

a、客户端 eureka.client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
1、RegistryFetchIntervalSeconds
// 从eureka服务器注册表中获取注册信息的时间间隔(s),默认为30秒
2、InstanceinfoReplicationIntervalSeconds
// 复制实例变化信息到eureka服务器所需要的时间间隔(s),默认为30秒
3、InitialInstanceInfoReplicationIntervalSeconds
// 最初复制实例信息到eureka服务器所需的时间(s),默认为40秒
4、EurekaServiceUrlPollIntervalSeconds
// 询问Eureka服务url信息变化的时间间隔(s),默认为300秒
5、ProxyHost
// 获取eureka服务的代理主机,默认为null
6、ProxyProxyPort
// 获取eureka服务的代理端口,默认为null
7、ProxyUserName
// 获取eureka服务的代理用户名,默认为null
8、ProxyPassword
// 获取eureka服务的代理密码,默认为null
9、GZipContent
// eureka注册表的内容是否被压缩,默认为true,并且是在最好的网络流量下被压缩
10、EurekaServerReadTimeoutSeconds
// eureka需要超时读取之前需要等待的时间,默认为8秒
11、EurekaServerConnectTimeoutSeconds
// eureka需要超时连接之前需要等待的时间,默认为5秒
12、BackupRegistryImpl
// 获取实现了eureka客户端在第一次启动时读取注册表的信息作为回退选项的实现名称
13、EurekaServerTotalConnections
// eureka客户端允许所有eureka服务器连接的总数目,默认是200
14、EurekaServerTotalConnectionsPerHost
// eureka客户端允许eureka服务器主机连接的总数目,默认是50
15、EurekaServerURLContext
// 表示eureka注册中心的路径,如果配置为eureka,则为http://x.x.x.x:x/eureka/,在eureka的配置文件中加入此配置表示eureka作为客户端向注册中心注册,从而构成eureka集群。此配置只有在eureka服务器ip地址列表是在DNS中才会用到,默认为null
16、EurekaServerPort
// 获取eureka服务器的端口,此配置只有在eureka服务器ip地址列表是在DNS中才会用到。默认为null
17、EurekaServerDNSName
// 获取要查询的DNS名称来获得eureka服务器,此配置只有在eureka服务器ip地址列表是在DNS中才会用到。默认为null
18、UseDnsForFetchingServiceUrls
// eureka客户端是否应该使用DNS机制来获取eureka服务器的地址列表,默认为false
19、RegisterWithEureka
// 实例是否在eureka服务器上注册自己的信息以供其他服务发现,默认为true
20、PreferSameZoneEureka
// 实例是否使用同一zone里的eureka服务器,默认为true,理想状态下,eureka客户端与服务端是在同一zone下
21、AllowRedirects
// 服务器是否能够重定向客户端请求到备份服务器。如果设置为false,服务器将直接处理请求,如果设置为true,它可能发送HTTP重定向到客户端。默认为false
22、LogDeltaDiff
// 是否记录eureka服务器和客户端之间在注册表的信息方面的差异,默认为false
23、DisableDelta(*)
// 默认为false
24、fetchRegistryForRemoteRegions
// eureka服务注册表信息里的以逗号隔开的地区名单,如果不这样返回这些地区名单,则客户端启动将会出错。默认为null
25、Region
// 获取实例所在的地区。默认为us-east-1
26、AvailabilityZones
// 获取实例所在的地区下可用性的区域列表,用逗号隔开。
27、EurekaServerServiceUrls
// Eureka服务器的连接,默认为http://XXXX:X/eureka/,但是如果采用DNS方式获取服务地址,则不需要配置此设置。
28、FilterOnlyUpInstances(*)
// 是否获得处于开启状态的实例的应用程序过滤之后的应用程序。默认为true
29、EurekaConnectionIdleTimeoutSeconds
// Eureka服务的http请求关闭之前其响应的时间,默认为30秒
30、FetchRegistry
// 此客户端是否获取eureka服务器注册表上的注册信息,默认为true
31、RegistryRefreshSinglevipAddress
// 此客户端只对一个单一的VIP注册表的信息感兴趣。默认为null
32、HeartbeatExecutorThreadPoolSize(*)
// 心跳执行程序线程池的大小,默认为5
33、HeartbeatExecutorExponentialBackOffBound(*)
// 心跳执行程序回退相关的属性,是重试延迟的最大倍数值,默认为10
34、CacheRefreshExecutorThreadPoolSize(*)
// 执行程序缓存刷新线程池的大小,默认为5
35、CacheRefreshExecutorExponentialBackOffBound
// 执行程序指数回退刷新的相关属性,是重试延迟的最大倍数值,默认为10
36、DollarReplacement
// eureka服务器序列化/反序列化的信息中获取“$”符号的的替换字符串。默认为“_-”
37、EscapeCharReplacement
// eureka服务器序列化/反序列化的信息中获取“_”符号的的替换字符串。默认为“__”
38、OnDemandUpdateStatusChange(*)
// 如果设置为true,客户端的状态更新将会点播更新到远程服务器上,默认为true
39、EncoderName
// 这是一个短暂的编码器的配置,如果最新的编码器是稳定的,则可以去除,默认为null
40、DecoderName
// 这是一个短暂的解码器的配置,如果最新的解码器是稳定的,则可以去除,默认为null
41、ClientDataAccept(*)
// 客户端数据接收
42、Experimental(*)
// 当尝试新功能迁移过程时,为了避免配置API污染,相应的配置即可投入实验配置部分,默认为null

b、服务端 eureka.server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1、AWSAccessId
// 获取aws访问的id,主要用于弹性ip绑定,此配置是用于aws上的,默认为null
2、AWSSecretKey
// 获取aws私有秘钥,主要用于弹性ip绑定,此配置是用于aws上的,默认为null
3、EIPBindRebindRetries
// 获取服务器尝试绑定到候选的EIP的次数,默认为3
4、EIPBindingRetryIntervalMsWhenUnbound(*)
// 服务器检查ip绑定的时间间隔,单位为毫秒,默认为1 * 60 * 1000
5、EIPBindingRetryIntervalMs
// 与上面的是同一作用,仅仅是稳定状态检查,默认为5 * 60 * 1000
6、SelfPreservation模式,
// SelfPreservation模式,当出现出现网络分区、eureka在短时间内丢失过多客户端时,会进入SelfPreservation模式,即一个服务长时间没有发送心跳,eureka也不会将其删除,默认为true
7、RenewalPercentThreshold(*)
// 阈值因子,默认是0.85,如果阈值比最小值大,则SelfPreservation模式开启
8、RenewalThresholdUpdateIntervalMs
// 阈值更新的时间间隔,单位为毫秒,默认为15 * 60 * 1000
9、PeerEurekaNodesUpdateIntervalMs(*)
// 集群里eureka节点的变化信息更新的时间间隔,单位为毫秒,默认为10 * 60 * 1000
10、EnableReplicatedRequestCompression
// 复制的数据在发送请求时是否被压缩,默认为false
11、NumberOfReplicationRetries
// 获取集群里服务器尝试复制数据的次数,默认为5
12、PeerEurekaStatusRefreshTimeIntervalMs
// 服务器节点的状态信息被更新的时间间隔,单位为毫秒,默认为30 * 1000
13、WaitTimeInMsWhenSyncEmpty(*)
// 在Eureka服务器获取不到集群里对等服务器上的实例时,需要等待的时间,单位为毫秒,默认为1000 * 60 * 5
14、PeerNodeConnectTimeoutMs
// 连接对等节点服务器复制的超时的时间,单位为毫秒,默认为200

c、实例微服务端配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
1、InstanceId
// 此实例注册到eureka服务端的唯一的实例ID,其组成为${spring.application.name}:${spring.application.instance_id:${random.value}}
2、Appname
// 获得在eureka服务上注册的应用程序的名字,默认为unknow
3、AppGroupName
// 获得在eureka服务上注册的应用程序组的名字,默认为unknow
4、InstanceEnabledOnit(*)
// 实例注册到eureka服务器时,是否开启通讯,默认为false
5、NonSecurePort
// 获取该实例应该接收通信的非安全端口。默认为80
6、SecurePort
// 获取该实例应该接收通信的安全端口,默认为443
7、NonSecurePortEnabled
// 该实例应该接收通信的非安全端口是否启用,默认为true
8、SecurePortEnabled
// 该实例应该接收通信的安全端口是否启用,默认为false
9、LeaseRenewalIntervalInSeconds
// eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30秒
10、LeaseExpirationDurationInSeconds
// Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
11、VirtualHostName
// 此实例定义的虚拟主机名,其他实例将通过使用虚拟主机名找到该实例。
12、SecureVirtualHostName
// 此实例定义的安全虚拟主机名
13、ASGName(*)
// 与此实例相关联AWS自动缩放组名称。此项配置是在AWS环境专门使用的实例启动,它已被用于流量停用后自动把一个实例退出服务。
14、HostName
// 与此实例相关联的主机名,是其他实例可以用来进行请求的准确名称
15、MetadataMap(*)
// 获取与此实例相关联的元数据(key,value)。这个信息被发送到eureka服务器,其他实例可以使用。
16、DataCenterInfo(*)
// 该实例被部署在数据中心
17、IpAddress
// 获取实例的ip地址
18、StatusPageUrlPath(*)
// 获取此实例状态页的URL路径,然后构造出主机名,安全端口等,默认为/info
19、StatusPageUrl(*)
// 获取此实例绝对状态页的URL路径,为其他服务提供信息时来找到这个实例的状态的路径,默认为null
20、HomePageUrlPath(*)
// 获取此实例的相关主页URL路径,然后构造出主机名,安全端口等,默认为/
21、HomePageUrl(*)
// 获取此实例的绝对主页URL路径,为其他服务提供信息时使用的路径,默认null
22、HealthCheckUrlPath
// 获取此实例的相对健康检查URL路径,默认为/health
23、HealthCheckUrl
// 获取此实例的绝对健康检查URL路径,默认为null
24、SecureHealthCheckUrl
// 获取此实例的绝对安全健康检查网页的URL路径,默认为null
25、DefaultAddressResolutionOrder
// 获取实例的网络地址,默认为[]
26、Namespace
// 获取用于查找属性的命名空间,默认为eureka

FLP impossibility

FLP不可能原理:在网络可靠,存在节点失效(即便只有一个)的最小化异步模型系统中,不存在一个可以解决一致性问题的确定性算法。

  • 1985年 FLP 原理实际上说明对于允许节点失效情况下,纯粹异步系统无法确保一致性在有限时间内完成。
  • 科学告诉你什么是不可能的;工程则告诉你,付出一些代价,我可以把它变成可能。
  • Post title:分布式系统
  • Post author:Wei Jieyang
  • Create time:2021-03-04 14:11:00
  • Post link:https://jieyang-wei.github.io/2021/03/04/分布式系统/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.