1、 Spring Cloud介绍
-
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
-
微服务是可以独立部署、水平扩展、独立访问(或者有独立的数据库)的服务单元,Spring Cloud就是这些微服务的大管家,采用了微服务这种架构之后,项目的数量会非常多,Spring Cloud做为大管家就需要提供各种方案来维护整个生态。
-
Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具;Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;Spring Boot使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud很大的一部分是基于Spring Boot来实现。
-
通过Maven等构建工具来创建针对不同场景的脚手架工程,在需要新建项目时通过这些脚手架来初始化我们自定义的标准工程, 并根据需要做一 些简单修改以达到简化原有配置过 程的 效果。 这样的做法虽然减少了工作量, 但是 这些配置依然大量散布在我们的工程中
-
SpringBoot的出现 可以有效改善这类问题,SpringBoot的宗旨并非要重写Spring或是 替代Spring, 而是希望通过设计大量的自动化配置等方式来简化Spring原有样板化的配置,
使得开发者可以快速构建应用。 -
除了解决配置问题之外,SpringBoot还通过一系列StaiterPOMs的定义, 让我们整合 各项功能的时候, 不需要在 Maven的pom.xml中维护那些错综复杂的依赖关系, 而是通
-
过类似模块化的Starter模块定义来引用, 使得依赖管理工作变得更为简单。
-
在如今容器化大行其道的时代,Spring Boot除了可以很好融入Docker之外, 其自身就 支持嵌入式的 Tomcat、 Jetty 等容器。 所以, 通过Spring Boot 构建的应用不再需要安装 Tomcat, 将应用打包成war, 再部署到Tomcat这样复杂的构建与部署动作, 只需将Spring Boot应用打成jar包, 并通过java -jar命令直接运行就能启动一个标准化的Web应用,这使得Spring Boot应用变得非常轻便。
-
整个SpringBoot的生态系统都使用到了Groovy, 很自然的,我们完全可以通过使用Gradle 和Groovy来开发Spring Boot应用, 比如下面短短的不足100个字符的代码, 通过编译打包, 使用java -jar命令就能启动 一 个返回"hello"的RSE T lAPI。
2、为什么要用Spring Cloud?
-
单体架构是什么
-
一个归档包包含了应用所有功能的应用程序, 我们通常称之为单体应用。
-
缺点:
- 复杂性逐渐变高
- 技术债务逐渐上升
- 部署速度逐渐变慢
- 阻碍技术创新
- 无法按需伸缩
-
微服务架构
- 每个微服务可独立运行在自己的进程里;
- 一系列独立运行的微服务共同构建起了整个系统;
- 每个服务为独立的业务开发,一个微服务一般完成某个特定的功能,比如:订单管理、用户管理等;
- 微服务之间通过一些轻量的通信机制进行通信,例如通过REST API或者RPC的方式进行调用。
-
微服务优点
- 易于开发和维护
- 启动较快
- 局部修改容易部署
-
4.技术栈不受限
-
5.按需伸缩
-
6.DevOps
-
微服务带来的挑战
-
运维要求较高
-
分布式的复杂性
-
接口调整成本高
-
重复劳动
-
-
微服务设计原则
- 单一职责原则
- 服务自治原则
- 轻量级通信原则
- 接口明确原则
-
2、如何构建Spring Cloud项目
- 服务的注册与发现(服务的生产者和消费者)。这里主要使用的是 Eureka 。
- Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能。
- 为什么要使用Eureka,因为在一个完整的系统架构中,任何单点的服务都不能保证不会中断,因此我们需要服务发现机制,在某个节点中断后,其它的节点能够继续提供服务,从而保证整个系统是高可用的。
- 服务发现有两种模式:一种是客户端发现模式,一种是服务端发现模式。Erueka采用的是客户端发现模式。
-
Eureka Server会提供服务注册服务,各个服务节点启动后,会在Eureka Server中进行注册,这样Eureka Server中就有了所有服务节点的信息,并且Eureka有监控页面,可以在页面中直观的看到所有注册的服务的情况。同时Eureka有心跳机制,当某个节点服务在规定时间内没有发送心跳信号时,Eureka会从服务注册表中把这个服务节点移除。Eureka还提供了客户端缓存的机制,即使所有的Eureka Server都挂掉,客户端仍可以利用缓存中的信息调用服务节点的服务。Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka中读取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载。
-
Eureka通过心跳检测、健康检查、客户端缓存等机制,保证了系统具有高可用和灵活性。
-
eureka- server 注册服务 application.yml 文件
- 启动类服务注册
- eureka-server 生产者的 pom文件
- eureka-consumer 消费服务 application.yml 文件
- 启动类注入客户端服务
- eureka-consumer 消费者的 pom文件
- 启动两个项目, 访问 http://localhost:8761 ,进入如下界面
2、高可用配置
主要是利用多个eureka相互注册,下例用采用三台服务器做集群部署,其中每台eureka服务器向另外两台注册自己的实例.
- 1.Eureka Server的同步遵循着一个非常简单的原则:只要有一条边将节点连接,就可以进行信息传播与同步.
- 2.如果Eureka A的peer指向了B, B的peer指向了C,那么当服务向A注册时,B中会有该服务的注册信息,但是C中没有。也就是说,如果你希望只要向一台Eureka注册其它所有实例都能得到注册信息,那么就必须把其它所有节点都配置到当前Eureka的peer属性中。这一逻辑是 PeerAwareInstanceRegistryImpl#replicateToPeers()方法中实现的:
拆分三个配置,可以根据这三个配置分别打成jar包运行即可,当然,这里建议配合docker-compose进行编排部署.
-
1.在Eureka中,一个instance通过一个eureka.instance.instanceId 来唯一标识,如果这个值没有设置,就采用eureka.instance.metadataMap.instanceId来代替。instance之间通过eureka.instance.appName 来彼此访问,在spring cloud中默认值是spring.application.name,如果没有设置则为UNKNOWN。在实际使用中spring.application.name不可或缺,因为相同名字的应用会被Eureka合并成一个群集。eureka.instance.instanceId也可以不设置,直接使用缺省值(client.hostname:application.name:port)
,同一个appName下InstanceId不能相同。 -
2.如果 eureka.client.registerWithEureka设置成true(默认值true),应用启动时,会利用指定的eureka.client.serviceUrl.defaultZone注册到对应的Eureka server中。之后每隔30s(通过eureka.instance.leaseRenewalIntervalInSeconds来配置)向Eureka server发送一次心跳,如果Eureka server在90s(通过eureka.instance.leaseExpirationDurationInSeconds配置)内没有收到某个instance发来的心跳就会把这个instance从注册中心中移走。发送心跳的操作是一个异步任务,如果发送失败,则以2的指数形式延长重试的时间,直到达到eureka.instance.leaseRenewalIntervalInSeconds * eureka.client.heartbeatExecutorExponentialBackOffBound这个上限,之后一直以这个上限值作为重试间隔,直至重新连接到Eureka server,并且重新尝试连接到Eureka server的次数是不受限制的。
-
3.在Eureka server中每一个instance都由一个包含大量这个instance信息的com.netflix.appinfo.InstanceInfo标识,client向Eureka server发送心跳和更新注册信息是不相同的,InstanceInfo也以固定的频率发送到Eureka server,这些信息在Eureka client启动后的40s(通过eureka.client.initialInstanceInfoReplicationIntervalSeconds配置)首次发送,之后每隔30s(通过eureka.client.instanceInfoReplicationIntervalSeconds配置)发送一次。
-
4.如果eureka.client.fetchRegistry设置成true(默认值true),Eureka client在启动时会从Eureka server获取注册信息并缓存到本地,之后只会增量获取信息(可以把eureka.client.shouldDisableDelta设置成false来强制每次都全量获取)。获取注册信息的操作也是一个异步任务,每隔30秒执行一次(通过eureka.client.registryFetchIntervalSeconds配置),如果操作失败,也是以2的指数形式延长重试时间,直到达到eureka.client.registryFetchIntervalSeconds * eureka.client.cacheRefreshExecutorExponentialBackOffBound 这个上限,之后一直以这个上限值作为重试间隔,直至重新获取到注册信息,并且重新尝试获取注册信息的次数是不受限制的。
这些任务都是在com.netflix.discovery.DiscoveryClient中启动,spring cloud用org.springframework.cloud.netflix.eureka.CloudEurekaClient对这个类进行了扩展。
微信扫码关注java架构,获取Java面试题和架构师相关题目和视频。













网友评论