Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现java
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
server: port: 3000 eureka: server: enable-self-preservation: false #关闭自我保护机制 eviction-interval-timer-in-ms: 4000 #设置清理间隔(单位:毫秒 默认是60*1000) instance: hostname: localhost
@SpringBootApplication @EnableEurekaServer public class Eureka3000App { public static void main(String[] args) { SpringApplication.run(Eureka3000App.class, args); } }
Eureka作为注册中心, 作为服务的管理,它不能挂掉, 若是它挂掉,整个服务所有访问不了
所以Eureka也要搭建集群多台Eureka服务, 集群之间要进行相互之间通讯,通讯靠的就是Eureka-client
Eureka是一个服务端, 也是一个客户商, 之后相互注册,如今没有其它的可注册,因此就会报ClientExceptionnode
解决方案:不让它作为客户端注册,在application.yml添加以下配置
spring
client: registerWithEureka: false #不把本身做为一个客户端注册到本身身上 fetchRegistry: false #不须要从服务端获取注册信息(由于在这里本身就是服务端,并且已经禁用本身注册了) serviceUrl: #微服务要注册到的地址. #http://localhost:3000/eureka defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
<!--Eureka的客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
@EnableEurekaClient
server: port: 5000 eureka: client: serviceUrl: #eureka服务端提供的注册地址 参考服务端配置的这个路径 defaultZone: http://localhost:3000/eureka instance: instance-id: user-1 #此实例注册到eureka服务端的惟一的实例ID prefer-ip-address: true #是否显示IP地址 #eureka客户须要多长时间发送心跳给eureka服务器,代表它仍然活着,默认为30 秒 (与下面配置的单位都是秒) leaseRenewalIntervalInSeconds: 10 #Eureka服务器在接收到实例的最后一次发出的心跳后,须要等待多久才能够将此实例删除,默认为90秒 leaseExpirationDurationInSeconds: 30 spring: application: name: client-user #此实例注册到eureka服务端的name
服务提供者在启动时,会检测配置属性中的:eureka.client.register-with-erueka=true参数是否正确,
事实上默认就是true。若是值确实为true,则会向EurekaServer发起一个Rest请求api
当服务消费者启动是,会检测eureka.client.fetch-registry=true参数的值,若是为true, 则会从Eureka
Server服务的列表只读备份,而后缓存在本地。而且每隔30秒会从新获取并更新数据。
eureka.client.registry-fetch-interval-seconds: 5 生产环境中,咱们不须要修改这个值。浏览器
eureka: instance: lease-expiration-duration-in-seconds: 90 :服务续约(renew)的间隔,默认为30秒 lease-renewal-interval-in-seconds: 30 :服务失效时间,默认值90秒
在注册服务完成之后,服务提供者会维持一个心跳
也就是说,默认状况下每一个30秒服务会向注册中心发送一次心跳,证实本身还活着。若是超过90秒没有发送心跳
EurekaServer就会认为该服务宕机,会从服务列表中移除,这两个值在生产环境不要修改,默认便可。缓存
有些时候,咱们的服务提供方并不必定会正常下线,可能由于内存溢出、网络故障等缘由致使服务没法正常工做 Eureka
Server须要将这样的服务剔除出服务列表。所以它会开启一个定时任务,每隔60秒对全部失效的服务(超过90秒未响应)进行剔除
能够经过eureka.server.eviction-interval-timer-in-ms参数对其进行修改,单位是毫秒服务器
当把一个服务停掉后, 并不会立马从服务列表当中移除,默认是90秒清除一次
有能够注册中心和微服务之间出现了网络波动,网络很差,没有收到心跳,有多是网络很差,可是微服务还在,因此它不会立马把服务给移除
当15分钟内85%的心跳都没有正常心跳,那么eureka认为客户端与注册中心出现了网络问题,此时会出现如下状况:
1.Eureka再也不从注册列表中移除由于长时间没有收到的心跳而过时的服务
2.Eureka仍然可以接收服务的注册和查询请求,可是不会被同步到其它节点上
3.当网络稳定后,当前实例新注册的信息会被同步到其它节点上网络
CAP定理又称CAP原则, 指的是在一个分布式系统中,Consistency(一致性)、
Availability(可用性)、Partition tolerance(分区容错性), 最多只能同时三个特性中的两个,三者不可兼得架构
“all nodes see the same data at the same time”,
即更新操做成功并返回客户端后,全部节点在同一时间的数据彻底一致,这就是分布式的一致性。app
可用性指“Reads and writes always succeed” 即服务一直可用,并且是正常响应时间。
好的可用性主要是指系统可以很好的为用户服务,不出现用户操做失败或者访问超时等用户体验很差的状况
大多数分布式系统都分布在多个子网络。每一个子网络就叫作一个区
分区容错的意思是,区间通讯可能失败。好比,一台服务器放在本地,另外一台服务器放在外地(多是外省,甚至是外国),这就是两个区,它们之间可能没法通讯
两台跨区的服务器。Server1 向 Server2 发送一条消息,Server2 可能没法收到。系统设计的时候,必须考虑到这种状况.
通常来讲,分区容错没法避免,所以能够认为 CAP 的 P 老是成立
即分布式系统在遇到某节点或网络分区故障的时候,仍然可以对外提供知足一致性或可用性的服务。
分区容错性要求可以使应用虽然是一个分布式系统,而看上去却好像是在一个能够运转正常的总体。
若是保证 Server2 的一致性,那么 Server1 必须在写操做时,锁定 Server2
的读操做和写操做。只有数据同步后,才能从新开放读写。锁按期间,Server2 不能读写,没有可用性 若是保证 Server2的可用性,那么势必不能锁定 Server2,因此一致性不成立
若是不要求P(不容许分区),则C(强一致性)和A(可用性)是能够保证的。
但放弃P的同时也就意味着放弃了系统的扩展性,也就是分布式节点受限,没办法部署子节点, 这是违背分布式系统设计的初衷的。
2.CP without A:
若是不要求A(可用),至关于每一个请求都须要在服务器之间保持强一致,而P(分区)会致使同步时间无限延长
(也就是等待数据同步完才能正常访问服务)
一旦发生网络故障或者消息丢失等状况,就要牺牲用户的体验,等待全部数据所有一致了以后再让用户访问系统。
3.AP wihtout C:
要高可用并容许分区,则需放弃一致性。 一旦分区发生,节点之间可能会失去联系,为了高可用,每一个节点只能用本地数据提供服务
而这样会致使全局数据的不一致性。
抢购商品时,可能前几秒你浏览商品的时候页面提示是有库存的,当你选择完商品准备下单的时候,系统提示你下单失败,商品已售完。这其实就是先在
A(可用性)方面保证系统能够正常的服务,而后在数据的一致性方面作了些牺牲,虽然多少会影响一些用户体验,但也不至于形成用户购物流程的严重阻塞。
没有最好的策略,好的系统应该是根据业务场景来进行架构设计的,只有适合的才是最好的