一、SpringCloud简介
1.简介
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基 础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开 发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂 的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包,是 微服务开发的一套完整的解决方案。
2.微服务
SOA(面向服务的架构):面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元 (称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的, 它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以 以一种统一和通用的方式进行交互。
微服务:微服务架构是一种将单个应用程序作为一套小型服务开发的方法,每种应用程序都在自己的进 程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。这些服务是围绕业务功能构建的,可以 通过全自动部署机制独立部署。这些服务的集中管理最少,可以用不同的编程语言编写,并使用不同的 数据存储技术。 微服务是可以独立部署、水平扩展、独立访问(或者有独立的数据库)的服务单元,springcloud就是 这些微服务的大管家,采用了微服务这种架构之后,项目的数量会非常多,springcloud做为大管家需 要管理好这些微服务,自然需要很多工具来帮忙。
五大重要组件
服务发现——Netflix Eureka
客服端负载均衡——Netflix Ribbon/Feign
服务网关——Netflix Zuul
断路器——Netflix Hystrix
分布式配置——Spring Cloud Config
3.SpringCloud架构
1、外部或者内部的非Spring Cloud项目都统一通过API网关(Zuul)来访问内部服务.
2、网关接收到请求后,从注册中心(Eureka)获取可用服务
3、由Ribbon进行均衡负载后,分发到后端的具体实例
4、微服务之间通过Feign进行通信处理业务
5、Hystrix负责处理服务超时熔断
6、Turbine监控服务间的调用和熔断相关指标
4.SpringCloud核心组件
4.1 Spring Cloud Netflix
Spring Cloud netflix是一套框架,由Netflix开发后来又并入Spring Cloud大家庭,它主要提供的模块包 括:服务发现、断路器和监控、智能路由、客户端负载均衡等。
Eureka
服务中心,云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和 故障转移。这个可是springcloud最牛鼻的小弟,服务中心,任何小弟需要其它小弟支持什么都需 要从这里来拿,同样的你有什么独门武功的都赶紧过报道,方便以后其它小弟来调用;它的好处是 你不需要直接找各种什么小弟支持,只需要到服务中心来领取,也不需要知道提供支持的其它小弟 在哪里,还是几个小弟来支持的,反正拿来用就行,服务中心来保证稳定性和质量。
Feign
服务客户端,服务之间如果需要相互访问,可以使用RestTemplate,也可以使用Feign客户端访 问。它默认会使用Ribbon来实现负载均衡。 Feign旨在使编写Java的http客户端变得更容易。RestTemplate对http请求的封装处理,形成了一套 模板化的调用方法,但是在实际开发中由于对服务依赖的调用可能不止一处,使用RestTemplate 就不是太灵活。Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定 义,所以在Feign时我们只需要创建一个接口并使用注解的方式来配置它(以前是Dao接口上标注 Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),简化了服务调用时客户端开发的工作量。
Ribbon
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端 负载均衡的服务调用。Feign中集成了Ribbon。
Hystrix
熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。比如突然某个小弟生病了,但是你还需要它的支持,然后调用之后它半天没有响 应,你却不知道,一直在等等这个响应;有可能别的小弟也正在调用你的武功绝技,那么当请求多 之后,就会发生严重的阻塞影响老大的整体计划。这个时候Hystrix就派上用场了,当Hystrix发现 某个小弟不在状态不稳定立马马上让它下线,让其它小弟来顶上来,或者给你说不用等了这个小弟 今天肯定不行,该干嘛赶紧干嘛去别在这排队了。
Zuul
Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。当其它门派来找大哥办事的时候一定要先经过zuul,看下 有没有带刀子什么的给拦截回去,或者是需要找那个小弟的直接给带过去。
4.2 Spring Cloud Config
俗称的配置中心,配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持 本地存储、Git以及Subversion。就是以后大家武器、枪火什么的东西都集中放到一起,别随便自己带,方便以后统一管理、升级装备。
4.3 Spring Cloud Bus
事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合 实现热部署。确保各个服务之间消息保持畅通。
5.Dubbo和Spring Cloud有何不同
首先做一个简单的功能对比:
功能名称 | Dubbo | Spring Cloud |
服务注册中心 | ZooKeeper | Spring Cloud Netflix Eureka |
服务调用方式 | RPC | REST API |
服务监控 | Dubbo-monitor | Spring Boot Admin |
断路器 | 不完善 | Spring Cloud Netflix Hystrix |
服务网关 | 无 | Spring Cloud Netflix Zuul |
分布式配置 | 无 | Spring Cloud Config |
服务跟踪 | 无 | Spring Cloud Sleuth |
消息总线 | 无 | Spring Cloud Bus |
数据流 | 无 | Spring Cloud Stream |
批量任务 | 无 | Spring Cloud Task |
…… | …… | …… |
从上图可以看出其实 Dubbo的功能只是Spring Cloud体系的一部分。
这样对比是不够公平的,首先 Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分 发、流量监控和熔断。而 Spring Cloud 诞生于微服务架构时代,考虑的是微服务治理的方方面面,另 外由于依托了 Spring、Spring Boot 的优势之上,两个框架在开始目标就不一致,Dubbo 定位服务治理、Spring Cloud 是一个生态。
如果仅仅关注于服务治理的这个层面,Dubbo其实还优于Spring Cloud很多:
- Dubbo 支持更多的协议,如:rmi、hessian、http、webservice、thrift、memcached、redis 等。
- Dubbo 使用 RPC 协议效率更高,在极端压力测试下,Dubbo 的效率会高于 Spring Cloud 效率一 倍多。
- Dubbo 有更强大的后台管理,Dubbo 提供的后台管理 Dubbo Admin 功能强大,提供了路由规 则、动态配置、访问控制、权重调节、均衡负载等诸多强大的功能。
- Dubbo 可以限制某个 IP 流量的访问权限,设置不同服务器分发不同的流量权重,并且支持多种算法,利 用这些功能我们可以在线上做灰度发布、故障转移等,Spring Cloud 到现在还不支持灰度发布、 流量权重等功能。
6.和Spring Boot 是什么关系
Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具;Spring Boot专注于快速、方便集成的单个个 体,Spring Cloud是关注全局的服务治理框架;Spring Boot使用了默认大于配置的理念,很多集成方 案已经帮你选择好了,能不配置就不配置,Spring Cloud很大的一部分是基于Spring Boot来实现。那是否可以不基于Spring Boot使用SpringCloud的呢?回答是:不可以。Spring Boot可以离开 Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
7. SpringCloud的版本号
Spring Cloud是一个总括项目,由原则上具有不同发布节奏的独立项目组成。为了管理项目组合,将发 布BOM(物料清单),并带有对单个项目的精选依赖关系集(请参见下文)。发行列车的名称而不是 版本,以避免与子项目混淆。名称是按字母顺序排列的(因此您可以按时间顺序对其进行排序),带有 伦敦地铁站的名称(“ Angel”是第一个发行版,“ Brixton”是第二个发行版)。当各个项目的点发布积累 到一定数量时,或者如果其中一个关键错误需要所有人使用,则发布系列将推出名称以“ .SRX”结尾的 “服务版本”,其中“ X”是数字。
以下是SpringBoot与Spring Cloud版本的对照表:
Spring Boot | Spring Cloud |
1.2.x | Angel版本 |
1.3.x | Brixton版本 |
1.4.x stripes | Camden版本 |
1.5.x | Dalston版本、Edgware版本 |
2.0.x | Finchley版本 |
2.1.x | Greenwich.SR2 |
2.2.x | Hoxton |
二、注册中心Eureka
Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry和Service Discovery实现。也是springcloud体系中最重要最核心的组件之一。
Springcloud的注册中心不但可以使用Eureka,也可以使用Zookeeper。但是在springcloud中一 般都是以Eureka为主。
1.注册中心对比
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性 (Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实 现两点,不可能三者兼顾。
ZooKeeper:
zookeeper保证了cp(一致性、分区容错性),但是作为服务注册中心,我们可以容忍注册中心返回的是 几分钟以前的注册信息。但是服务中心却必须保证可用性, 即服务注册中心对于高可用性的需求高于一致性。对于可用性,zookeeper有一个leader选举方案。当 master主节点宕机与其他节点失去联系时,其他节点会重 新进行Leader选举,选出新的master节点。然而选举耗时过长,一般为30~120S,并且整个选举期 间,整个zookeeper集群是无法使用的。
Eureka:
eureka保证了ap(可用性、分区容错性),eureka每一个节点都是平等的,几个节点宕机不会影响正常节 点的工作。剩余的正常节点依旧可以提供服务注册和查询。 并且,当客户端向某节点注册服务时,注册失败或者超时,则会自动切换到其他节点。只要有一台 eureka节点还正常工作,就能保证注册服务的可用。但是对于服 务信息的同步则不能保证一致性(不能保证强一致性,但是最终一致)。除此之外,Eureka还有一种自我 保护机制,如果在15分钟内85%的节点都没有正常心跳(不可用) 那么Eureka就认为客户端与注册中心之间出现了网络故障,此时会出现以下几种情况:
- Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
- Eureka仍然能够接收新服务的注册和查询请求,但是不会被同步到其他节点上(保证当前节点的可用性)
- 当网络稳定后,当前实例新注册的服务会被同步到其他节点 因此,Eureka能够保证注册中心的高可用性,而不会像zookeeper一样直接集群瘫痪
2.创建Eureka Server
创建EurekaServer也离不开springboot,所以我们先创建一个maven的聚合工程,在父工程中配置springcloud的相关信息,然后再添加一个模块,在模块中创建Eureka-Server。
创建聚合工程
聚合工程中主要是配置springcloud的版本信息,以及依赖。
<!--继承springboot-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/>
</parent>
<!-- 定义springcloud的版本信息 -->
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<!--使用springcloud管理器进行管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
创建Eureka-Server
在Eureka-Server模块中pom:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
创建启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerRunner {
public static void main(String[] args) {
SpringApplication.run(EurekaServerRunner.class);
}
}
创建配置文件 application.yml
#服务名称,集群要保持一致
spring:
application:
name:eureka-server
#指定端口:eureka是使用tomcat可以设置端口区别不同的服务 默认是8080可以不写
server:
port: 8000
eureka:
client:
#是否注册到Eureka,默认他要把Eureka作为服务注册到其他注册中心,如果是单机版不需要注册到其他Eureka,可以通过下面设置
register-with-eureka: false
#表示是否从Eureka Server获取注册信息,默认为true
fetch-registry: false
#默认eureka会有备份数据到一个节点(初始是不存在的节点)的行为,可以通过指定url来指定复制节点
#service-url指定其他节点信息,如果是单机,可以忽略不管,
service-url:
#Zone: 机房/分区,一个分区可以有多个eureka服务
defaultZone: http://127.0.0.1:8001
测试
访问: http://localhost:8000/ (指定的的端口)可以看到下面页面:
3.Eureka集群
注册中心这么关键的服务,如果是单点话,遇到故障就是毁灭性的。在一个分布式系统中,服务注册中 心是最重要的基础部分,理应随时处于可以提供服务的状态。为了维持其可用性,使用集群是很好的解 决方案。Eureka通过互相注册的方式来实现高可用的部署,所以我们只需要将Eureke Server配置其他可用的serviceUrl就能实现高可用部署。
在生产中我们可能需要三台或者大于三台的注册中心来保证服务的稳定性,配置的原理就是将注册中心分别指向其它的注册中心。每台注册中心分别指向其它两个节点即可,使用application.yml来配置。
Eureka集群因为不需要进行选举,所以可以部署台数不限奇数偶数,zookeeper因为涉及选举制度,所以最好是奇数台。
注意:如果是在一台机器模拟,配置文件必须是 application-8001.ym 这种被识别(不可换成下划线等其他字符,8001 是可以自己随意取的),如果是在多台机器,则都是application.yml
第一台:application-8001.yml
#服务名称,集群要保持一致
spring:
application:
name:eureka-server
server:
port: 8001
#指定其他节点信息
eureka:
client:
#下面两个 默认就是true,可以不写
register-with-eureka: true
fetch-registry: true
#指定其他节点信息
service-url:
defaultZone: http://eureka8002:8002/eureka/,http://eureka8003:8003/eureka/
#一台机器,运行多个实例无法通过ip直接访问其他节点,所以要在hosts里指定主机名称,指定主机名称
instance:
hostname: eureka8001
第二台:application-8002.yml
#服务名称,集群要保持一致
spring:
application:
name:eureka-server
server:
port: 8002
#指定其他节点信息
eureka:
client:
#下面两个 默认就是true,可以不写
register-with-eureka: true
fetch-registry: true
#指定其他节点信息
service-url:
defaultZone: http://eureka8001:8001/eureka/,http://eureka8003:8003/eureka/
#一台机器,运行多个实例无法通过ip直接访问其他节点,所以要在hosts里指定主机名称,指定主机名称
instance:
hostname: eureka8002
第三台:application-8003.yml
#服务名称,集群要保持一致
spring:
application:
name:eureka-server
server:
port: 8003
#指定其他节点信息
eureka:
client:
#下面两个 默认就是true,可以不写
register-with-eureka: true
fetch-registry: true
#指定其他节点信息
service-url:
defaultZone: http://eureka8001:8001/eureka/,http://eureka8002:8002/eureka/
#一台机器,运行多个实例无法通过ip直接访问其他节点,所以要在hosts里指定主机名称,指定主机名称
instance:
hostname: eureka8003
如果是多台机器,直接运行即可。
若果是一台机器,运行多个实例无法通过ip直接访问其他节点,所以要在c:\windows\system32\drivers\etc\hosts 里指定主机名称
# Eureka 后面是在配置文件里面设置的实例主机名
127.0.0.1 eureka8001
127.0.0.1 eureka8002
127.0.0.1 eureka8003
使用 application.yml 指定配置文件:
#指定激活的文件
spring:
profiles:
active: 8001 #直接写 - 后面的信息即可
然后按下图将idea调节成运行多次运行
对三个文件分别激活即可,访问 http://eureka8001:8001/, http://eureka8002:8002/, http://eureka8003:8003/, 就可以看到注册信息.
4.集群配置注意事项
如果配置了Eureka集群节点出现在unavailable-replicas下,说明备份节点是不可用的,出现这个问题 的几种原因如下:
- eureka.client.serviceUrl.defaultZone 配置项的地址,不能使用localhost,要使用域名, DNS解析请自行配置。本地可以修改hosts文件来实现。
- spring.application.name 属性集群中的每个节点要一致。
- 如下两个参数需配为true,当然不配置也可以,这两个参数默认都是true。
eureka:
client:
#下面两个 默认就是true,可以不写
register-with-eureka: true
fetch-registry: true
- 配置 eureka.instance.hostname 属性,设置域名信息
eureka:
instance:
hostname: eureka8001
这个域名需要真正的对应一个ip地址,可以在hosts文件中配置。
- 如果配置了 eureka.instance.prefer-ip-address 属性,应该设置成 false ,或者去掉此参数,默认就是false。
eureka:
instance:
prefer-ip-address: false
链接:SpringCloud之微服务调用OpenFeign