微服务架构原理:主要是面向SOA理念,更细小粒度服务的拆分,将功能分解到各个服务当中,从而降低系统的耦合性,并提供更加灵活的服务支持。
SpringCloud与Dubbo:Dubbo是二进制传输,对象直接转成二进制,使用RPC通信。SpringCloud是http传输,同时使用http协议一般会使用JSON报文,json再转二进制,消耗会更大。 Spring Cloud下面有几十个子项目分别覆盖了微服务架构下的方方面面。
Spring Cloud作为当下主流的微服务框架,可以让我们更简单快捷地实现微服务架构。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
业务模块 | 常用组件 |
---|---|
服务注册与发现 | Netflix Eureka、Nacos、Zookeeper |
客户端负载均衡 | Netflix Ribbon、SpringCloud LoadBalancer |
服务熔断器 | Netflix Hystrix、Alibaba Sentinel、Resilience4J |
服务网关 | Netflix Zuul、SpringCloud Gateway |
服务接口调用 | Netflix Feign、 Resttemplate、Openfeign |
链路追踪 | Netflix Sleuth、Skywalking、Pinpoint |
聚合Hystrix监控数据 | Netflix Turbine |
监控中心 | SpringBoot Admin |
配置中心 | Spring Cloud Config 、Apollo、nacos |
Spring Cloud 是一个基于 Spring Boot 实现的微服务框架,它包含了实现微服务架构所需的各种组件。Spring Cloud中各个组件在微服务架构中扮演的角色如下图所示:
由上图所示,微服务架构大致由上图的逻辑结构组成,其包括各种微服务、注册发现、服务网关、熔断器、统一配置、跟踪服务等。下面说说Spring Cloud中的组件分别充当其中的什么角色。
一、服务注册与发现
微服务模式下,一个大的Web应用通常都被拆分为很多比较小的Web应用(服务),这个时候就需要有一个地方保存这些服务的相关信息,才能让各个小的应用彼此知道对方,这个时候就需要在注册中心进行注册。每个应用启动时向配置的注册中心注册自己的信息(IP地址,端口号, 服务名称等信息),注册中心将他们保存起来,服务间相互调用的时候,通过服务名称就可以到注册中心找到对应的服务信息,从而进行通讯。注册与发现服务为微服务之间的调用带来了方便,解决了硬编码的问题。服务间只通过对方的服务ID,而无需知道其IP和端口即可以获取对方方服务。
注册中心如果挂了,可以读取本地持久化里的配置。服务提供者如果挂了,应该配有服务监控中心,感知到服务下线后可以通过配置的邮件通知相关人员排查问题。
用zookeeper和eureka做注册中心的区别:Zookeeper保证的是CP(一致性,容错性), 而Eureka则是AP(可用性,容错性)。
二、服务接口调用
微服务之间通过Rest接口通讯,Spring Cloud提供Feign框架来支持Rest的调用,Feign使得不同进程的Rest接口调用得以用优雅的方式进行,这种优雅表现得就像同一个进程调用一样。
三、客户端负载均衡
Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者的地址列表后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。
Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从EurekaServer获取服务提供者的地址列表,并基于负载均衡算法,请求其中一个服务提供者的实例(为了服务的可靠性,一个微服务可能部署多个实例)。
Ribbon负载均衡原理:
(1)Ribbon通过ILoadBalancer接口对外提供统一的选择服务器(Server)的功能,此接口会根据不同的负载均衡策略(IRule)选择合适的Server返回给使用者。
(2)IRule是负载均衡策略的抽象,ILoadBalancer通过调用IRule的choose()方法返回Server。
(3)IPing用来检测Server是否可用,ILoadBalancer的实现类维护一个Timer每隔10s检测一次Server的可用状态。
(4)IClientConfig主要定义了用于初始化各种客户端和负载均衡器的配置信息,器实现类为DefaultClientConfigImpl。
四、服务熔断器
1、微服务熔断降级机制
微服务框架是许多服务互相调用的,当服务提供者响应非常缓慢,那么消费者对提供者的请求就会被强制等待,直到提供者响应或超时。在高负载场景下,如果不做任何处理,此类问题可能会导致服务消费者的资源耗竭甚至整个系统的崩溃(雪崩效应)。如果调用某服务报错(或者挂了),就对该服务熔断,在 5 分钟内请求此服务直接就返回一个默认值,不需要每次都卡几秒,这个过程,就是所谓的熔断。但是熔断了之后就会少调用一个服务,此时需要做下标记,标记本来需要做什么业务,但是因为服务挂了,暂时没有做,等该服务恢复了,就可以手工处理这些业务。这个过程,就是所谓的降级。
2、Hystrix的实现原理
Hystrix是由Netflix开源的一个隔离、熔断以及降级的一个框架。旨在隔离对远程系统、服务和第三方库的访问点,停止级联故障,并在不可避免发生故障的复杂分布式系统中实现快速恢复,主要靠Spring的AOP实现。
- 正常情况下,断路器关闭,服务消费者正常请求微服务。
- 一段时间内,失败率达到一定阈值,断路器将打开,此时不再请求服务提供者,而是只是快速失败的方法(断路方法)。
- 断路器打开一段时间,自动进入“半开”状态,此时,断路器可允许一个请求方法服务提供者,如果请求调用成功,则关闭断路器,否则继续保持断路器打开状态。
Hystrix主要通过以下几点实现延迟和容错。
- 包裹请求:使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立线程中执行。这使用了设计模式中的“命令模式”。
- 跳闸机制:当某服务的错误率超过一定阈值时,Hystrix可以自动或者手动跳闸,停止请求该服务一段时间。
- 资源隔离:Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定。
- 监控:Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时和被拒绝的请求等。
- 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑可由开发人员指定。
五、服务网关
不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求。例如一个电影购票的手机APP,可能调用多个微服务的接口才能完成一次购票的业务流程,如果让客户端直接与各个微服务通信,会有以下的问题:
- 客户端会多次请求不同的微服务,增加了客户端的复杂性。
- 存在跨域请求,在一定场景下处理相对复杂。
- 认证复杂,每个服务都需要独立认证。
- 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将很难实施。
- 某些微服务可能使用了对防火墙/浏览器不友好的协议,直接访问时会有一定的困难。
以上问题可借助微服务网关解决。微服务网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过微服务网关。使用微服务网关后,微服务网关将封装应用程序的内部结构,客户端只用跟网关交互,而无须直接调用特定微服务的接口。这样,开发就可以得到简化。不仅如此,使用微服务网关还有以下优点:
- 易于监控。可在微服务网关收集监控数据并将其推送到外部系统进行分析。
- 易于认证。可在微服务网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
- 减少了客户端与各个微服务之间的交互次数。
六、配置中心
对于传统的单体应用,常使用配置文件管理所有配置。例如一个SpringBoot开发的单体应用,可将配置内容放在application.yml文件中。如果需要切换环境,可设置多个Profile,并在启动应用时指定spring.profiles.active={profile}。
在微服务架构中,微服务的配置管理一般有以下需求:
(1)集中管理配置。一个使用微服务架构的应用系统可能会包含成百上千个微服务,因此集中管理配置是非常有必要的。
(2)不同环境,不同配置。例如,数据源配置在不同的环境(开发、测试、预发布、生产等)中是不同的。
(3)运行期间可动态调整。例如,可根据各个微服务的负载情况,动态调整数据源连接池大小或熔断阈值,并且在调整配置时不停止微服务。
(4)配置修改后可自动更新。如配置内容发生变化,微服务能够自动更新配置。
综上所述,对于微服务架构而言,一个通用的配置管理机制是必不可少的,常见做法是使用配置服务器管理配置。Spring Cloud Bus利用Git或SVN等管理配置、采用Kafka或者RabbitMQ等消息总线通知所有应用,从而实现配置的自动更新并且刷新所有微服务实例的配置。
1、配置中心如何实现自动刷新
(1)配置中心Server端承担起配置刷新的职责。
(2)更新配置,触发post请求给server端的bus/refresh接口。
(3)server端接收到请求并发送给Spring Cloud Bus总线。
(4)Spring Cloud bus接到消息并通知给其它连接到总线的客户端。
(5)其它客户端接收到通知,请求Server端获取最新配置。
(6)全部客户端均获取到最新的配置。
2、配置中心如何保证数据安全
(1)保证容器文件访问的安全性,即保证所有的网络资源请求都需要登录。
(2)将配置中心里所有配置文件中的密码进行加密,保证其密文性。
(3)开发环境禁止拉取生产环境的配置文件。
七、链路追踪
Sleuth和Zipkin结合使用可以通过图形化的界面查看微服务请求的延迟情况以及各个微服务的依赖情况。需要注意的是Spring Boot 2及以上不在支持Zipkin的自定义,需要到官方网站下载ZipKin相关的jar包。另外需要提一点的是Spring Boot Actuator,提供了很多监控端点如/actuator/info、/actuator/health、/acutator/refresh等,可以查看微服务的信息、健康状况、刷新配置等。