spring cloud Netflix全套面试,这一篇就够了,3万字整理

*spring cloud Netflix*

面试:springcloud

https://blog.csdn.net/weixin_46577306/article/details/106906088?ops_request_misc=&request_id=&biz_id=102&utm_term=feign%E9%9D%A2%E8%AF%95%E9%A2%98&utm_medium=distribute.pc_search_result.none-task-blog-2blogsobaiduweb~default-1-.pc_v2_rank_blog_default&spm=1018.2226.3001.4450

1. *什么是微服务*

*<1>、什么是微服务?*

为适应企业的业务发展,提高软件研发的生产力,降低软件研发的成本,软件架构也作了升级和优化,将一个独立的系统拆分成若干小的服务,每个小服务运行在不同的进程中,服务与服务之间采用http 轻量协议(比如流行的RESTful)传输数据,每个服务所拥有的功能具有独立性强、高内聚的特点,这样的设计就实现了单个服务的高内聚,服务与服务之间的低耦合效果,这一个一个的小服务就是微服务,基于这种方法设计的系统架构即微服务架构。

微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事,从技术角度看就是一种小而独立的处理过程,类似进程概念,能够自行单独启动或销毁,拥有自己独立的数据库。

*微服务的要素*

\1. api 网关 (zuul) 服务的路由分配

\2. 服务注册与发现 (Eureka zookeeper)

\3. 服务的通信 (Rest RPC )

\4. 服务的容灾容错 (Hystrix)

*<2>、微服务需要解决什么问题*

服务治理、服务网关、智能路由、负载均衡、断路器、监控跟踪、分布式消息队列、配置管理等领域的解决方案。

服务治理,服务容错,服务通信,服务分发

*<3>、微服务特点*

· 应用按业务拆分成服务

· 各个服务均可独立部署

· 服务可被多个应用共享

· 服务之间可以通信

2. *微服务的优缺点*

*<1>、微服务的优点*

(1) ****每个服务足够内聚,足够小****,代码容易理解这样能聚焦一个指定的业务功能或业务需求

(2) ****开发简单、开发效率提高****,一个服务可能就是专一的只干一件事。

(3) 微服务能够被小团队****单独开发****,这个小团队是2到5人的开发人员组成。

(4) 微服务是****松耦合****的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。

(5) 微服务能使用****不同的语言开发****。

(6) 易于和****第三方集成****,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如Jenkins, Hudson, bamboo 。

(7) 微服务易于被一个开发人员理解,****修改和维护****,这样小团队能够更关注自己的工作成果。无需通过合作才能体现价值。

(8) 微服务允许你利用融合最新技术。

(9) 微服务只是业务逻辑的代码,不会和HTML,CSS 或其他界面组件混合。

(10) 每个微服务都有自己的存储能力,可以有自己的数据库。也可以有统一数据库。

*<2>、微服务的缺点*

\1. 开发人员要处理分布式系统的复杂性

\2. 多服务运维难度,随着服务的增加,运维的压力也在增大

\3. 系统部署依赖

\4. 服务间通信成本

\5. 数据一致性

\6. 系统集成测试

3. *注册中心Eureka*

面试题 : https://mp.weixin.qq.com/s?__biz=MzkwMzE3MDY0Ng==&mid=2247485445&idx=1&sn=671cf8e951421ce06cf94064273b2fba&chksm=c09b173cf7ec9e2acca0f592ccbd5646d9708576163cf660fb4fa704d98ea61bca18004d4c01&scene=21#wechat_redirect

1) *什么是服务注册?*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6fcY8Ggm-1629648645916)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps18.png)]

首先我们来了解下,服务注册、服务发现和服务注册中心的之间的关系。

举个形象的例子,三者之间的关系就好像是供货商,顾客和商店。

首先各地的供货商会将各种商品提供给商店,然后顾客需要商品的时候会去商店购买。

注册中心就好比是这个商店,供货商的动作就是服务注册,商品就是注册的服务。

当部署的服务启动后,会注册到注册中心,消费者需要什么样的服务,就自己去注册中心拉取。

2) *那么到底什么是服务注册,为什么要将服务注册到注册中心呢?*

服务注册指的是服务在启动时将服务的信息注册到注册中心中,由注册中心统一对所有的注册的服务进行管理。

现在我们想想,假如你是消费者,你需要买一个商品,你可以去商店,也可以直接去供货商。

但是如果今天你要买很多商品,而且我们并不知道每个商品对应的供应商的地址,那么你就得挨家挨户的去跑供货商购买商品。

是不是就很麻烦了,倘若此时有一家商店,汇总了多家供货商的商品,那你是不是只需要去这一家商店就能购买到你需要的所有的商品了呢?

这样是不是就方便了。

在我们现实开发中,比如我们需要获取用户信息的时候,而此时,我们的用户服务只部署了一个节点,那我们就可以使用IP+端口的形式访问服务。

当此时我们的服务部署了10个节点后,我们可以通过域名访问,通过nginx转发到某一个节点上,访问该节点的服务。

使用过nginx的小伙伴们都知道,每当我们需要新增一个节点的时候,我们就需要去修改nginx的配置文件,一旦服务部署的节点过多,频繁修改配置文件就变成了一件极其麻烦的事情。

这个时候,我们的注册中心,就应该粉墨登场了。

注册中心一登场,我们就尽管部署服务节点,部署完成后,服务启动,服务的信息就会被注册到注册中心,我们就不需要担心是不是又要去修改配置文件了。

3) *什么是服务发现?*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KIInteS0-1629648645918)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps19.jpg)]

服务发现有两种模式:一种是客户端发现模式,一种是服务端发现模式。Eureka采用的是客户端发现模式。

客户端发现模式就好比我是一个土豪顾客,我去了商店,我把所有的商品都买回家,需要的时候在这些商品里面寻找。

因为我是土豪,所以我当然不能忍受商店里有新品上架,而我却没有,所以我每隔一段时间就会商店增量获取最新的商品。

*这就是Eureka中的Fetch Registry,抓取注册信息。*

Eureka Client 从 Eureka Server 获取注册表信息并在本地缓存。

这里我们注意一下,Eureka Client并不是直接去服务注册表中获取数据,而是从ReadOnly缓存中获取数据。

并且会通过在上一个获取周期和当前获取周期之间获取增量更新,这些信息会定期更新(每30秒更新一次)。

获取的时候可能返回相同的实例。Eureka Client会自动处理重复信息。

因为我的土豪行为,我已经被商店老板记录在它的VVIP名单上了。可惜天有不测风云,我破产了,我再也不能这么土豪了,没办法,我告诉了老板我破产了,老板听了我的话,想都没想,直接从他的VVIP名单上将我的名字给剔除了,社会就是这么现实。

*这就是Eureka中的Cancel,取消。*

每一个微服务节点关闭时,Eureka Client会向Eureka Server发送一个取消请求。

Eureka Server收到你的取消请求后,就会将你从服务注册表中给剔除。

商店老板是个傲娇的人,她制定了一个规则,如果你是她VVIP名单上的人,你必须每隔一段时间就要去商店采购商品。

一旦你在一段时间内没有来采购,她就觉得你已经没有购买能力,不适合在她的VVIP名单上存在了。

她就会狠心的将你从她的VVIP名单上将我的名字给剔除了。

*这就是Eureka中的Renew(更新 / 续借)*

Eureka Client 内部具备一个内置的负载均衡器,它使用轮训(round-robin)负载算法。

在服务启动后,每隔一定周期(默认30秒)向Eureka Server发送心跳。

如果Eureka Server在多个心跳周期内(默认90秒)没有收到Eureka Client发送过来的心跳,Eureka Server将会在服务注册表中将该节点剔除。

当然了,服务发现去注册中心拉取的是服务的信息,然后需要从服务信息中获取到服务部署的节点信息,然后通过域名地址访问到该节点的服务。

就好像一家商店,因为空间太小,只是存放了一些商品的微缩模型,模型上写着该商品所属的供货商地址,我们去商店拿到该模型后,看到供货商的地址,然后我们就可以直接去供货商那儿直接购买商品了。

4) *什么是注册中心,注册中心的作用?*

注册中心就是一个管理器,各个服务提供者将服务注册到注册中心,有注册中心进行统一的存储和管理。

注册中心同时还有着判断服务是否可用,对于不可用的服务进行剔除的功能。

至于如何判断服务的可用性和如何剔除不可用的服务,后续会有详细的讲解。

5) *什么是 Eureka,有什么作用?*

Eureka采用CS架构,它分为两大组件。

一个是Eureka Server,注册中心服务端。

当各个微服务节点启动后,Eureka Server 会存储服务提供者注册上来的服务信息,并且提供二层缓存机制来维护整个注册中心。

另一个是Eureka Client,注册中心客户端。

Eureka Client是一个java客户端,它用来简化和Eureka Server交互。

Eureka Client 会拉取、更新和缓存 Eureka Server 中的信息。

因此当所有的 Eureka Server 节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者,但是当服务有更改的时候会出现信息不一致。

Eureka 架构详解

如下图所示,这是官网提供给我们的Eureka的架构图Eureka 的架构,主要分为 Eureka Server 和 Eureka Client 两部分,Eureka Client 又分为 Applicaton Service 和 Application Client,Applicaton Service 就是服务提供者,Application Client 就是服务消费者。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HPC7t2GV-1629648645920)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps20.png)]

我们首先会在应用程序中依赖 Eureka Client,项目启动后 Eureka Client 会向 Eureka Server 发送请求,进行注册,并将自己的一些信息发送给 Eureka Server。

注册成功后,每隔一定的时间,Eureka Client 会向 Eureka Server 发送心跳来续约服务,也就是汇报健康状态。如果客户端长时间没有续约,那么 Eureka Server 大约将在 90 秒内从服务器注册表中删除客户端的信息。

Eureka Client 还会定期从 Eureka Server 拉取注册表信息,然后根据负载均衡算法得到一个目标,并发起远程调用,关于负载均衡在后面的课时会详细介绍,也就是 Ribbon 组件。

应用停止时也会通知 Eureka Server 移除相关信息,信息成功移除后,对应的客户端会更新服务的信息,这样就不会调用已经下线的服务了,当然这个会有延迟,有可能会调用到已经失效的服务,所以在客户端会开启失败重试功能来避免这个问题。

Eureka Server 会有多个节点组成一个集群,保证高可用。Eureka Server 没有集成其他第三方存储,而是存储在内存中。

所以 Eureka Server 之间会将注册信息复制到集群中的 Eureka Server 的所有节点。

这样数据才是共享状态,任何的 Eureka Client 都可以在任何一个 Eureka Server 节点查找注册表信息。

Eureka 的工作流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dyD8fIdu-1629648645923)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps21.png)]

高清图片可以添加小编微信获取。

6) *Eureka 的自我保护机制*

*什么是自我保护机制*

官方定义:自我保护模式正是一种针对网络异常波动时的安全保护措施,使用自我保护模式能使Eureka集群更加健壮稳定的运行。

*为什么要开启自我保护机制?*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ZDNdokl-1629648645925)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps22.png)]

如果Eureka Server在一定时间内(默认90s)(可优化)没有收到某一个服务节点的心跳,Eureka Server将会移除该服务实例。

但是在某些时候,遇到网络分区故障,服务节点实际上是正常存货状态,但是却无法和Eureka Server正常通信,此时如果没有引入自我保护机制,Eureka Server就会将该服务节点剔除。

*自我保护模式的工作机制*

如果15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka Server就会认为客户端与注册中心发生了网络故障,Eureka Server进入自我保护机制。

*自我保护机制的缺点*

如果在自我保护机制中,刚好某些服务节点非正常下线,但是Eureka Server并不会剔除该服务节点,服务消费者就会获取到一个无效的服务实例。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWKpIRlE-1629648645927)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps23.png)]

*解决方案*

① :关闭自我保护机制(不推荐)

② :切换请求或断路器,使用负载均衡的方式,设置当一个请求超过多少秒还未得到响应,速度切换请求到下一个注册服务,例如使用Ribbon+Hystrix配置负载均衡和断路器。

*Eureka Server 进入自我保护机制后*

1、Eureka Server不在从注册表中剔除因为长时间没有和注册中心续约的服务节点

2、Eureka Server仍然能够接受新服务的注册和查询请求,但是不会同步到其他Eureka Server节点上

3、网络正常后,当前Eureka Server节点会将新的服务节点信息同步到其他Eureka Server节点上

*如何开启自我保护*

通过 eureka.server.enable-self-preservation=true/false 来开启或关闭自我保护机制。

其他关键配置:

清理失效服务节点的时间间隔:eureka.server.evication-interval-timer-in-ms 默认60s

续约间隔时间:eureka.instance.lease-renewal-interval-in-seconds 默认30s

续约到期时间:eureka.instance.lease-expiration-duration-in-seconds 默认90s

*通过源码窥探Eureka是如何开启自我保护机制的*

第一步,我们引入Eureka Server 依赖。

第二步,我们找到eureka-core jar包下的路径为com.netflix.eureka下的registry包

第三步,进入AbstractInstanceRegistry 类,找到evict方法,这个是定期剔除任务的线程最终执行的方

public void evict(long additionalLeaseMs) { logger.debug(“Running the evict task”); //判断自动保护是否开启,如果开启了自动保护, //那么剔除服务的操作就不往下执行,就不会剔除服务了 if (!this.isLeaseExpirationEnabled()) { logger.debug(“DS: lease expiration is currently disabled.”); } else { … }}

第四步,我们找到isLeaseExpirationEnabled()方法的实现

public boolean isLeaseExpirationEnabled() { //首先判断是否在配置文件中关闭了自我保护,如果关闭了自我保护直接返回true, // evict方法也就可以继续往下执行,进行无用服务剔除操作 if (!this.isSelfPreservationModeEnabled()) { return true; } else { //如果开启了自我保护机制,则进一步判断是否开启自我保护机制 //numberOfRenewsPerMinThreshold(每分钟最小的续约次数)大于0 //而且getNumOfRenewsInLastMin(最后一分钟的续约次数)必须要大于每分钟最小的续约次数 //当满足上面两个条件时则说明续约正常,返回true,evict方法也就可以继续往下执行,进行无用服务剔除操作 //所以说,只有不满足上述两个条件的情况下,才会返回false,evict方法也就不在往下执行,即使有没有正常续约的服务,也不会剔除 return this.numberOfRenewsPerMinThreshold > 0 && this.getNumOfRenewsInLastMin() > (long)this.numberOfRenewsPerMinThreshold; }}

第五步,我们注意到numberOfRenewsPerMinThreshold这个变量很关键,它的含义是每分钟最小的续约次数

在服务注册register和服务下线cancel两个方法中会更新这个变量,更新该变量方法如下:

/*** 期望每分钟最小的续约次数 = 期望正常续约的服务实例数 * (60/(我们配置的发送一次心跳时间间隔(默认30秒)))0.85 serverConfig.getRenewalPercentThreshold() 默认是 0.85 (可以通过eureka.server.renewal-percent-threshold)进行配置**/protected void updateRenewsPerMinThreshold() { this.numberOfRenewsPerMinThreshold = (int)((double)this.expectedNumberOfClientsSendingRenews * (60.0D / (double)this.serverConfig.getExpectedClientRenewalIntervalSeconds()) * this.serverConfig.getRenewalPercentThreshold());}

以上就是Eureka开启自我保护的整个逻辑流程。

*解除自我保护机制*

1.当服务的网络分区故障解除之后,客户端能够和服务进行交互时,在续约的时候,更新每分钟的续约数,当每分钟的续约数大于85%时,则自动解除。

2.重启服务

7) *Eureka 的健康检查*

其实很多框架的健康状态监控都是通过****actuator*来管理健康状态的,并且扩展了*health****端点。

所以说我们只要在项目中集成Actuator,我们就能管理监控项目的健康状态。

Eureka也是一样,我们可以将某些不健康的服务节点的状态告知Eureka Server,然后Eureka Server 会主动让其下线。

这个就是Eureka的健康检查。

如何实现Eureka-Actuator健康检查?

首先我们要在pom中依赖spring-boot-starter-actuator。

org.springframework.boot spring-boot-starter-actuator 2.3.3.RELEASE

第二步,配置文件中添加 eureka.client.healthcheck.enabled=true 配置

*原理分析:*

首先在****EurekaDiscoveryClientConfiguration**** 中根据 *eureka.client.healthcheck.enabled* 的值来决定是否要装配 *EurekaHealthCheckHandler****,然后在 *EurekaClientAutoConfiguration* 中会注册 *HealthCheck****,但我们注册完成后会有调用任务来进行状态的更新,在*com.netflix.discovery.InstanceInfoReplicator.run()* 中会进行状态更新。

Eureka 的多级缓存机制

8) *什么是多级缓存机制*

Eureka Server 为了避免同事读取内存数据造成的并发冲突问题,采用了多级缓存机制提升服务请求的响应速度。

Eureka Server的缓存是通过一个只读,一个读写缓存来实现的。

一级缓存:concurrentHashMap<key,value> readOnlyCacheMap 本质是HashMap,无过期时间,保存数据信息对外输出。

readOnlyCacheMap依赖于定时器的更新,通过与readWriteCacheMap的值做对比,以readWriteCacheMap为准。

responseCacheUpdateIntervalMs:readOnlyCacheMap缓存更新间隔,默认30s

二级缓存:LoaDing<key,value> readWriteCacheMap 本质是Guava缓存,包含失效机制,保护数据信息对外输出。

responseCacheAutoExpirationInSeconds:readWriteCacheMap 缓存过期时间,默认180s。

*当服务节点发生注册,下线,过期,状态变更等变化时*

1.在内存中更新注册表信息

2.同时过期掉readWriteCacheMap缓存,缓存清除只是会去清除readWriteCacheMap这个缓存, readOnlyCacheMap 只读 缓存并没有更新,也就说当客户端的信息发生变化之后, 只读缓存不是第一时间感知到的。只读缓存的更新只能依赖那个30秒的定时任务来更新。

3.一段时间后(默认30s),后台线程发现readWriteCacheMap缓存为空,于是也将readOnlyCacheMap中的缓存清空

4.当有服务消费者拉取注册表信息时,会调用ClassLoader的load方法,将内存中的注册表信息加载到各级缓存中,并返回注册表信息。

在Eureka Server 中会有两个线程,一个是定时同步两个缓存的数据,默认30s,一个是定时检测心跳故障,默认90s。

*服务拉取*

1.服务消费者,默认每30s,拉取注册表信息

2.从readOnlyCacheMap中获取信息,如果获取为空

3.从readWriteCacheMap中获取,如果还是为空

4.调用ClassLoader的load方法,将内存中的注册表信息加载到各级缓存中,并返回注册表信息。

Eureka的区域配置

当用户地理分布范围很广的时候,比如公司在上海、杭州、青岛等都有分公司的时候,一般都会有多个机房。

那么对于用户而言,当然是希望调用本地分公司的机房中的微服务应用。

比如:上海用户A,调用OAuth2服务,用户A当然希望调用上海机房里面的微服务应用。如果上海用户A调用杭州机房的OAuth2服务,就增加的延时时间。

所以我们希望一个机房内的服务优先调用同一个机房内的服务,当同一个机房的服务不可用的时候,再去调用其它机房的服务,以达到减少延时的作用。

为此,eureka提供了region和zone两个概念来进行分区,Eureka基于Amazon设计的,所以对于地域的区分也与Amazon一致,Amazon分为多个region,每个region包含多个zone,所以Eureka设计时也是可以设置region与zone,请求时可以优先选择与请求服务在同一个zone的服务。

*基本配置*

eureka: client: region: shanghai availability-zones: shanghai: zone1, zone2 service-url: zone1: http://localhost:8081/eureka, http://localhost:8082/eureka zone2: http://localhost:8083/eureka, http://localhost:8084/eureka instance: metadata-map: zone: zone1

此时无论我们调用多少次,调用的都是shanghai下面的zone1下面的服务。

一般来说我们都会结合Ribbon来实现微服务的负载均衡,而Ribbon内部会有一些专门的负载策略算法,虽然刚刚我们说过会优先请求的是指定region下指定 Zone 区域的服务实例。

但有些时候比如当在Region=shanghai下没有可用的zone,系统会默认加载 DEFAULT_ZONE,或者说活着同区域的服务负载过高…等等,也会自动切换成其他区域的服务。

Eureka的重试机制

由于 Spring Cloud Eureka 实现的服务治理机制强调了 CAP 原理中的 AP,即可用性与可靠性,牺牲了一定的一致性(在极端情况下它宁愿接受故障实例也不要丢掉"健康"实例,如同如我们上面所说的自我保护机制)。

但不论是由于触发了保护机制还是服务剔除的延迟,引起服务调用到这些不正常的服务,调用就会失败,从而导致其它服务不能正常工作!

这显然不是我们愿意看到的,我们还是希望能够增强对这类问题的容错。所以,我们在实现服务调用的时候通常会加入一些重试机制。

从 Camden SR2 版本开始,Spring Cloud 就整合了 Spring Retry 来增强 RestTemplate 的重试能力,对于开发者来说只需通过简单的配置,原来那些通过 RestTemplate 实现的服务访问就会自动根据配置来实现重试策略。

开启Eureka的重试机制很简单,首先我们在pom中引入Spring Retry的依赖:

org.springframework.retry spring-retry

然后在配置文件中配置spring.cloud.loadbalancer.retry.enabled参数来控制重试机制的开关,因为 Spring Retry默认是开启的,所以说我们只要引入依赖即可,如果说我们想要关闭的话只需要将 spring.cloud.loadbalancer.retry.enabled设置为false即可。

其实在SpringCloud的架构组件中无论是Fegin,Ribbon,还是Zuul都提供了重试机制,这些暂且不论,后续再讲到具体的组件时再进行具体的分析。

4. *负载均衡Ribbon*

面试 https://my.oschina.net/u/3748584/blog/4764723

1) *为什么要使用Ribbon*

我们知道但我们存在多个服务提供者的时候,我们会让所有的服务提供者将服务节点信息都注册到****EurekaServer*中,然后让客户端去拉取一份服务注册列表到本地,服务消费者会从服务注册列表中找到合适的服务实例信息,通过*IP:Port****的方式去调用服务。

那么,消费者是如何决定调用哪一个服务实例呢,此时,本章节的主人公****Ribbon****默默的站了起来,笑着说,没错,正是在下。

Srping Cloud Ribbon 是基于 Netflix Ribbon实现的一套 客户端负载均衡的工具。

简单的说,****Ribbon****是Netflix发布的开源顶目,主要功能是解析配置中或注册中心的服务列表,通过客户端的软件负均衡算法来实现服务请求的分发。

Ribbon客户端组件提供一系列完善配置项如连接超时,重试等。

简单的说,就是在配置文件中列出****LoadBalancer****后面所有的机器,****Ribbon****会自动的帮助你基于某种规则(筒单轮洵,随机连接等)去连接这些机器。

我们也很容易使****Ribbon****实现自定义负载均衡算法。

2) *Ribbon和Nginx又有什么不同呢?*

 *集中式负载均衡*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fmCE1U1q-1629648645928)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps24.jpg)]

如图所示就是集中式负载均衡集中式负载均衡就好比房屋中介,他手里有很多房屋信息。

服务消费者就好比是需要租房的租客,我们并不能直接的和房屋主人进行租房交易,而是通过房屋中介选择房屋信息达成租房交易。

也就是说,客户端的请求信息并不会直接去请求服务实例,而是在到达负载均衡器的时候,通过负载均衡算法选择某一个服务实例,然后将请求转发到这个服务实例上。

集中式负载均衡又分为硬件负载均衡,如F5,软件负载均衡,如Nginx。

 *客户端负载均衡*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t6Dehg71-1629648645929)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps25.jpg)]

如图所示就是客户端负载均衡就好比,现在有很多租房app,很多房屋的主人并不想通过中介租房,想省一笔中介费。

很多租客也想省一笔中介费,不想通过中介租房,于是租客将App上的租房信息记录在自己的笔记本上。

但是由于租客租房经验不足,并不知道应该选择哪一套房,此时刚好租客有一个做房屋中介好友(就是这么巧),于是租客将好友请到家里来,让他帮忙出谋划策,选择好房源,然后租客到时候直接去看房租房。

也就是说,此时客户端请求不会再去负载均衡器上进行转发了,客户端自己维护了一套服务列表,要掉用的某个服务实例之前首先会通过负载均衡算法选择一个服务节点,直接将请求发送到该服务节点上。

3) *Ribbon 总体架构*

首先我们看一张图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-68Fs7XN3-1629648645930)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps26.jpg)]

*接下来我们详细介绍下上图所示的Ribbon核心的6个组件接口。*

4) *IRule*

释义:IRule就是根据特定算法中从服务器列表中选取一个要访问的服务,Ribbon默认的算法为轮询算法。

接下来我们来看一张IRule的类继承关系图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4sdaKOi6-1629648645931)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps27.jpg)]

其中用红色方框圈出来的叶子节点是现在还在使用的负载均衡算法,而用紫色方框圈出来的是已经废弃了的。

由图可知,目前我们使用的负载均衡算法有以下几种:

*RoundRobinRule和WeightedResponseTimeRule*

首先说明下 RoundRobinRule(轮询)策略,虽然我没有圈出来但是他是很常用的负载均衡算法,表示表示每次都取下一个服务器。

****线性轮询算法实现****:每一次把来自用户的请求轮流分配给服务器,从1开始,直到N(服务器个数),然后重新开始循环。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。

通过图上的继承关系我们可知RoundRobinRule和WeightedResponseTimeRule是继承和被继承的关系。

WeightedResponseTimeRule是根据平均响应时间计算所有服务的权重,响应时间越快的服务权重越大被选中的概率越大。

有一个默认每30秒更新一次权重列表的定时任务,该定时任务会根据实例的响应时间来更新权重列表。

但是由于刚启动时如果统计信息不足,则使用RoundRobinRule(轮询)策略,等统计信息足够,会切换到WeightedResponseTimeRule。

*AvailabilityFilteringRule*

AvailabilityFilteringRule会先过滤掉由于多次访问故障而处于断路器状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问。

*ZoneAvoidanceRule*

综合判断Server所在区域的性能和Server的可用性选择服务器。

*BestAvailableRule*

会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。

*RandomRule*

随机选取服务。

使用 ThreadLocalRandom.current().nextInt(serverCount);随机选择。

*RetryRule*

先按照RoundRobinRule(轮询)的策略获取服务,如果获取的服务失败侧在指定的时间会进行重试,继续获取可用的服务。

5) *自定义负载均衡算法*

*自定义负载均衡算法主要分三步:*

实现IRule接口或者继承AbstractLoadBalancerRule类

重写choose方法

指定自定义的负载均衡策略算法类

首先我们创建一个MyRule类,但是这个类不能随便乱放。

官方文档给出警告:这个自定义的类不能放在@ComponentScan所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是我们达不到特殊化指定的目的了。

第一种,直接在启动类上添加

@RibbonClient(name = “order-service”,configuration = MyRule.class)

name指的是服务名称,configuration指的是自定义算法类。

第二种,在配置文件中指定自定义的负载均衡算法类。

# 指定order-service的负载策略user-service.ribbon.NFLoadBalancerRuleClassName=javaer.study.RibbonTest.MyRule

*ServerList*

ServerList用于获取服务节点列表并存储的组件。

存储分为静态存储和动态存储两种方式。

默认从配置文件中获取服务节点列表并存储称为静态存储。

从注册中心获取对应的服务实例信息并存储称为动态存储。

*ServerListFilter*

ServerListFilter主要用于实现服务实例列表的过滤,通过传入的服务实例清单,根据规则返回过滤后的服务实例清单。

*ServerListUpdater*

ServerListUpdater是列表更新器,用于动态的更新服务列表。

ServerListUpdater通过任务调度去定时实现更新操作。所以它有个唯一实现子类:PollingServerListUpdater。

PollingServerListUpdater动态服务器列表更新器要更新的默认实现,使用一个任务调度器ScheduledThreadPoolExecutor完成定时更新。

*IPing*

缓存到本地的服务实例信息有可能已经无法提供服务了,这个时候就需要有一个检测的组件,来检测服务实例信息是否可用。

IPing就是用来客户端用于快速检查服务器当时是否处于活动状态(心跳检测)

*ILoadBalancer*

ILoadBalancer是整个Ribbon中最重要的一个环节,它将负载均衡器最核心的资源也就是所有的服务的获取,更新,过滤,选择等操作都能安排的妥妥当当。

package com.netflix.loadbalancer;import java.util.List;public interface ILoadBalancer { void addServers(List var1); Server chooseServer(Object var1); void markServerDown(Server var1); /** @deprecated */ @Deprecated List getServerList(boolean var1); List getReachableServers(); List getAllServers();}

ILoadBalancer最重要的重要是获取所有的服务节点信息,或者是获取可访问的服务节点信息,然后通过ServerListFilter按照指定策略过滤服务节点列表,通过ServerListUpdater动态更新一组服务列表,通过IPing剔除非存活状态下的服务节点以及根据IRule从现有服务器列表中选择一个服务。

6) *Ribbon选择一个可用服务的详细流程*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-se5NVVLC-1629648645932)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps28.jpg)]

通过上图可知,流程如下:

① 通过ServerList从配置文件或者注册中心获取服务节点列表信息。

② 某些情况下我们可能需要通过通过ServerListFilter按照指定策略过滤服务节点列表。

③ 为了避免每次都要去注册中心或者配置文件中获取服务节点信息,我们会将过滤后的服务列表信息存到本地内存。此时如果新增服务节点或者是下线某些服务时,我们需要通过ServerListUpdater来动态更新服务列表。

④ 当有些服务节点已经无法提供服务后,我们会通过IPing(心跳检测)来剔除服务。

⑤ 最后ILoadBalancer 接口通过IRule指定的负载均衡算法去服务列表中选取一个服务。

7) *Ribbon的使用方式*

*总体来说Ribbon 的使用方式分为三种*

*第一种,使用原生API的方式*

*第二种,当我们整合了Spring-Cloud时,我们就可以使用Ribbon + RestTemplate来实现负载均衡。*

*第三种,使用Ribbon+Fegin,这种方式后续会有专文讲解,此处不做多演示。*

8) *Ribbon 饥饿加载(eager-load)模式*

我们在搭建完springcloud微服务时,经常会发生这样一个问题:我们服务消费方调用服务提供方接口的时候,第一次请求经常会超时,再次调用就没有问题了。

*为什么会这样?*

主要原因是Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,从而就会很容易发生请求超时的问题。

*解决方法*

既然超时的原因是第一次调用时还需要创建RibbonClient,那么我们能不能提前创建RibbonClient呢?

既然我们都能想到,那么SpringCloud开发者肯定也能想到。

所以我们可以通过设置下面两个属性来提前创建RibbonClient:

//开启Ribbon的饥饿加载模式ribbon.eager-load.enabled=true//指定需要饥饿加载的服务名ribbon.eager-load.clients=cloud-shop-userservice

5. *Feign接口调用*

Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。

简而言之:

Feign 采用的是基于接口的注解

Feign 整合了ribbon

6. *Hystrix服务熔断降级限流*

1) *服务熔断:*

*服务雪崩:*

在微服务架构中,微服务之间的数据交互通过远程调用完成,微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,此时如果链路上某个微服务的调用响应时间过长或者不可用,那么对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,导致“雪崩效应”。

*雪崩效应产生的几种场景*

· 突增流量:比如一大波爬虫,或者黑客攻击等。

· 程序bug:代码死循环,或者资源未释放等。

· 硬件原因:机器宕机、机房断电、光纤被挖断等。

*什么是服务熔断:*

服务熔断是应对雪崩效应的一种微服务链路保护机制。例如在高压电路中,如果某个地方的电压过高,熔断器就会熔断,对电路进行保护。同样,在微服务架构中,熔断机制也是起着类似的作用。当调用链路的某个微服务不可用或者响应时间太长时,会进行服务熔断,不再有该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。

在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。

服务熔断解决如下问题: 1. 当所依赖的对象不稳定时,能够起到快速失败的目的;2. 快速失败后,能够根据一定的算法动态试探所依赖对象是否恢复。

2) *服务降级:*

*什么是服务降级*

服务降级是指 当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心业务正常运作或高效运作。说白了,就是尽可能的把系统资源让给优先级高的服务。

资源有限,而请求是无限的。如果在并发高峰期,不做服务降级处理,一方面肯定会影响整体服务的性能,严重的话可能会导致宕机某些重要的服务不可用。所以,一般在高峰期,为了保证核心功能服务的可用性,都要对某些服务降级处理。比如当双11活动时,把交易无关的服务统统降级,如查看蚂蚁深林,查看历史订单等等。

服务降级分类

降级按照是否自动化可分为:自动开关降级和人工开关降级。
降级按照功能可分为:读服务降级、写服务降级。
降级按照处于的系统层次可分为:多级降级。

*自动开关降级*

自动降级是根据系统负载、资源使用情况、SLA等指标进行降级。

我们可以根据以下一些指标和方式进行降级:

*超时*
当访问的数据库/HTTP服务/远程调用响应慢或者长时间响应慢,且该服务不是核心服务的话,可以在超时后自动降级。在实际场景中一 定要配置好超时时间和超时重试次数及机制

*统计失败次数降级*
调用外部服务,当失败调用次数达到一 定阙值自动降级(熔断器)。然后通过异步线程去探测服务是否恢复了,恢复则取消降级。

*故障降级*
要调用的远程服务挂掉了(网络故障、DNS故障、HTTP服务返回错误的状态码、RPC服务抛出异常),则可以直接降级。降级后的处理方案有:默认值(比如库存服务挂了,返回默认现货)、兜底数据(比如广告挂了,返回提前准备好的一 些静态页面)、缓存(之前暂存的一 些缓存数据)。

*限流降级*
当我们去秒杀或者抢购一 些限购商品时,可能会因为访问量太大而导致系统崩溃,此时,开发者会使用限流来限制访问量,当达到限流阙值时,后续请求会被降级。降级后的处理方案可以是:排队页面(将用户导流到排队页面等一 会儿重试)、无货 (直接告知用户没货了)、错误页(如活动太火爆了,稍后重试)。

*降级的策略*

****服务接口拒绝服务:****无用户特定信息,页面能访问,但是添加删除提示服务器繁忙。页面内容也可在Varnish或CDN内获取。

****页面拒绝服务:****页面提示由于服务繁忙此服务暂停。跳转到varnish或nginx的一个静态页面。

****延迟持久化:****页面访问照常,但是涉及记录变更,会提示稍晚能看到结果,将数据记录到异步队列或log,服务恢复后执行。

****随机拒绝服务****:服务接口随机拒绝服务,让用户重试,目前较少有人采用。因为用户体验不佳。

****服务读降级****:一般情况下,分布式应用当中都会有缓存,查询频率比较高的数据,一般都会从缓存中获取(****Radis****)。但是有一些数据,如果直接从缓存中获取的话,有可能造成客户的投诉。比如用户账户余额,这个一般只从DB里面获取,而且是主库里面去读取。当大促来临时,此时可以降级为从库里面或者缓存里面去获取余额信息。

****服务写降级****:在秒杀抢购业务中,由于并发的数量比较大。除了在各个层面上限流、使用队列等方式应对,还可以对写库进行降级,可以将库存扣减操作在内存中进行,当高峰过去之后,再异步的同步至DB中做扣减操作。

3) *服务限流*

*限流的算法*

*固定窗口算*

是使用计数器在周期内累加访问次数,当达到设定的阈值时就会触发限流策略。下一个周期开始时,清零重新开始计数。此算法在单机和分布式环境下实现都非常简单,可以使用Redis的incr原子自增和线程安全即可以实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BC7fH9gd-1629648645933)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps29.jpg)]

*滑动窗口算法*

滑动窗口算法是将时间周期拆分成N个小的时间周期,分别记录小周期里面的访问次数,并且根据时间的滑动删除过期的小周期。如下图,假设时间周期为1分钟,将1分钟再分为2个小周期,统计每个小周期的访问数量,则可以看到,第一个时间周期内,访问数量为92,第二个时间周期内,访问数量为104,超过100的访问则被限流掉了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h09ujDLA-1629648645934)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps30.jpg)]

*漏桶算法*

漏桶算法是访问请求到达时直接放入漏桶,如当前容量已达到上限(限流值),则进行丢弃(触发限流策略)。漏桶以固定的速率进行释放访问请求(即请求通过),直到漏桶为空。

(处理请求的速度恒定,即每秒处理速度恒定,桶比较大的时候,处理太慢了)

****缺点****:如果桶的容量过大,突发请求时也会对后面请求的接口造成很大的压力。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZVsh9MJj-1629648645935)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps31.jpg)]

*令牌桶算法*

令牌桶算法是程序以恒定的速度向令牌桶中增加令牌,令牌桶满了之后会丢弃新进入的令牌,当请求到达时向令牌桶请求令牌,如获取到令牌则通过请求,否则触发限流策略

*(请求达到堆积一定时间就去获取令牌,若取得的就ok,取不到丢弃请求,只管自己是否会被冲垮)*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VnzCZR0K-1629648645936)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps32.jpg)]

*限流分类:*

集群限流 — 单节点限流

服务限流 — 接口限流

*单节点限流:* 只有一个服务,不用管集群的,数据已本机为准

*集群限流:* 需要共享数据,注意保证cas,Radis进行统一数据中心配置

*服务限流:* 在整个服务的接口上面如zuul上面,使用zuulFilter 过滤

*接口限流:* Hystrix 每秒的请求数, 或者使用aop

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lfCa24EI-1629648645937)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps33.jpg)]

4) *熔断和降级的比较*

*共性*

· 目的很一致:都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段,都是为了保证系统的稳定。

· 终表现类似:对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用;

· 粒度一般都是服务级别:当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改);

· 自治性要求很高: 熔断模式一般都是服务基于策略的自动触发,比如
降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段;

*差异性*

· 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;

· 管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)熔断是降级方式的一种体现。

7. *Zuul路由网关*

1) *什么是zuul*

Zuul包含了对请求的****路由**过滤****两个最主要的功能:

其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础.

Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得.

2) *zuul用来做限流,但是为什么要限流?*

① 防止不需要频繁请求服务的请求恶意频繁请求服务,造成服务器资源浪费。

② 防止不法分子恶意攻击系统,击穿系统盗取数据,防止数据安全隐患。

③ 防止系统高峰时期,对系统对频繁访问,给服务器带来巨大压力。
限流策略

3) *zuul的工作原理*

1、*过滤器机制*

zuul的核心是一系列的filters, 其作用可以类比Servlet框架的Filter,或者AOP。

zuul把Request route到 用户处理逻辑 的过程中,这些filter参与一些过滤处理,比如Authentication,Load Shedding等。

Zuul提供了一个框架,可以对过滤器进行动态的加载,编译,运行。

Zuul的过滤器之间没有直接的相互通信,他们之间通过一个RequestContext的静态类来进行数据传递的。RequestContext类中有ThreadLocal变量来记录每个Request所需要传递的数据。

Zuul的过滤器是由Groovy写成,这些过滤器文件被放在Zuul Server上的特定目录下面,Zuul会定期轮询这些目录,修改过的过滤器会动态的加载到Zuul Server中以便过滤请求使用。

下面有几种标准的过滤器类型:

Zuul大部分功能都是通过过滤器来实现的。Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。

(1) PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。

(2) ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。

(3) POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

(4) ERROR:在其他阶段发生错误时执行该过滤器。

内置的特殊过滤器

zuul还提供了一类特殊的过滤器,分别为:StaticResponseFilter和SurgicalDebugFilter

StaticResponseFilter:StaticResponseFilter允许从Zuul本身生成响应,而不是将请求转发到源。

SurgicalDebugFilter:SurgicalDebugFilter允许将特定请求路由到分隔的调试集群或主机。

自定义的过滤器

除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。

如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。

*2、过滤器的生命周期*

Zuul请求的生命周期如图,该图详细描述了各种类型的过滤器的执行顺序。

try {

preRoute();

} catch (ZuulException e) {

error(e);

postRoute();

return;

}

try {

route();

} catch (ZuulException e) {

error(e);

postRoute();

return;

}

try {

postRoute();

} catch (ZuulException e) {

error(e);

return;

}

4) *zuul 的作用*

Zuul可以通过加载动态过滤机制,从而实现以下各项功能:

 *验证与安全保障:* 识别面向各类资源的验证要求并拒绝那些与要求不符的请求。

 *审查与监控:* 在边缘位置追踪有意义数据及统计结果,从而为我们带来准确的生产状态结论。

 *动态路由:* 以动态方式根据需要将请求路由至不同后端集群处。

 *压力测试:* 逐渐增加指向集群的负载流量,从而计算性能水平。

 *负载分配:* 为每一种负载类型分配对应容量,并弃用超出限定值的请求。

 *静态响应处理:* 在边缘位置直接建立部分响应,从而避免其流入内部集群。

 *多区域弹性:* 跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。

5) *Zuul和Nginx的区别*

相同点:Zuul和Nginx都可以实现****负载均衡、反向代理(隐藏真实ip地址),过滤请求****,实现网关的效果

不同点:

① Nginx–c语言开发

② Zuul–java语言开发

③ Zuul负载均衡实现:采用ribbon+eureka实现本地负载均衡

④ Nginx负载均衡实现:采用服务器实现负载均衡

⑤ Nginx相比zuul功能会更加强大,因为Nginx整合一些脚本语言(Nginx+lua)

⑥ Nginx适合于服务器端负载均衡

⑦ Zuul适合微服务中实现网关

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xNicdkap-1629648645939)(file:///C:\Users\24140\AppData\Local\Temp\ksohtml12804\wps34.jpg)]

6) *zuul限流*

流算法

漏桶: leakey bucket,原理:桶的下方的小孔会以一个相对恒定的速率漏水,而不管入桶的水流量,这样就达到了控制出水口的流量

令牌桶: token bucket,原理:以相对恒定的速率向桶中加入令牌,请求来时于桶中取令牌,取到了就放行,没能取到令牌的请求则丢弃

限流粒度

粗粒度

网关限流

单个服务

细粒度

user: 认证用户或者匿名,针对某个用户粒度进行限流

origin: 客户机的IP,针对请求客户机的IP进行限流

url: 特定url,针对请求的url粒度进行限流

serviceId: 特定服务,针对某个服务的id粒度进行限流

8. *springConfig配置中心*

1) *什么是spring cloud?*

Spring cloud为用户提供了一整套快速开发分布式应用的解决方案,包括配置管理,服务发现,断路开关,智能路由,微代理,控制总线,一次token,全局锁,leader选举,分布式session,集群状态等功能。spring boot作为spring cloud等基础应用,可以快速搭建一个微服务。

应用

spring boot会有很多配置属性,在bootstrap或者application.properties中,区别不大,但是一般系统级别的配置在bootstrap中。

那么问题来了,每个人都修改配置文件,势必引起冲突或者不稳定,利用微服务思想,我们把配置中心也设计成一个微服务。

2) *配置中心有两种方式:*

本地配置中心,一般是本地的配置服务器

远程配置中心,一般是git仓库

但是无论那种方式都要保证高可用。配置中心的所有属性客户的和服务端都可以使用。

主要配置如下:

本地config server

server.port=9090

spring.cloud.config.server.native.searchLocations=file://${user.home}/CentralRepo/

SPRING_PROFILES_ACTIVE=native

git server

spring.cloud.config.server.git.uri=https://github.com/forezp/SpringcloudConfig/

spring.cloud.config.server.git.searchPaths=respo

spring.cloud.config.label=master

spring.cloud.config.server.git.username=your username

spring.cloud.config.server.git.password=your password

3) *优势:*

修改配置无需重新部署微服务

便于统一管理,提供了profile属性,可以统一切换配置属性文件,比如dev.properties, test.properties,production.properties.

上面两点保证微服务遵守了约定:

4) *缺点:*

没有cache策略

没有负载均衡策略,没有failover机制,如采用本地文件可以采用共享文件存储(ClusterFS等),防止disk损害,但是git却比较麻烦,需要把config server部署到load balancer后面,client连接vip获取config

如果存储git,存在网络问题导致属性加载出错

如果使用git存储,push之后,配置文件不变化,更新配置文件后,需要使用postman post请求访问 http://localhost:2009/refresh 手动刷新。因为git虽然发生变化,但是config server并不知道。所以需要手动刷新。如何避免手动刷新呢?Git webhooks和 Spring Cloud Bus

关于git webhooks

https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

5) *高可用实现*

由于config server不提供高可用实现,一般做法有以下两种:

利用其它负载均衡实现。

配置中心服务化,注册到eureka,利用eureka提供负载均衡,服务熔断等功能

这个就是使用一个负载均衡设备来隐藏后面的配置服务器集群,这是很容易想到的,不过Spring Cloud给我另一种实现,那就是服务化配置中心。

****也就是把配置中心也注册到Eureka-Server上称为一个服务****,这样,就和其他普通的服务一样做到了多实例,负载均衡,当然也做到了高可用,还有其他的一些功能特性,比如,熔断降级啊,失败策略等。如下图所示,一般采用下面的应用:

6) *与zookeeper比较*

zookeepr采用namespace体系,存储任意数据,监听机制等等,config server的优势是与spring紧密结合,利用spring抽象的

属性变更监听:利用git server,如果监听到git的push事件,发送rest请求通知其中一个service,接受到的service发送消息到spring cloud bus,其它service已经监听事件,接受到事件后自动refresh属性配置

loudConfig/

spring.cloud.config.server.git.searchPaths=respo

spring.cloud.config.label=master

spring.cloud.config.server.git.username=your username

spring.cloud.config.server.git.password=your password

3) *优势:*

修改配置无需重新部署微服务

便于统一管理,提供了profile属性,可以统一切换配置属性文件,比如dev.properties, test.properties,production.properties.

上面两点保证微服务遵守了约定:

4) *缺点:*

没有cache策略

没有负载均衡策略,没有failover机制,如采用本地文件可以采用共享文件存储(ClusterFS等),防止disk损害,但是git却比较麻烦,需要把config server部署到load balancer后面,client连接vip获取config

如果存储git,存在网络问题导致属性加载出错

如果使用git存储,push之后,配置文件不变化,更新配置文件后,需要使用postman post请求访问 http://localhost:2009/refresh 手动刷新。因为git虽然发生变化,但是config server并不知道。所以需要手动刷新。如何避免手动刷新呢?Git webhooks和 Spring Cloud Bus

关于git webhooks

https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

5) *高可用实现*

由于config server不提供高可用实现,一般做法有以下两种:

利用其它负载均衡实现。

配置中心服务化,注册到eureka,利用eureka提供负载均衡,服务熔断等功能

这个就是使用一个负载均衡设备来隐藏后面的配置服务器集群,这是很容易想到的,不过Spring Cloud给我另一种实现,那就是服务化配置中心。

****也就是把配置中心也注册到Eureka-Server上称为一个服务****,这样,就和其他普通的服务一样做到了多实例,负载均衡,当然也做到了高可用,还有其他的一些功能特性,比如,熔断降级啊,失败策略等。如下图所示,一般采用下面的应用:

6) *与zookeeper比较*

zookeepr采用namespace体系,存储任意数据,监听机制等等,config server的优势是与spring紧密结合,利用spring抽象的

属性变更监听:利用git server,如果监听到git的push事件,发送rest请求通知其中一个service,接受到的service发送消息到spring cloud bus,其它service已经监听事件,接受到事件后自动refresh属性配置

配置中心服务化:config server和其它服务一样都是注册到eureka server,进行统一管理,也能够进行负载均衡,故障切换等

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值