前言:

刚毕业找工作时,会背Spring的Aop、IoC原理,会背一套SpringMVC的流程,成了能被大部分公司认可的通行证。然而时过境迁,随着微服务概念的兴起,SpringCloud为中小企业带来的巨大便利越来越得到业界的认可,渐渐地只会SpringMVC那一套已经不顶用了。能讲出一整套的SpringCloud解决方案、能说出SpringCloud几个组件的原理,才是当下Java业界显示一个程序员吃不吃香的重点(这里用了”吃香“这一词,言外之意不懂SpringCloud并不带表这个Java程序员不厉害,相反别人可能是研究底层如JVM原理、JDK源码、Spring核心这些东西的大佬)

好了,今天就让我来和大家一起好好把SpringCloud这个东西从头开始翻一翻

一、SpringCloud是什么

我们学习一种新的技术栈时,必然绕不开其官网。SpringCloud挂在Spring的官网上,是一款与Spring Boot、Spring Framework、Spring Data等经典产品同级别的产品。注意这里的Spring Framework包括Spring的核心Aop、IoC以及SpringMVC、WebFlux等Web开发的基础组件,而我们引入jar包时springframework是一个包含了boot、cloud的包名,大家要注意区分。

springclouddependce版本号_Cloud

1. 概述

我们先看看SpringCloud英文原版的介绍(要学会尝试看英文原版,因为有时候别人的翻译可能会有语义的理解偏差,而且学会看英文文档更有利于学习第一手的新技术)

springclouddependce版本号_微服务_02

 

构建分布式系统中常见的一些模式(之前讲设计模式时,有提到过模式的定义,A pattern is a solution to a problem in a context. 模式就是特定环境下问题的解决方案,注意经过大量验证才能成为解决方案)。括号里举例了一系列分布式系统的模式,按顺序分别是配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、分布式会话、leader选举、群集状态。

剩下部分大家先自己翻译理解下,然后参考下我的:

为了协调分布式系统,产生了一些样板化的开发模式,而开发者可以使用Spring Cloud快速地应用这些开发模式去搭建自己的服务和应用程序。它们可以在任何分布式环境中正常工作,包括开发人员自己的笔记本电脑,裸机数据中心以及类似云计算的托管平台。

2. 特性

Spring Cloud focuses on providing good out of box experience for typical use cases and extensibility mechanism(可扩展性机制) to cover others.

  • Distributed/versioned configuration
  • Service registration and discovery
  • Routing
  • Service-to-service calls 
  • Load balancing
  • Circuit Breakers(断路器,用于熔断、降级)
  • Global locks
  • Leadership election and cluster state
  • Distributed messaging

这里的特性其实也对应着分布式系统中需要具备的一些功能,对应着SpringCloud的一些组件。比如第一个对应Spring Cloud的配置中心,第二个对应Eureka或者consul。

3. 中文官网简介

最后我们来看下中文官网springcloud.cc的简介:微服务架构集大成者,云计算最佳业务实践。

再看看开源中国oschina.net简介:微服务开发和治理框架。

有没有发现一个关键字,对,就是微服务。而原官网貌似只提到了分布式系统。个人理解,微服务架构是分布式架构和SOA的拓展,更强调服务的细粒度和轻量级协议。

二、SpringCloud版本

springclouddependce版本号_微服务_03

 

 其中Dalston、Edgware、Finchley、Greenwich这四个版本官方不再提供技术支持了(不再维护)。

三、必须知道的几个分布式概念(尤其理解Eureka、Zookeeper、Nacos时要用到)

1、CAP/BASE理论

CAP理论告诉我们,一个分布式系统不可能同时满足一致性(C : Consistency)、可用性(A  : Available)和分区容错性(P : Partition tolerance)这个三个基本需求,最多只能同时满足其中两项。

其中分区容错性是分布式系统必须要满足的条件,所以系统架构师往往把精力放在如何根据业务特点在A和C之间寻求平衡。

BASE:Basic Available、Soft state、Eventually consistenct。

2、二阶段、三阶段提交

首先得知道协调者和参与者的概念,协调者是用来统一调度所有分布式节点的执行逻辑,被调度的节点称为参与者。

2PC   分两个阶段:提交事务请求(也叫投票阶段),执行事务提交。在这过程中,任何一个参与者返回No或者协调者等待反馈超时,都会中断事务。2PC可以看作一种强一致性协议,常被用在关系型数据库中。存在的问题有:同步阻塞、单点问题、太过保守。

3PC   分三个阶段:CanCommit、PreCommit、Commit(相当于把2PC中的二阶段拆成了预提交和正式提交)。

注意在3PC模型中,进入阶段三后,如果协调者故障或者协调者和参与者之间网络故障,参与者在等待超时后,会自行继续事务提交。(这样会造成数据不一致,在出现网络分区的情况下)

3、Paxos算法

Paxos算法是 Leslie Lamport于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。该算法中有三种参与角色,分别用Proposer、Acceptor、Learner来表示。

关键点:提交版本号、过半机制

四、SpringCloud重要组件

Spring Cloud 下面加入了很多套各种企业的解决方案,包括我们熟悉的Netflix、Alibaba,另外还有Azure、Amazon等。我们一般所讲的SpringCloud(也是我一开始接触SpringCloud时用的组件)其实就是Netflix那一套,主要包含以下5个组件

1、Eureka

Eureka包含两个组件:Eureka Server和Eureka Client。Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

Eureka有心跳机制,客户端每30秒会向服务端发送心跳,服务端在多个周期内没有收到客户端的心跳,会将这个客户端(服务提供者)剔除。

Eureka多节点是平等的,节点间通过复制同步数据,它没有主节点的概念,因此不存在选举的过程,可能会出现数据不一致的情况。它是牺牲了C,保证了AP。

 

客户端使用Eureka的方法,在主启动类上加注解@EnableEurekaClient

2、Hystrix

SpringCloud中的断路器Hystrix,可以实现应用级别的限流、熔断、降级。它主要使用了命令模式,构造一个 HystrixCommand或HystrixObservableCommand对象, 用于封装请求。Hystrix提供线程池隔离和信号量隔离两种模式,其中信号量隔离不支持超时失败。

以下是使用熔断器示例:

1. 首先pom文件引入jar包

<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2. 然后主启动类加上注解

@EnableHystrix
@EnableCircuitBreaker

3. 在Controller里对外提供的接口方法上加上相应注解

//服务熔断
    @HystrixCommand(fallbackMethod = "fallback_query",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),   //是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "100"),  //请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),    //时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),    //失败率达到多少后跳闸
    })
    @GetMapping("/query")
    public String query(String name){return "normal call";
    }
 
    public String fallback_query(String name ){return "failure";
    }

3、Feign

Feign 是一种声明式服务调用组件,它在 RestTemplate 的基础上做了进一步的封装。通过 Feign,我们只需要声明一个接口并通过注解进行简单的配置即可实现对 HTTP 接口的绑定。通过 Feign,我们可以像调用本地方法一样来调用远程服务,而完全感觉不到这是在进行远程调用。2019年,Netflix宣布Feign停更,于是后来SpringCloud推出了openfeign作为替代方案(支持SpringMVC注解)。

启动类加有@FeignClient 注解,Feign在启动时,会为其创建一个本地JDK Proxy代理实例,并注册到Spring IOC容器。

Feign默认使用自带的hhtpclient创建连接,连接不能被复用。如果要使用apache的HttpClient或者http-ok,则需要额外写代码配置转换。另,Feign建立连接,最终是通过URLConnection这个类实现的。

4、Ribbon

客户端负载均衡,就是会从注册中心获取一份服务提供者的列表,然后根据这个计算调用哪个服务。

5、Zuul

基于老版本的Servlet规范,不支持异步非阻塞。现在国内更倾向于使用gateway网关。