微服务之Spring Cloud
1. 微服务概述
1.1 什么是微服务
通常而言,微服务架构风格就是一种将单个应用拆分成一组小服务开发的方法,每一个小服务运行在它自己的进程中并且使用轻量的协议通信,通常是一个HTTP资源API。这些服务围绕业务能力构建并且由自动化部署机器部署。这些服务有着最小化的*管理,这个*管理可以使用不同语言编写并使用不同的数据存储技术。
微服务的核心是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事,从技术角度看就是一种小而独立的处理过程,类似进程概念,能够独立启动或销毁,可以拥有自己独立的数据库。
1.2 微服务优缺点
优点
强模块边界
可独立部署
技术多样性
缺点:
分布式复杂性
最终一致性(各个服务的团队,数据也是分散式治理,会出现不一致的问题)
运维复杂性
测试复杂性
1.3 微服务技术栈有哪些
微服务条目 | 实现技术 |
---|---|
服务开发 | Spring Boot、Spring、SpringMVC |
服务配置与管理 | Netflix公司的Archaius、阿里的Diamond等 |
服务注册与发现 | Eureka、Consul、Zookeeper等 |
服务调用 | REST、RPC、gRPC |
负载均衡 | Ribbon、Nginx等 |
服务接口调用(客户端调用服务发简单工具) | Feign等 |
消息队列 | kafka、RabbitMQ、ActiveMQ等 |
服务配置中心管理 | SpringCloudConfig、Chef等 |
服务路由(API网关) | Zuul等 |
服务监控 | Zabbix、Nagios、Metrics、Spectator等 |
全链路追踪 | Zipkin、Brave、Dapper等 |
服务部署 | Docker、OpenStack、Kubernetes等 |
数据流操作开发包 | SpringCloud Stream(封装与Redis,Rabbit、Kafka等发送接收消息) |
事件消息总线 | SpringCloud Bus |
2.Spring Cloud入门概述
2.1 概述
Spring Cloud基于Spring Boot提供了一套微服务解决方案,它为开发人员提供了快速构建分布式系统中一些常见的工具(例如配置管理,服务发现,断路器,路由,微代理,控制总线)。 可以利用Spring Boot的开发风格做到一键启动及部署。
Spring Cloud是分布式微服务架构下的一站式解决方案,俗称微服务全家桶。
2.2 学习网站
2.2 Spring Cloud与Spring Boot的关系
- Spring Boot 专注于快速方便的开发单个个别微服务,Spring Cloud是专注全局的微服务协调治理框架,它将Spring Boot开发的一个个单体微服务整合并管理起来。
- Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖关系。
2.3 Spring Cloud和Dubbo有哪些区别
- Dubbo的定位始终是一款RPC框架,而Spring Cloud的目标是微服务架构下的一站式解决方案。
- Spring Cloud 摒弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式。
- Dubbo的RPC服务提供方与调用方接口依赖方式太强 ,而REST接口相比RPC更为轻量化,它牺牲了服务调用的性能,服务提供方和调用方的依赖只是依靠一纸契约,不存在代码级别的强依赖,当然REST接口也有痛点,因为接口定义过轻,很容易导致定义文档与实际实现不一致导致服务集成时的问题,但是服务可以整合swagger,让每个服务的代码与文档一体化。所以在分布式环境下,REST方式的服务依赖要比RPC方式的依赖更为灵活。
3.Eureka服务注册与发现
3.1 简介
Eureka是Netflix的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。功能类似于dubbo的注册中心,比如Zookeeper。
3.1 原理
Eureka包含两个组件:Eureka Server和Eureka Client。
- Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。服务提供方将自身服务注册到Eureka,从而使服务消费方能够发现。服务消费方从Eureka获取注册服务列表,从而能够消费服务。
- Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
3.2 构建步骤
- 增加maven坐标
<!--eureka-server服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
- SpringBoot主启动类上面,标注启动该组件技术的注解标签:@EnableEurekaServer
- 测试 服务启动后,流量器输入http://应用名称:端口,出现Spring Eureka的界面即为成功,No instances available表示没有服务注册进来
3.3 自我保护机制
默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。
在自我保护模式中,Eureka Server会保护注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。
在Spring Cloud中,可以使用eureka.server.enable-self-preservation=false
禁用自我保护机制。
3.4 集群配置
3.4 Eurkera与Zookeeper比较
CAP理论指出,一个分布式系统不可能同时满足C(Consistency 一致性)、A(Availability 可用性)和P(Partition tolerance 分区容错性)。由于分区容错性是分布式系统中必须保证的,因此只能在A和C之间权衡。Zookeeper保证的是CP,Eureka保证的则是AP。
Zookeeper会出现一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举,但是leader选举的时间太长,需要30~120s,且选举期间整个zk集群不可用,导致在选举期间注册服务瘫痪。
Eureka在设计时优先保证可用性,且各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。Eureka的客户端在向某个Eureka注册是如果发现连接失败,则会自动切换到其他节点,只要有一台Eureka在,就能保证注册服务可用,只不过查询的信息可能不是最新的(不保证强一致性)。
因此,Eureka可以很好的应对网络故障导致部分节点失去联系的情况,而不会像Zookeeper使注册服务瘫痪。
4.Ribbon负载均衡
4.1 概述
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项,如连接超时、重试等。简单的说就是在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(简单轮询、随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
4.2 配置
- 增加依赖
<!-- Ribbon相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
- 启动增加
@RibbonClient
注解
4.3 负载均衡
Ribbon是一个软负载均衡的客户端组件,可以和其他所需请求的客户端结合使用,和Eureka结合只是其中的一个实例。
4.4 核心组件 IRule
根据特定算法中从服务列表中选取一个要访问的服务。
- RoundRobinRule:轮询,默认
- RandomRule:随机
- RetryRule:重试
- AvailabilityFilteringRule:
- WeightedResponseTimeRule
- BestAvailableRule
- ZoneAvoidanceRule
4.5 自定义
-
@RibbonClient
声明其他配置(位于RibbonClientConfiguration
之上)来完全控制客户端 。
@Configuration
@RibbonClient(name = "foo", configuration = FooConfiguration.class)
public class TestConfiguration {
}
-
注意:
FooConfiguration
必须是@Configuration
,但请注意,它不在主应用程序上下文的@ComponentScan
中,否则将由所有@RibbonClients
共享。如果您使用@ComponentScan
(或@SpringBootApplication
),则需要采取措施避免包含(例如将其放在一个单独的,不重叠的包中,或者指定要在@ComponentScan
)。也就是说自定义的FooConfiguration类和主启动类不在同一个包及其子包下
5.Feign负载均衡
5.1 概述
Feign是一个声明式的web service客户端。这使得web service客户端的写入更加方便。要使用Feign创建一个接口,并在其上面进行注解。它具有可插入注解支持,包括Feign注释和JAX-RS注解。Feign还支持可插拔编码器和解码器。Spring Cloud增加了对Spring MVC注释的支持,并使用Spring Web中默认使用的HttpMessageConverters
。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
简单来说就是使用Feign是一个声明式的web service客户端,使得编写web service客户端变得非常容易。使用时只需要创建一个接口,然后在上面添加注解即可。
5.2 Feign集成了Ribbon
Feign集成了Ribbon,利用Ribbon维护了微服务的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。
Feign通过接口的方法调用Rest服务(上一节Ribbon+RestTemplate),该请求发送给Eureka服务器,通过Feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon技术,所以也支持负载均衡。
6.Hystrix断路器
6.1 分布式系统面临的问题
复杂的分布式体系架构中的应用程序有很多服务调用关系,在服务调用过程中不可避免出现失败情况。多个微服务之间的调用的时候,如果微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,即所谓的“雪崩效应”。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的资源都在几秒钟内饱和,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。基于这些原因,需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能使整个应用程序瘫痪。
6.2 概述
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里, 许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
断路器本身是一种开关配置,当某个服务单元发生故障之后,通过断路器的故障监控(类似保险丝),向调用方返回一个符合预期的、可处理的后备(Fallback),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
6.3 功能
- 服务降级
- 服务熔断
- 服务限流
- 服务监控
6.4 服务熔断
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务不可用或者响应的时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。
在Spring Cloud中熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand
。
- 增加依赖
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
- 增加注解@EnableCircuitBreaker
- 增加注解@HystrixCommand及fallbackMethod方法
@SpringBootApplication
@EnableCircuitBreaker//对hystrix熔断机制的支持
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
@Component
public class StoreIntegration {
////一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
@HystrixCommand(fallbackMethod = "defaultStores")
public Object getStores(Map<String, Object> parameters) {
//do stuff that might fail
}
public Object defaultStores(Map<String, Object> parameters) {
return /* something useful */;
}
}
6.5 服务降级
所谓服务降级,一般从整体符合考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以准备一个本地的fallback回调,返回一个缺省值。
6.6 服务监控Hystrix Dashboard
Hystrix提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少,成功多少,失败多少等。Spring Cloud提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。
7.Zuul路由网关
7.1概述
Zuul包含了对请求的路由和过滤两个最主要的功能:其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部统一入口的基础。而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。
Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后访问微服务都是通过Zuul跳转后获得。
7.2 配置
- 增加依赖
<!-- zuul路由网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
- 启动增加
@EnableZuulProxy
注解
7.3 路由访问映射规则
zuul:
routes:
users:
path: /myusers/**
serviceId: users_servic
这意味着对“/ myusers”的http呼叫转发到“users_service”服务。路由必须有一个“路径”,可以指定为蚂蚁样式模式,所以“/ myusers / *”只匹配一个级别,但“/ myusers / **”分层匹配。后端的位置可以被指定为“serviceId”(用于发现的服务)或“url”(对于物理位置)
8. Spring Cloud Config分布式配置中心
8.1 分布式系统面临的配置问题
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。Spring Cloud提供了Config Server来解决这个问题。
8.2 概述
Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,您可以在所有环境中管理应用程序的外部属性。
客户端和服务器上的概念映射与Spring的 g Environment
和PropertySource
抽象相同,因此它们与Spring应用程序非常契合,但可以与任何以任何语言运行的应用程序一起使用。
随着应用程序通过从开发人员到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。很容易添加替代实现,并使用Spring配置将其插入。
8.3 功能
- 集中管理配置文件
- 不同环境不同配置,动态化的配置更新,分环境部署
- 运行期间动态调整配置,不再需要在每个服务部署的服务器上编写配置文件
- 当配置发生变动时,服务不再需要重启即可感知到配置的变化并应用新的配置
- 将配置信息以REST接口的形式暴露
微服务常见问题
- 什么是微服务?
- 微服务之间是如何独立通讯的?
- Spring Cloud和dubbo有哪些区别?
- Spring Boot和Spring Cloud,请你谈谈对它们的理解
- 什么是服务熔断?什么是服务降级
- 微服务的优缺点分别是什么?
- 你所知道的微服务技术栈有哪些?
- euraka和zookeeper都可以提供注册和发布的功能,请说说两个的区别?
推荐阅读
-
详解Spring Cloud Consul 实现服务注册和发现
-
Spring-cloud 注册服务提供者搭建方法
-
Spring-cloud 服务发现与消费(以ribbon为例)
-
Spring Cloud 之 Feign.
-
微信授权就是这个原理,Spring Cloud OAuth2 授权码模式
-
Spring Cloud开发人员如何解决服务冲突和实例乱窜?(IP实现方案)
-
详解Spring Cloud Gateway基于服务发现的默认路由规则
-
SpringCloud之消息总线Spring Cloud Bus实例代码
-
SpringCloud之服务注册与发现Spring Cloud Eureka实例代码
-
Spring Cloud Alibaba | Sentinel: 服务限流高级篇