溪源的Java笔记—微服务

溪源的Java笔记—微服务

前言

微服务架构是一种架构风格和架构思想,它提倡将系统业务按照功能拆分为更加细粒度的服务,即每一个服务都是一个独立的应用。这些应用对外提供公共API用于应用调度。本篇博客从服务治理、微服务网关、Netty等方面介绍微服务。

分布式可参考我的博客溪源的Java笔记—分布式

正文

服务治理

服务注册发现

  • 服务注册就是维护一个登记簿,它管理系统内所有的服务地址。当新的服务启动后,它会向登记簿交待自己的地址信息。
  • 服务的依赖方直接向登记簿要 Service Provider 地址就行了。
  • 当下用于服务注册的工具非常多 ZooKeeperConsulNacos, Eureka等。

分布式的服务治理,其背后的逻辑其实就是分布式数据一致性。

Eureka
Eureka是一项基于REST(代表性状态转移)的服务,主要在AWS云中用于定位服务,以实现负载均衡和中间层服务器的故障转移。它是微服务框架中最核心和最基础的模块,它主要用来实现微服务实例的自动化注册与发现。

Eureka由2个部分组成:服务端 和 客户端:

  • 客户端通过注解的方式嵌入程序中,服务器和客户端之间会进行周期性心跳检测 ,如果心跳不存在时,该服务节点会从服务注册表中移除。并且我们要知道Eureka的心跳检测是基于SpringBoot Actuator来实现的。
  • 各个服务节点 通过注册中心得注册信息以Rest方式来实现调用。

Eureka的三种角色:服务注册中心、服务提供者、服务消费者,事实上一个结点既可以是服务提供者 、也可以是服务消费者。

微服务节点之间通过续约和续期地方式实现服务清单的一致性:

  • 续约Eureka Client会周期(默认30秒)地向Eureka Server发送心跳以续约(Renew)自己的信息。
  • 续期Eureka Server会定期(默认60秒)执行一次失效服务检测功能,它一会检查超过一定时间(默认是60秒)没有续约的Eureka Client,发现并注销该节点。

Consul
Consul是一个spring cloud 中集成好的开源的分布式的服务注册发现中心。
Go语言编写。支持健康检查,多数据中心还支持k-v存储,采用RAFT一致性算法,保证强一致性,可用性。并且和docker完美兼容。

Consul本身也是一种服务治理中心,相对于Eureka而言:

  • Consul牺牲了部分的性能,保证了服务的强一致性。
  • Eureka只要服务注册到主节点,就认为服务注册成功,不关其他节点是否可以正常调用。

Nacos
Nacos提供了四个主要功能

  • 服务发现和服务运行状况检查(服务治理)Nacos使服务易于注册自己并通过DNSHTTP接口发现其他服务。Nacos还提供服务的实时运行状况检查,以防止向不正常的主机或服务实例发送请求。
  • 动态配置管理:动态配置服务使您可以在所有环境中以集中和动态的方式管理所有服务的配置。Nacos消除了在更新配置时重新部署应用程序和服务的需求,这使配置更改更加有效和敏捷。
  • 动态DNS服务Nacos支持加权路由,使您可以更轻松地在数据中心内的生产环境中实施中间层负载平衡,灵活的路由策略,流控制和简单的DNS解析服务。它可以帮助您轻松实现基于DNS的服务发现,并防止应用程序耦合到特定于供应商的服务发现API
  • 服务和元数据管理(分布式配置)Nacos提供了易于使用的服务仪表板,可帮助您管理服务元数据,配置,kubernetes DNS,服务运行状况和指标统计信息。

Nacos 既支持AP也支持CP:

  • 作为服务治理中心(替代 Spring Cloud Eureka):采用的是AP模式,牺牲强一致性,从而保证存在节点宕机也不会影响正常的服务节点提供服务。
  • 作为配置中心(替代Spring Cloud Config):采用的是CP模式,牺牲数据可用性,确保分布式下配置参数的强一致性。

微服务网关

网关是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能提供路由请求、鉴权、监控、缓存、限流等功能。

溪源的Java笔记—微服务_第1张图片

网关的存在体现了设计模式中的外观模式:

  • 外观模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行。
  • 外观模式提供一个高层次的接口,使得子系统更易于使用。

微服务使用网关的意义
不同的微服务一般会有不同的网络地址,而客户端可能需要调用多个服务接口才能完成一个业务需求,若让客户端直接与各个微服务通信,会有以下问题:

  1. 客户端会多次请求不同微服务,增加了客户端复杂性
  2. 存在跨域请求,处理相对复杂
  3. 认证复杂,每个服务都需要独立认证
  4. 难以重构,多个服务可能将会合并成一个或拆分成多个

微服务网关介于服务端与客户端的中间层,所有外部服务请求都会先经过微服务网关客户只能跟微服务网关进行交互,无需调用特定微服务接口,使得开发得到简化。

微服务使用的网关主要有两种ZuulGateway,这里简单做一下对比:

  • 从性能方面比较,两种产品在流量小的场景下性能表现差不多;
  • 并发高的场景下Gateway性能要好很多。从开发方面比较,Zuul1编程模型简单,易于扩展;
  • Gateway编程模型稍难,代码阅读难度要比Zuul高不少,扩展也稍复杂一些。

某种意义上GateWay被作为Zuul的取代品。
溪源的Java笔记—微服务_第2张图片

Netty原理

BIO的阻塞问题

  • 当用户线程发出 IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block 状态。如果数据没有就绪,就会一直阻塞在read方法。
  • 无论是客户端还是服务器,同一时间只能发送或者接受一个信息。处于等待回复的间隔,便是"阻塞"问题。即使使用多线程的方式服务器端的accept()read()方法依旧会被阻塞。

NIO同步非阻塞

  • NIO本身采用的是多路复用IO模型:通过一个线程不断去轮询多个 socket的状态,只有当socket真正有读写事件时,才真正调用实际的IO读写操作。并且这种轮询是采用内核的方式,效率比直接使用用户线程高很多。
  • 传统 IO 基于字节流和字 符流进行操作,而 NIO 基于 ChannelBuffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。

NIO的非阻塞性

  • 非阻塞读:使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。
  • 非阻塞写:一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。

线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道。

Channel通道
Channel通道,是用于应用程序与操作系统进行交互的渠道。
NIOChannel的是主要实现类:

  • FileChannel:用于传输文件IO的通道
  • DatagramChannel:用于传输UDP数据的通道
  • SocketChannel:客户端使用SocketChannel来与服务器建立连接
  • ServerSocketChannel: 服务器ServerSocketChannel 来等待客户端的连接

通道类似于流,但是有区别:

  1. 通道既可以读数据,也可以写数据。但是流的读写操作是单向的。
  2. 通道可以异步读取
  3. 通道的数据总是要经过缓冲区

Buffer缓冲区
缓冲区,实际上是一个容器,是一个连续数组。Channel 提供从文件、 网络读取数据的渠道,但是读取或写入的数据都必须经由 Buffer

Selector

  • Selector 能够检测多个注册的通道上是否有事件发生,如果有事件发生,便获取事件然后针对每个事件进行相应的响应处理。
  • 用一个单线程就可以管理多个通道,也就是管理多个连接,新建的通道都要向选择器注册。
  • 这样使得只有在连接真正有读写事件发生时,才会调用函数来进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护多个线程,并且避免了多线程之间的上下文切换导致的开销。
  • selector进行select()操作可能会产生阻塞,但是可以设置阻塞时间,并且可以用wakeup()唤醒selector,所以NIO是非阻塞IO
  • 一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。

AIO异步非阻塞
异步的体现:

  • 同步的I/O流 服务器端不会"主动"联系客户端 ,但是AIO在数据准备完成后,会主动通知”客户端“
  • 异步的I/O是交给OS处理,而异步应用自己会处理。

AIO与NIO的区别:

  • AIO与NIO都是通过管道的方式进行I/O操作,但是AIO每一个处理器与通道都是独立的、一一对映,NIO是通过选择器进行匹配。

Netty
Netty是一个NIO客户端服务器框架:

  • 它可快速轻松地开发网络应用程序,例如协议服务器和客户端。
  • 它极大地简化和简化了网络编程,例如TCPUDP套接字服务器。
  • 提供了Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果。
  • Netty 采用了串行无锁化设计,在 IO 线程内部进行串行操作,避免多线程竞争导致的性能下降。

Netty线程模型
Netty 的线程模型是基于NIOSelector构建的,纯粹的selector存在半包问题。

半包问题

  • TCP/IP在发送消息的时候,可能会拆包,这就导致接收端无法知道什么时候收到的数据是一个完整的数据。
  • 在传统的BIO中在读取不到数据时会发生阻塞,但是NIO不会。为了解决NIO的半包问题,Netty提供了两种方式解决闭包问题: 包定长FixedLengthFrameDecoder和包分隔符DelimiterBasedFrameDecoder

Netty模型Reactor模式
Reactor模式(反应器模式)是一种处理一个或多个客户端并发交付服务请求的事件设计模式。当请求抵达后,服务处理程序使用I/O多路复用策略,然后同步地派发这些请求至相关的请求处理程序。

Reactor模式又可以被细分为:

  • Reactor单线程模型
  • Reactor多线程模型
  • 主从Reactor多线程模型

Reactor单线程模型
Reactor单线程模型,指的是所有的 IO操作都在同一个NIO线程上面完成,Reactor模式使用的是异步非阻塞IO,所有的IO操作都不会导致阻塞,理论上一个线程可以独立处理所有IO相关的操作,这些操作包括:

  • 建立TCP连接
  • 接受或者发送消息

Reactor多线程模型
Reactor多线程模型与单线程模型大的区别就是有一组 NIO 线程处理 IO操作:

  • 有一个 NIO线程Acceptor线程用于监听服务端,接收客户端的TCP连接请求。
  • 一个NIO线程池:处理请求,负责消息的读取、解码、编码和发送等。

主从Reactor多线程模型
接收客户端连接的不再是个1个单独的 NIO线程,而是一个独立的 NIO线程池,即mainReactor线程池。
溪源的Java笔记—微服务_第3张图片

主从Reactor多线程模型可以理解为是一种"boss接活,让work干"的模式:

  • mainReactor线程池用来接收请求,与客户端进行握手验证
  • subReactor线程池用来处理请求,不直接与客户端进行连接
  • 这种模式下只有mainReactor池接受到完整的数据后,subReactor池才会处理,这样就避免了半包的问题。

Spring Cloud

Dubbo与Spring Cloud的差异:

  • Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。
  • Spring Cloud 基于 Spring Boot,为微服务体系开发中的架构问题,提供了一整套的解决方案:包括服务注册与发现,服务消费,服务保护与熔断,网关,分布式调用追踪,分布式配置管理等。

Dubbo性能优于 Spring Cloud 的原因:

  • 因为 Dubbo 采用单一长连接和 NIO 异步通讯(保持连接/轮询处理),使用自定义报文的 TCP 协议。
  • 序列化使用定制 Hessian2框架,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况,但不适用于传输大数据的服务调用。
  • Dubbo的兼容性比较好,可以根据实际业务选择其他的通讯协议或序列化协议。
  • Spring Cloud 直接使用 HTTP 协议的REST。(REST为表述性状态传递)。

SpringCloud的子项目
1.Spring Cloud Starters:Spring Cloud的基础组件。

2.Spring Cloud Config:配置管理工具,支持使用Git存储配置内容,可以使用它实现应用配置的外部化存储, 支持客户端配置信息刷新、加密和解密等配置内容

3.Spring Clond Netflix:其中包括了:

  • Eureka:服务发现框架
  • Ribbon:客户端负载均衡
  • Hystrix:熔断机制
  • Zuul:服务端负载均衡
  • Feign:声明式调用框架

Eureka 服务发现框架(服务治理)

Eureka高可用注册中心

  • 单节点时注册中心不需要注册自己,但是高可用注册中心,节点要向出自己以外的服务中心进行注册

  • 不需要重新创建新项目 只要多配制application.properties 运行时 java -jar xxx.jar--spring.profiles.active=ek8761 (命令行配置优先级最高)

Eureka客户端的实现

  • 启动类@EnableEurekaClient中的@EnableDiscoveryClient用来实现发现服务,帮助与Eureka Server相互协作
  • 客户端在加载过程中 首先会加载Region,接着会加载Zone,一个应用只有一个Region,但是可以有多个Zone(适用于跨机房、跨地区配置)
  • Ribbon的默认策略会优先访问通客户端处于一个Zone中的服务端实例,只有当同一个Zone中没有可用服务端实例才会访问其他Zone的实例

Eureka框架与负载均衡
Ribbon是一个基于HTTPTCP的客户端负载均衡器:

  • 只使用ribbon时需要在客户端配置ribbonServerList服务端列表去轮询以达到负载均衡的作用。
  • 当与Eureka结合,扩展成从Eureka注册中心获取服务端列表。ribbon将确认服务端是否启动的职责委托给Eureka
  • Eureka服务端中保存着所有的服务的实例清单,当新的客户端进行注册时,会从服务端获取该份清单。
  • 微服务对请求进行负载均衡时,便会从该份清单中以某种轮询策略选取一个组价进行请求的处理。

我们通常所说的服务端负载均衡(硬件负载均衡和软件负载均衡)和客户端负载均衡的差异就在于这份清单的存储位置:

  • 服务端负载均衡只有服务器保存该份清单(如nginx),而客户端负载均衡(ribbon)每一个客户端组件都保存完整的服务清单。

通过设置nginx.conf的服务器端负载均衡的弊端在于:

  • 通过这种静态配置来维护这份清单会随着业务增加而越来越困难。而通过Eureka注册服务,服务的调用可以通过向服务名发起请求而实现。

RestTemplate

  • 该对象会使用Ribbon的自动化配置,同时通过配置@LoadBalanced还能开启客户端负载均衡。
  • @LoadBalanced会使用拦截器的方式来实现其负载均衡,如getForEntityurl,body类型,参数)会通过url从服务清单中获取服务节点

GET请求

  • 请求指定的页面信息,并返回实体主体。
  • getForEntityurl,body类型,参数)
  • 该方法返回的是ResponseEntity,该对象是SpringHttp请求响应的封装,它包括:http请求状态、请求头、请求体对象

POST请求

  • 向指定资源提交数据进行处理请求
  • postForEntity(url,参数,返回对象类型)

PUT请求

  • 只提交数据,不会返回结果
  • put(url,参数,序列号)

DELETE请求

  • 请求服务器删除指定的页面
  • delete(url,序列号)

Spring Eureka保护机制、重试机制

Eureka保护机制

  • Eureka会在超过85%的实例失去心跳而出发保护机制,注册中心会保留此时的所有节点,以实现服务间依然可以相互调用的场景,即时其中有部分故障节点,但这样可以继续保障绝大数服务可以正常使用。

重试机制在请求超时后进行重试:

  • 借助Spring Retry实现重试
  • 借助Ribbon实现重试
  • 借助Zuul实现重试
  • 借助Feign实现重试

Spring Cloud Hystrix 熔断机制
Spring Cloud Hystrix,该框架的使用目标在于通过控制那些访问远程系统、服务和 第三方库的节点,从而对延迟和故障提供更强大的容错能力。

  • Hystrix具有服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。
  • 将分布式业务的正向操作和逆向操作分离,并通过设置最长等待时间、抛出异常等方法让逆向操作自动执行,解决事务补偿机制中反向操作,导致其他业务无法执行,而造成的系统雪崩。
  • 通过在启动类添加 @EnableCircuitBreaker来开启熔断器功能

Hystrix的工作流程

  1. 创建HystrixCommand(单个结果)或HystrixObservableCommand(多个结果)对象
    用来表示对依赖服务的操作请求,同时传递所有需要的参数;(这里使用了命令模式 将事件通过命令的形式 委派特定对象执行)
  2. 命令执行 :有异步执行、同步执行、返回Observable事件源对象、返回多个Observable事件源对象这四种事件源通常会被订阅者所监控(这里的设计是观察者-订阅者模式)
  3. 结果是否被缓存 如果命中缓存,会即刻返回Observable事件源对象
  4. 判断断路器是否被打开 如果断路器被打开,执行fallback方法
  5. 线程池/请求队列/信号量是否占满 Hystrix的线程池设计采用了“舱壁模式”
  6. HystrixObservableCommand.construct() 返回多个结果 或HystrixCommand.run()返回单一的结果计算断路器的健康程度
  7. fallback处理:当服务执行失败时,“服务降级”,执行fallback函数
  8. 返回成功的响应:当Hystrix命令执行成功之后,它会将处理结果直接返回或者以Obervable的形式返回。

断路器健康程度
熔断器熔断服务的决定因素:
当前服务健康状态=请求失败数/请求总数 A设定阈值 当前请求数B

  • 熔断器关闭 请求安全通过
  • A>B 请求安全通过
  • A

服务降级

  • 如果设置fallback方法,进入fallback方法
  • 通过fallback给用户一个友好的提示结果

“舱壁模式”
“舱壁模式”:Hystrix使用该模式实现线程池的隔离:

  • 它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况(线程被长时间挂起),也只会对该依赖服务的调用产生影响,而不会拖慢其他的依赖服务。这样的设计模式提高了应用的健壮性。
  • 使用线程隔离为系统在稳定性和灵活性带来了巨大的提升,但是增加了线程池一定的额外开销。Hystrix在部分地方使用信号量的方式来控制单个依赖服务的并发度,但这种方式不支持设置超时和实现异步访问。

Hystrix的请求缓存

  • @CacheResult:该注解来标记请求命令返回的结果应该被缓存,它必须与@HystrixCommand注解结合使用
  • @CacheRemove:该注解来让请求命令的缓存失效,失效的定义根据KEY来设定@CacheRemove(commadKey="请求的函数名")
  • @CacheKey:用来在请求命令的参数上做标记,作为缓存的key值,如果没有标注则会使用所有的参数。
  • @cacheKeyMethod:配置一个方法来指定Key生成方式 优先级高于CacheKey

请求合并

  • 在高并发的情况下,会出现通讯消耗严重、排队和响应延迟的情况
  • Hystrix提供了HystrixCollapser来实现请求的合并,以减少通讯的消耗好线程的占用。
  • HystrixCollapser将使用一个合并处理器,将处于一个很短的时间窗(默认10毫秒)内对同一依赖服务的多个请求进行整合并以批量的方式发起请求的功能。

使用场景:

  • 该请求本身就是一个高延迟的命令
  • 一个时间窗口下会有很多请求(高并发)
@HystrixCollapser(batchMethod = "helloService",collapserProperties = {
     @HystrixProperty(name ="timerDelayInMilliseconds",value = "100")})

@HystrixCommand
@Override public List<User> helloService(List<String> ids) {
     
    ResponseEntity<List> responseEntity =restTemplate.getForEntity("http://springcloud-eureka-client-user/hello?id={1}",List.class,StringUtils.join(ids,","));
  return   responseEntity.getBody();
}

Hystrix配置
Hystrix根据不同业务场景提供了非常丰富和灵活的配置方法。@HystrixCommand(commandProperties = {@HystrixProperty(name="属性1",value = "值1"),@HystrixProperty(name="属性名2",value = "值2")})

提供了5类配置属性:

  • execution配置:控制的是HystrixCommand.run()的执行。
  • fallback配置:用来控制HystrixCommand.getFallback()的执行。这些属性同时适用于线程池的信号量的隔离策略。
  • circuitBreaker配置:断路器的属性配置,用来控制HystrixCircuitBreaker的行为。
  • metrics配置:HystrixCommandHystrixObservableCommand执行中的指标信息。
  • requestContext配置:涉及HystrixCommand使用的HystrixRequestContext的设置。

声明式服务调用:Spring Cloud Feign

  • Feign整合了Spring Cloud RibbonSpring Cloud Hystrix,同时提供了一种声明式的Web服务客户端定义方式。

  • 所有通过Feign我们可以通过注解的方式 快速的调用服务,并且自动回开启客户端负载均衡。

简单地说 Feign能够对RestTemplate进行进步封装。

Dubbo

Dubbo来自于阿里巴巴,它是一个分布式服务框架,致力于提供高性能和透明化的PRC远程调用服务调用方案。
溪源的Java笔记—微服务_第4张图片

Dubbo的的特点

  • 通过spring配置的方式即可完成服务化,对于应用无入侵。(SpringCloud有一定的入侵)
  • 通过maveninstall &deploy命令把interfaceModel层发布到仓库中,服务调用方只需要依赖interface和model层即可。
  • 通过zookeeper设置达到注册服务和心跳检测,通过GateWay前置网关(Spring Cloud使用Zuul实现负载均衡将请求转向Eureka服务器)隔绝外部直接调用原子服务的风险
  • 它是基于Dubbo SPI来实现的,其基本原理是Java SPI机制。

Dubbo支持的通信协议和序列化协议
通讯协议:(10种)

  1. Dubbo 默认协议:议采用单一长连接和 NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
  2. REST 协议: 基于标准的Java REST API实现的REST调用支持
  3. Hessian 协议Hessian 协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现
  4. HTTP 协议:需同时给应用程序和浏览器 JS 使用的服务。
  5. dubbo rpc jsonrpc:json-rpc是基于json的跨语言远程调用协议
  6. WebService 协议:系统集成,跨语言调用
  7. RMI 协议RMI 协议采用 JDK 标准的 java.rmi.* 实现,采用阻塞式短连接和 JDK 标准序列化方式。
  8. Thrift 协议:使用Thrift实现PRC协议
  9. Redis 协议:基于redis实现RPC协议
  10. Memcached 协议:基于Memcached实现RPC协议
    溪源的Java笔记—微服务_第5张图片

序列化协议:(6种)

  • dubbo-hessian-lite:是官方 hessian 的一个 Apache Dubbo 私有版本
  • Apache Avro:是一个数据序列化系统。
  • Jdk 序列化Java自带的序列号工具
  • JSON - fastjson:一个Java版本内的 JSON 解析器/生成器
  • FST: 一个快速的Java序列化工具
  • Kryo:是一个Java版本的快速有效的二进制对象序列化框架
    溪源的Java笔记—微服务_第6张图片

Dubbo 核心部件:

  • Provider: 暴露服务的提供方,可以通过jar或者容器的方式启动服务(需要启动 使用Docker容器)
  • Consumer:调用远程服务的服务消费方。
  • Registry: 服务注册中心和发现中心。(zookeeper
  • Monitor: 统计服务和调用次数,调用时间监控中心。(dubbo的控制台页面中可以显示,目前只有一个简单版本)
  • Container:服务运行的容器。

溪源的Java笔记—微服务_第7张图片

Dubbo调用的流程

Provider

  1. start 启动服务。
  2. register 注册服务到注册中心。

Consumer

  1. subscribe 向注册中心订阅服务,只订阅使用到的服务。
  2. 首次会拉取订阅的服务列表,缓存在本地,notify 当服务发生变化时,获取最新的服务列表,更新本地缓存。

invoke调用

  • Consumer 直接发起对 Provider 的调用,无需经过注册中心。而对多个 Provider 的负载均衡,Consumer 通过cluster 组件实现。

count监控

  • ConsumerProvider 都异步通知监控中心。

dubbo与Apache Thrift的区别

  1. dubbo 本身是一个综合的SOA解决方案,thrift仅是一个rpc服务框架;

  2. dubbo当前主要用作java, thrift可以用作目前所熟知的各种语言;

  3. dubbo可以使用thrift作为rpc服务组件,dubbo也有自带的rpc组件

Dubbo服务高可用机制
Dubbo 容错机制
容错机制值得是服务容忍错误的能力,当系统出现网络延迟、网络中断、服务异常等原因,造成当前服务暂时不可用,Dubbo提供了容错机制来优雅地帮助服务调用者处理这类错误。

Dubbo默认提供了6种容错模式

  1. Failover Cluster(默认):失败自动切换。当服务调用失败后,会切换到集群中的其他机器进行重试,默认重试次数为2,通过属性retries=2可以修改次数,但是重试次数增加会带来更长的响应延迟。(这种容错模式通常用于读操作)
  2. Failfast Cluster:快速失败。当服务调用失败后,立即报错,也就是指发起一次调用。(这种模式通常用于写操作,这种模式可以防止网络等问题导致数据重复新增,它等同于Failover Cluster retries=0
  3. Failsafe Cluster:失败安全,出现异常时,直接忽略异常。(这种模式处理的数据相对而言不太重要)
  4. Failback Cluster:失败后自动回复。服务调用出现异常时,在后台记录这条失败的请求定时重发。(这种模式适合用于消息通知操作,保证这个请求一定发送成功,可以解决短期网络拥塞导致请求的丢失)
  5. Forking Cluster:并行调用集群中的多个服务,只要其中一个成功就返回。可以通过forks=2来设置最大并行数。(这种模式要保证请求的幂等性)
  6. Broadcast Cluster:广播调用所有的服务提供者,任意一个服务报错则表示服务调用失败。(这种模式需要所有节点都是正常的才能被调用)

服务调用者容错机制的配置方式容错机制既可以在服务调用者中配置或在服务提供者中配置

  1. 在服务调用者中配置只对该调用者起作用(其他调用节点采用默认的)
  2. 在服务服务者中配置对所有调用者起作用
  3. 调用者的配置优先级高于服务者

Dubbo 负载均衡机制
Dubbo提供了4种负载均衡策略,分别是:

  1. Random LoadBalance随机算法(默认):可以针对性能较好的服务器设置较大的权重值,权重值越大,随机的概率越大。

  2. RoundRobin LoadBalance轮询:安装公约后的权重设置轮询比例。

  3. LeastActive LoadBalance最少活跃调用数:处理较慢的节点将会收到更少的请求。

  4. ConsistentHash LoadBalance一致性Hash:相同参数的请求总是发送到同一个服务提供者。

Dubbo服务降级机制
服务降级是一种系统保护策略,当服务器访问压力较大时,可以根据当前业务情况对不重要的服务降级,以保证核心服务的正常进行。服务降级可以分为两类:

  • 人工降级:具有一定的前置性,比如在电商大促之前,关闭某些非核心服务,比如评价等
  • 自动降级:当系统出现某些异常时自动触发“补偿性响应”

Dubbo 提供了Mock配置来实现服务降级,它会在一下情况触发:

  • Dubbo服务者不提供服务
  • Dubbo服务超时

Mock本身是一种模拟失败的行为。服务降级mock的级别:

  • false,不调用mock服务
  • true,当服务调用失败时,使用mock服务。
  • default,当服务调用失败时,使用mock服务。
  • force,强制使用Mock服务(不管服务能否调用成功)。

SpringCloud Alibaba

Spring Cloud Alibaba主要为微服务开发提供一站式的解决方案,使开发者通过SpringCloud编程模型轻松地解决微服务架构下的
各种问题。

  • 流量控制和服务降级:使用阿里巴巴Sentinel进行流量控制,断路和系统自适应保护
  • 服务注册和发现:实例可以在Alibaba Nacos上注册,客户可以使用Spring管理的bean发现实例。通过Spring Cloud Netflix支持Ribbon,客户端负载均衡器
  • 分布式配置:使用阿里巴巴Nacos作为数据存储
  • 事件驱动:构建与Spring Cloud Stream RocketMQ Binder 连接的高度可扩展的事件驱动微服务
  • 消息总线:使用Spring Cloud Bus RocketMQ链接分布式系统的节点
  • 分布式事务:支持高性能且易于使用的Seata分布式事务解决方案
  • Dubbo RPC:通过Apache Dubbo RPC扩展Spring Cloud服务间调用的通信协议

你可能感兴趣的:(#,分布式,#,spring,#,人人都是架构师,微服务,dubbo,springcloud,面试,溪源)