白话文:Spring Cloud是一个微服务架构全家桶
是一个分布式系统,它是将单体应用划分成小的服务单元,微服务之间使用HTTP的API进行访问操作。每个微服务都独自运行在自己的进程中独立部署,而且每个微服务可以使用单独的语言开发以及不同的数据库存储。
DOTO 等删掉。。
服务间调用的问题:有网络问题、延迟开销、容错、带宽、安全等问题
独立的数据库,分布式事务问题:每个微服务都有自己的数据库,这就是所谓的去中心化的数据管理。这种模式的优点在于不同的服务,可以选择适合自身业务的数据,比如订单服务可以用 MySQL、评论服务可以用 Mongodb、商品搜索服务可以用 Elasticsearch。
目前最理想的解决方案就是柔性事务中的最终一致性
测试的难度增加:服务和服务之间通过接口来交互,当接口有改变的时候,对所有的调用方都是有影响的,这时自动化测试就显得非常重要了,如果要靠人工一个个接口去测试,那工作量就太大了。这里要强调一点,就是 API 文档的管理尤为重要。
运维的难度增加:在采用传统的单体应用时,我们可能只需要关注一个 Tomcat 的集群、一个 MySQL 的集群就可以了,但这在微服务架构下是行不通的。当业务增加时,服务也将越来越多,服务的部署、监控将变得非常复杂,这个时候对于运维的要求就高了。
使用SpringBoot开发分布式微服务时,我们面临以下问题:
(吐槽:这些是SpringCloud的优势吗,怎么是一堆问题。。。后续再理解)
与分布式系统相关的复杂性:这种开销包括网络问题,延迟开销,带宽问题,安全问题。
服务发现:服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉及一个服务目录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。
冗余:分布式系统中的冗余问题。
负载平衡:负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机集群,网络链路,中央处理单元,或磁盘驱动器的分布。
性能问题:由于各种运营开销导致的性能问题。
部署复杂性:Devops技能的要求。
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,**快速返回“错误”的响应信息
**。当检测到该节点微服务调用响应正常后恢复调用链路。
白话文:下游服务不可用的时候,会停止调用,并返回错误相应信息
在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内调用20次,如果失败,就会启动熔断机制。熔断机制的注解@HystrixCommand。
服务降级,一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。这样做,虽然水平下降,但好歹可用,比直接挂掉强。
白话文:熔断之后,报错太难看了,那就自己本地造一个回调
zookeeper 是CP原则(强一致性和分区容错性)。 zookeeper当主节点Master故障时,zk会在剩余节点重新选择主节点,耗时过长,虽然最终能够恢复,但是选取Master节点期间会导致服务不可用,这是不能容忍的。
eureka是AP原则(可用性和分区容错性)。 eureka各个节点是平等的,一个节点挂掉,其他节点仍会正常保证服务。
白话文:当节点出故障的时候,zookeeper因为强一致性,必须选好Master之后,才能用;Eureka因为高可用,一个节点挂了其他的节点顶上
白话文:Boot是快速开发的框架,有什么特点(内置tomcat、一键启动、简化配置等等),Cloud是微服务框架的集合,有啥啥啥的(牛逼的把全家都说出来)
在计算中,负载均衡可以改善计算机,计算机集群,网络连接,中央处理器单元或者磁盘驱动琪等多种计算资源和工作负载分布。负载均衡就是优化资源使用,最大吞吐量,最小化响应时间并且避免任何单一资源的过载。使用多个组件进行负载均衡,而不是单个组件可能会通过冗余来提高可靠性和可用性。负载均衡通常涉及专用软件或者硬件,例如多层交换机或者域名系统服务器进程。
白话文:让多台机子处理并发请求,并快速响应,避免单台机子压力太大而挂掉。
Hystrix是Netflix针对微服务分布式系统采用的熔断保护中间件,相当于电路中的保险丝。 在微服务架构下,很多服务都相互依赖,如果不能对依赖的服务进行隔离,那么服务本身也有可能发生故障,Hystrix 通过HystrixCommand对调用进行隔离,这样可以阻止故障的连锁反应,能够让接口调用快速失败并迅速恢复正常,或者回退并优雅降级。
白话文:hystrix就是保险丝,当下游服务不可用时,快速返回失败或者进行降级操作,而不是傻傻的等待响应
tips小知识:hystrix是基于线程池隔离调用,基于熔断器快速失败
Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败
白话文:检测调用失败频率太高的时候,直接打开断路器,快速失败,保护资源,之后尝试关闭断路器
断路器逻辑:
1、正常情况下,断路器关闭,可正常访问;
2、在一段时间内请求失败率达到阈值,断路器打开;
3、打开后进入“半开”状态。此时可允许一个请求访问依赖的服务,若成功则关闭断路器,若失败则继续保持打开状态。
其他方式实现容错:https://blog.51cto.com/u_13593129/2469355
首先要解决通讯的问题:即A机器想要调用B机器,首先得建立起通信连接。
主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。
通常这个连接可以是按需连接(需要调用的时候就先建立连接,调用结束后就立马断掉),也可以是长连接(客户端和服务器建立起连接之后保持长期持有,不管此时有无数据包的发送,可以配合心跳检测机制定期检测建立的连接是否存活有效),多个远程过程调用共享同一个连接。
要解决寻址的问题,也就是说,A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么。
通常情况下我们需要提供B机器(主机名或IP地址)以及特定的端口,然后指定调用的方法或者函数的名称以及入参出参等信息,这样才能完成服务的一个调用。
可靠的寻址方式(注册中心)是RPC的实现基石,比如可以采用Redis或者Zookeeper来注册服务等等。
当服务提供者启动的时候,需要将自己提供的服务注册到指定的注册中心,以便服务消费者能够通过服务注册中心进行查找;
当服务提供者由于各种原因致使提供的服务停止时,需要向注册中心注销停止的服务;
服务的提供者需要定期向服务注册中心发送心跳检测,服务注册中心如果一段时间未收到来自服务提供者的心跳后,认为该服务提供者已经停止服务,则将该服务从注册中心上去掉
服务的调用者启动的时候根据自己订阅的服务向服务注册中心查找服务提供者的地址等信息;
当服务调用者消费的服务上线或者下线的时候,注册中心会告知该服务的调用者;
服务调用者下线的时候,则取消订阅。
当A机器上的应用发起一个RPC调用时,调用方法和其入参等信息需要通过底层的网络协议如TCP传输到B机器,由于网络协议是基于二进制的,所有我们传输的参数数据都需要先进行序列化(Serialize)或者编组(marshal)成二进制的形式才能在网络中进行传输。然后通过寻址操作和网络传输将序列化或者编组之后的二进制数据发送给B机器。
当B机器接收到A机器的应用发来的请求之后,又需要对接收到的参数等信息进行反序列化操作(序列化的逆操作),即将二进制信息恢复为内存中的表达方式,然后再找到对应的方法(寻址的一部分)进行本地调用(一般是通过生成代理Proxy去调用,
通常会有JDK动态代理、CGLIB动态代理、Javassist生成字节码技术等),之后得到调用的返回值。
B机器进行本地调用(通过代理Proxy和反射调用)之后得到了返回值,此时还需要再把返回值发送回A机器,同样也需要经过序列化操作,然后再经过网络传输将二进制数据发送回A机器,而当A机器接收到这些返回值之后,则再次进行反序列化操作,恢复为内存中的表达方式,最后再交给A机器上的应用进行相关处理,一般是业务逻辑处理操作。
白话文:A去B家玩游戏,第一步,先打个电话确保B在家(建立通信,能够连得上);第二步,A要确认B的家有没有建好,所以要拿着要B的信息(ip、机器码、端口号、方法名、方法参数等)去注册中心上找到B的地址;第三步,A要去找B经过二进制这条路(需要序列化和反序列化);第四步,A到B家门口了,让管家(代理或反射)开门去把B叫出来玩(调用)
原文地址:https://blog.csdn.net/xiaole0313/article/details/103209782
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,此时会调用失败,对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。
白话文:服务实例注册到eureka之后,会和eureka维持心跳,当心跳低于一定阈值(85%)的时候,本来应该是删除这个实例的,但实际上eureka会有自我保护机制,留了一个假的实例,调用者还是可以调用的,只不过调用会触发熔断和降级
它不会从注册列表中剔除因长时间没收到心跳导致租期过期的服务,而是等待修复,直到心跳恢复正常之后,它自动退出自我保护模式。这种模式旨在避免因网络分区故障导致服务不可用的问题。例如,两个客户端实例 C1 和 C2 的连通性是良好的,但是由于网络故障,C2 未能及时向 Eureka 发送心跳续约,这时候 Eureka 不能简单的将 C2 从注册表中剔除。因为如果剔除了,C1 就无法从 Eureka 服务器中获取 C2 注册的服务,但是这时候 C2 服务是可用的。
白话文:为了高可用,避免网络抖动,导致服务提供者莫名其妙下线(冤死)
Ribbon是一个有负载均衡功能的http客户端(基于HTTP和TCP),它不像 spring cloud 服务注册中心、配置中心、API 网关那样独立部署,但是它几乎存在于每个 spring cloud 微服务中。包括 feign 提供的声明式服务调用也是基于该 Ribbon实现的。(feign内置了ribbon)
关键字:客户端负载均衡、基于http和TCP
Feign 运行在消费者端的,使用 Ribbon 进行负载均衡,所以 Feign 直接内置了 Ribbon
Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端
Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。
Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务
Feign本身不支持Spring MVC的注解,它有一套自己的注解(和OpenFeign的区别)
关键字:RESTful、Http客服端
OpenFeign在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等。
OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,
并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
白话文:OpenFeign支持SpringMvc的注解,多了个@FeignCLient
原文链接:https://blog.csdn.net/zimou5581/article/details/89949852
白话文:ribbon调用需要自己构建httpRibbon ,feign将要调用的方法定义成接口,并加个注解(就像我们调用自己本地的方法一样)
原文链接:https://blog.csdn.net/zimou5581/article/details/89949852