SpringCloud(一)概念及设计
来自各个博客的知识,帮助快速入门,了解相关概念。
分布式与集群
分布式与集群,形象的比喻:
小饭店原来只有一个厨师,切菜洗菜炒菜全都做。客人多了,一个厨师就忙不过来了,又请了个厨师,两个厨师做一样的事情,这两个厨师的关系是集群。为了让厨师专心炒菜,又请了个师傅负责切菜,厨师和切菜师傅的关系是分布式,一个切菜师傅也忙不过来了,又请了另一个切菜师傅,两个切菜师傅关系是集群。
书本读薄,一句话说明要用的东西
EurekaServer:相当于Spring容器,可以托管我们所有的服务;
EurekaClient:相当于一个个Class,每一个EurekaClient需要放置到容器中,统一管理起来;
Feign:相当于Spring中的@Resource注解,每一个EurekaClient引用其它服务的时候,需通过Feign引用;
Hystrix:熔断降级,相当于Spring中的异常切面,网络不通了,其它服务调用不起来了,此时需要提供有损服务;
Gateway:路由,相当于DispatcherServlet,提供统一的程序入口,每一个请求都走这个接口,然后分发到特定的服务上。
(讲完了,想详细看的,继续往下)
服务治理
功能类似于Spring容器,单机应用用Spring托管所有的Class。Cloud环境下,也需要这样一个容器,托管我们所有的服务。
使用服务治理的原因:在服务引用并不算多的时候,可以通过静态配置来完成服务的调用,但随着业务的发展,系统功能越来越复杂,相应的微服务也不断增加,此时静态配置会变得越来越难以维护。并且面对不断发展的业务,集群规模,服务的位置、服务的命名等都有可能发生变化,如果还是通过手工维护的方式,极易发生错误或是命名冲突等问题。同时,也将消耗大量的人力来维护静态配置的内容。为了解决微服务架构中的服务实例维护问题,就产生了大量的服务治理框架和产品。这些框架和产品的实现都围绕着服务注册与服务发现机制来完成对微服务应用实例的自动化管理。
服务注册:在服务治理框架中,通常都会构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机与端口号、版本号、通信协议等一些附加信息告知注册中心,注册中心按服务名分类组织服务清单。另外,注册中心还需要以心跳的方式去监测清单中的服务是否可用,若不可用需要从服务清单中剔除,达到排除故障服务的效果。
服务发现:在服务治理框架的运作下,服务间的调用不再通过指定具体的实例地址来实现,而是通过向服务名发起请求调用实现。所以,服务调用方在调用服务提供方接口时,并不知道具体的服务实例位置。因此,调用方需要向注册中心咨询服务,并获取所有服务的实例清单,以实现对具体服务实例的访问。比如:以上述服务为例,有服务C希望调用服务A,服务C就向注册中心发起咨询请求,服务注册中心就会将服务A的位置清单返回给服务C,当服务C要发起调用时,便从该清单中以某种轮询策略取出一个位置来进行服务调用(客户端负载均衡)
https://blog.csdn.net/m0_37450089/article/details/80232339?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
可选框架:
consul/eureka
二者最大的区别是Eureka保证AP, Consul为CP,因为定位不同,有时间最好两个都学。
这里又引出了 CAP 的概念,下面叨叨这个。
CAP的概念
核心问题:各个服务通过网络进行信息交互,网络出现故障,我们该如何选择?
Consistency (一致性):“all nodes see the same data at the same time”,同一时间所有节点数据一致,优先保证数据的准确性。数据更新后,服务端需要将数据同步到所有节点,客户端读取的数据要完全一致。
Availability (可用性):“Reads and writes always succeed”,读写总是成功,优先保证业务的执行。
Partition Tolerance (分区容错性):遇到某节点或网络分区故障的时候,仍然能够对外提供服务。
案例以及描述:
存在 A 和 B 两个相同功能的服务器,还有一个 C 服务器,C 读取到的数据可能来自 A 和 B 任何一个。若保证每次读取结果都正确,在 A 写入的时候,B 的读取需要加锁。如果网络较差,A 与 B 之间无法互相通知。这时候,我们就必须考虑业务上如何取舍了,该不该在 C 服务上继续使用数据呢?继续用的话,可能会读到错误的数据,但是不用的话,又需要等网络恢复。
在上述案例中面临的这个选择,就是所谓的,保证 P 的时候,需要在 C 与 A 之间做选择。
当然,不论作何选择,不代表任由错误发展,因为我们可以通过调整业务流程、代码逻辑,让最终结果是准确的。
CAP的注意点
1.cap关注的是数据
cap关注的是数据,不是系统,一个系统中,不同的数据在分区发生时,可以有不同的选择。比如说一份商品数据,在分区发生时,他的商品描述是可修改的,可在事后补偿达到最终一致,这放弃了c,但商品价格是不可修改的,因为这会导致发生交易行为时的不一致,这放弃了a。
2.未发生分区时,ca我们可以都保证
分区的发生概论是很低的,我们借用google团队的图片,google在保证99.99%可用性的同时,我们可以看到网络出现问题的概率只有7.6%。当然这和google团队的强大工程能力有关系。所以,我们架构时要考虑的是在未发生分区时如何保证数据的ca,同时也要保证分区发生时我们要选择cp,还是ap。
3.cap忽略了延迟
实际上,我们的网络是有延迟的,即便同机房,也会产生毫秒级的延迟。这意味着,我们的数据同步必然会存在毫秒级的不一致。所以我们要为不同的业务数据分配不同的策略,降低不一致产生的业务影响。甚至有的业务,如金钱业务,我们只能选择ca,单点写入,来消除不一致的影响。
4.ap并不意味着放弃了一致性
分区只是暂时的,我们需要在分区时做一些工作,来保证我们的数据能在分区结束后达到最终一致性,而BASE理论就是AP的实践。
可选框架:
CAP理论告诉我们分区发生时,CA时不可兼得的。但是我们也要清楚的认识到,CA是数据级,我们设计时需要针对不同的数据有不同的策略。同时,我们考虑不发生分区时,延时对一个分布式系统的影响。而我们设计一个系统时,更应该考虑的是整个系统的可用性和一致性双重保障。
如果要求一致性,则选择zookeeper、Consul,如金融行业
如果要求可用性,则Eureka,如电商系统
https://www.jianshu.com/p/b0c8c9fb4763
负载均衡
负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行。
可选框架:
Ribbon:是一个基于 HTTP 和 TCP 的负载均衡的工具。
Feign:是在 Ribbon 的基础上改进的框架,毫无疑问是目前最优选择。
服务熔断与降级
服务熔断:
也叫做过载保护,同时在线人数过多、服务响应超时等,需要暂时停止对该服务的调用。
服务降级:
对于无法及时、准确响应的情况,提供有损的服务,返回一些错误处理信息。
可选框架:Hystrix
微服务网关
功能上类似于DispatcherServlet,不外乎统一入口、鉴权、授权、过滤、流量统计、请求分发等等等:
认证和安全 - 对每一个resource进行身份认证
追踪和监控 - 实时观察后端微服务的TPS、响应时间,失败数量等准确的信息
日志 - 记录所有请求的访问日志数据,可以为日志分析和查询提供统一支持
动态路由 - 动态的将request路由到后端的服务上去
压力测试 - 逐渐的增加访问集群的压力,来测试集群的性能
限流 - allocating capacity for each type of request and dropping requests that go over the limit
静态响应 - 直接在网关返回一些响应,而不是通过内部的服务返回响应
可选框架:
gateway、zuul
区别:
1、内部实现:
gateway对比zuul多依赖了spring-webflux,在spring的支持下,功能更强大,内部实现了限流、负载均衡等,扩展性也更强,但同时也限制了仅适合于Spring Cloud套件
zuul则可以扩展至其他微服务框架中,其内部没有实现限流、负载均衡等。
2、是否支持异步
zuul仅支持同步
gateway支持异步。理论上gateway则更适合于提高系统吞吐量(但不一定能有更好的性能),最终性能还需要通过严密的压测来决定
3、框架设计的角度
gateway具有更好的扩展性,并且其已经发布了2.0.0的RELESE版本,稳定性也是非常好的
4、性能
WebFlux 模块的名称是 spring-webflux,名称中的 Flux 来源于 Reactor 中的类 Flux。Spring webflux 有一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好。使用非阻塞 API。Websockets 得到支持,并且由于它与 Spring 紧密集成,所以将会是一个更好的开发体验。
Zuul1 是一个基于阻塞io的API Gateway。Zuul已经发布了Zuul 2.x,基于Netty,也是非阻塞的,支持长连接,但Spring Cloud暂时还没有整合计划。