【⼋股⽂】SpringCloud全家桶
⽬录
什么是SpringCloud
Spring Cloud是⼀个微服务系统架构的⼀站式解决⽅案,提供的全套的分布式系统解决⽅案。
Spring Cloud对微服务基础框架Netflix的多个开源组件进⾏了封装,⼜实现了和Spring Boot开发框架以及云端平台的集成。
Spring Cloud为微服务架构开发涉及的配置管理,服务治理,熔断机制,智能路由,微代理,控制总线,⼀次性token,全局⼀致性锁,leader选举,分布式session,集状态管理等操作提供了⼀种简单的开发⽅式。(贼多,记住⼏个就⾏)
Spring Cloud 为开发者提供了快速构建分布式系统的⼯具,开发者可以快速的启动服务或构建应⽤、同时能够快速和云平台资源进⾏对接。
⽩话⽂:Spring Cloud是⼀个微服务架构全家桶
什么是微服务?
是⼀个分布式系统,它是将单体应⽤划分成⼩的服务单元,微服务之间使⽤HTTP的API进⾏访问操作。每个微服务都独⾃运⾏在⾃⼰的进程中独⽴部署,⽽且每个微服务可以使⽤单独的语⾔开发以及不同的数据库存储。
微服务的优点
服务的独⽴部署:每个服务都是⼀个独⽴的项⽬,可以独⽴部署,不依赖于其他服务,耦合性低。
服务的快速启动:拆分之后服务启动的速度必然要⽐拆分之前快很多,因为依赖的库少了,代码量也少了。
更加适合敏捷开发:敏捷开发以⽤户的需求进化为核⼼,采⽤迭代、循序渐进的⽅法进⾏。服务拆分可以快速发布新版本,修改哪个服务只需要发布对应的服务即可,不⽤整体重新发布。(啥是敏捷开发?)
服务可以动态按需扩容:当某个服务的访问量较⼤时,我们只需要将这个服务扩容即可。
服务的数据库独⽴:分库分表,正因为与单体架构⼀样都在⼀个数据库⾥⾯就会给数据库造成压⼒最好的办法及时分库分表。
DOTO 等删掉。。
分布式服务集中化管理(说的就是注册中⼼)。
服务的管理中⼼对微服务集中化管理,Eureka和Zookeeper和Consul。
熔断机制
微服务之间相互依赖,⼀个服务A不可⽤(超时或者⽹络延迟),导致调⽤服务A的其他服务也不可⽤,导致系统瘫痪(雪崩效应),为了解决这⼀问题采⽤“熔断机制”。
微服务的缺点
服务间调⽤的问题:有⽹络问题、延迟开销、容错、带宽、安全等问题
独⽴的数据库,分布式事务问题:每个微服务都有⾃⼰的数据库,这就是所谓的去中⼼化的数据管理。这种模式的优点在于不同的服务,可以选择适合⾃⾝业务的数据,⽐如订单服务可以⽤ MySQL、评论服务可以⽤ Mongodb、商品搜索服务可以⽤
Elasticsearch。
⽬前最理想的解决⽅案就是柔性事务中的最终⼀致性
测试的难度增加:服务和服务之间通过接⼝来交互,当接⼝有改变的时候,对所有的调⽤⽅都是有影响的,这时⾃动化测试就显得⾮常重要了,如果要靠⼈⼯⼀个个接⼝去测试,那⼯作量就太⼤了。这⾥要强调⼀点,就是 API ⽂档的管理尤为重要。
运维的难度增加:在采⽤传统的单体应⽤时,我们可能只需要关注⼀个 Tomcat 的集、⼀个 MySQL 的集就可以了,但这在微服务架构下是⾏不通的。当业务增加时,服务也将越来越多,服务的部署、监控将变得⾮常复杂,这个时候对于运维的要求就⾼了。
SpringCloud有什么优势?
使⽤SpringBoot开发分布式微服务时,我们⾯临以下问题:
(吐槽:这些是SpringCloud的优势吗,怎么是⼀堆问题。。。后续再理解)
与分布式系统相关的复杂性:这种开销包括⽹络问题,延迟开销,带宽问题,安全问题。
服务发现:服务发现⼯具管理集中的流程和服务如何查和互相交谈。它涉及⼀个服务⽬录,在该⽬录中注册服务,然后能够查并连接到该⽬录中的服务。
冗余:分布式系统中的冗余问题。
负载平衡:负载平衡改善跨多个计算资源的⼯作负荷,诸如计算机,计算机集,⽹络链路,中央处理单元,或磁盘驱动器的分布。
性能问题:由于各种运营开销导致的性能问题。
部署复杂性:Devops技能的要求。
什么是服务熔断?什么是服务降级?
熔断机制(微服务链路保护机制)
熔断机制是应对雪崩效应的⼀种微服务链路保护机制。当扇出链路的某个微服务不可⽤或者响应时间太长时,会进⾏服务降级,进⽽熔断该节点微服务的调⽤,**快速返回“错误”的响应信息
**。当检测到该节点微服务调⽤响应正常后恢复调⽤链路。
⽩话⽂:下游服务不可⽤的时候,会停⽌调⽤,并返回错误相应信息
在SpringCloud框架⾥熔断机制通过Hystrix实现,Hystrix会监控微服务间调⽤的状况,当失败的调⽤到⼀定阈值,缺省是5秒内调⽤20次,如果失败,就会启动熔断机制。熔断机制的注解@HystrixCommand。
服务降级
服务降级,⼀般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调⽤,此时客户端可以⾃⼰准备⼀个本地的fallback回调,返回⼀个缺省值。这样做,虽然⽔平下降,但好⽍可⽤,⽐直接挂掉强。
⽩话⽂:熔断之后,报错太难看了,那就⾃⼰本地造⼀个回调
Eureka和zookeeper都可以提供服务注册与发现的功能,请说说两个的区别?
zookeeper
zookeeper 是CP原则(强⼀致性和分区容错性)。 zookeeper当主节点Master故障时,zk会在剩余节点重新选择主节点,耗时过长,虽然最终能够恢复,但是选取Master节点期间会导致服务不可⽤,这是不能容忍的。
Eureka
eureka是AP原则(可⽤性和分区容错性)。 eureka各个节点是平等的,⼀个节点挂掉,其他节点仍会正常保证服务。
⽩话⽂:当节点出故障的时候,zookeeper因为强⼀致性,必须选好Master之后,才能⽤;Eureka因为⾼可⽤,⼀个节点挂了其他的节点顶上
SpringBoot和SpringCloud的区别
SpringBoot只是⼀个快速开发框架
SpringCloud是⼀系列框架的集合(每⼀个框架可以认为是⼀个SpringBoot)
SpringBoot可以离开SpringCloud单独使⽤,⽽SpringCloud离不开SpringBoot
⽩话⽂:Boot是快速开发的框架,有什么特点(内置tomcat、⼀键启动、简化配置等等),Cloud是微服务框架的集合,有啥啥啥的(⽜逼的把全家都说出来)
负载均衡的意义是什么?
在计算中,负载均衡可以改善计算机,计算机集,⽹络连接,中央处理器单元或者磁盘驱动琪等多种计算资源和⼯作负载分布。负载均衡就是优化资源使⽤,最⼤吞吐量,最⼩化响应时间并且避免任何单⼀资源的过载。使⽤多个组件进⾏负载均衡,⽽不是单个组件可能会通过冗余来提⾼可靠性和可⽤性。负载均衡通常涉及专⽤软件或者硬件,例如多层交换机或者域名系统服务器进程。
⽩话⽂:让多台机⼦处理并发请求,并快速响应,避免单台机⼦压⼒太⼤⽽挂掉。
什么是hystrix,如何实现容错
什么是hystrix
Hystrix是Netflix针对微服务分布式系统采⽤的熔断保护中间件,相当于电路中的保险丝。 在微服务架构下,很多服务都相互依赖,如果不能对依赖的服务进⾏隔离,那么服务本⾝也有可能发⽣故障,Hystrix 通过HystrixCommand对调⽤进⾏隔离,这样可以阻⽌故障的连锁反应,能够让接⼝调⽤快速失败并迅速恢复正常,或者回退并优雅降级。
⽩话⽂:hystrix就是保险丝,当下游服务不可⽤时,快速返回失败或者进⾏降级操作,⽽不是傻傻的等待响应
tips⼩知识:hystrix是基于线程池隔离调⽤,基于熔断器快速失败
如何实现容错
Hystrix是由Netflix开源的⼀个延迟和容错库,⽤于隔离访问远程系统、服务或者第三⽅库,防⽌级联失败
1. 包裹请求
2. 跳闸机制:当服务错误率达到⼀定阈值时,⾃动跳闸或者⼿动跳闸
3. 资源隔离:Hystrix为每个依赖都维护了⼀个⼩型的线程池,当线程池已满,会⽴即拒绝该依赖的请求,加速失败判定。
4. 监控
5. 回退机制:发⽣错误时,执⾏回退机制fallback,类似缺省值;
6. ⾃我修复:断路器打开后的⾃动恢复机制
⽩话⽂:检测调⽤失败频率太⾼的时候,直接打开断路器,快速失败,保护资源,之后尝试关闭断路器
断路器逻辑:
1、正常情况下,断路器关闭,可正常访问;
2、在⼀段时间内请求失败率达到阈值,断路器打开;
3、打开后进⼊“半开”状态。此时可允许⼀个请求访问依赖的服务,若成功则关闭断路器,若失败则继续保持打开状态。
说说RPC的实现原理(⾮常重要)
1. 建⽴通信
⾸先要解决通讯的问题:即A机器想要调⽤B机器,⾸先得建⽴起通信连接。
主要是通过在客户端和服务器之间建⽴TCP连接,远程过程调⽤的所有交换的数据都在这个连接⾥传输。连接可以是按需连接,调⽤结束后就断掉,也可以是长连接,多个远程过程调⽤共享同⼀个连接。
通常这个连接可以是按需连接(需要调⽤的时候就先建⽴连接,调⽤结束后就⽴马断掉),也可以是长连接(客户端和服务器建⽴起连接之后保持长期持有,不管此时有⽆数据包的发送,可以配合⼼跳检测机制定期检测建⽴的连接是否存活有效),多个远程过程调⽤共享同⼀个连接。
2. 服务寻址
要解决寻址的问题,也就是说,A服务器上的应⽤怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端⼝,⽅法的名称名称是什么。
通常情况下我们需要提供B机器(主机名或IP地址)以及特定的端⼝,然后指定调⽤的⽅法或者函数的名称以及⼊参出参等信息,这样才能完成服务的⼀个调⽤。
可靠的寻址⽅式(注册中⼼)是RPC的实现基⽯,⽐如可以采⽤Redis或者Zookeeper来注册服务等等。
2.1 从服务提供者的⾓度看:
当服务提供者启动的时候,需要将⾃⼰提供的服务注册到指定的注册中⼼,以便服务消费者能够通过服务注册中⼼进⾏查;
当服务提供者由于各种原因致使提供的服务停⽌时,需要向注册中⼼注销停⽌的服务;
服务的提供者需要定期向服务注册中⼼发送⼼跳检测,服务注册中⼼如果⼀段时间未收到来⾃服务提供者的⼼跳后,认为该服务提供者已经停⽌服务,则将该服务从注册中⼼上去掉
2.2 从调⽤者的⾓度看:
服务的调⽤者启动的时候根据⾃⼰订阅的服务向服务注册中⼼查服务提供者的地址等信息;
当服务调⽤者消费的服务上线或者下线的时候,注册中⼼会告知该服务的调⽤者;
服务调⽤者下线的时候,则取消订阅。
3. ⽹络传输
3.1 序列化
当A机器上的应⽤发起⼀个RPC调⽤时,调⽤⽅法和其⼊参等信息需要通过底层的⽹络协议如TCP传输到B机器,由于⽹络协议是基于⼆进制的,所有我们传输的参数数据都需要先进⾏序列化(Serialize)或者编组(marshal)成⼆进制的形式才能在⽹络中进⾏传输。然后通过寻址操作和⽹络传输将序列化或者编组之后的⼆进制数据发送给B机器。
spring到底是干啥的
3.2 反序列化
当B机器接收到A机器的应⽤发来的请求之后,⼜需要对接收到的参数等信息进⾏反序列化操作(序列化的逆操作),即将⼆进制信息恢复为内存中的表达⽅式,然后再到对应的⽅法(寻址的⼀部分)进⾏本地调⽤(⼀般是通过⽣成代理Proxy去调⽤,
通常会有JDK动态代理、CGLIB动态代理、Javassist⽣成字节码技术等),之后得到调⽤的返回值。
4. 服务调⽤
B机器进⾏本地调⽤(通过代理Proxy和反射调⽤)之后得到了返回值,此时还需要再把返回值发送回A机器,同样也需要经过序列化操作,然后再经过⽹络传输将⼆进制数据发送回A机器,⽽当A机器接收到这些返回值之后,则再次进⾏反序列化操作,恢复为内存中的表达⽅式,最后再交给A机器上的应⽤进⾏相关处理,⼀般是业务逻辑处理操作。
⽩话⽂:A去B家玩游戏,第⼀步,先打个电话确保B在家(建⽴通信,能够连得上);第⼆步,A要确认B的家有没有建好,所以要拿着要B的信息(ip、机器码、端⼝号、⽅法名、⽅法参数等)去注册中⼼上到B的地址;第三步,A要去B经过⼆进制这条路(需要序列化和反序列化);第四步,A到B家门⼝了,让管家(代理或反射)开门去把B叫出来玩(调⽤)
Eureka的⾃我保护机制
Eureka Server 在运⾏期间会去统计⼼跳失败⽐例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果刚好这个服务提供者⾮正常下线了,此时服务消费者就会拿到⼀个⽆效的服务实例,此时会调⽤失败,对于这个问题需要服务消费者端要有⼀些容错机制,如重试,断路器等。
⽩话⽂:服务实例注册到eureka之后,会和eureka维持⼼跳,当⼼跳低于⼀定阈值(85%)的时候,本来应该是删除这个实例的,但实际上eureka会有⾃我保护机制,留了⼀个假的实例,调⽤者还是可以调⽤的,只不过调⽤会触发熔断和降级
⾃我保护机制的意义