Hello,今天给各位童鞋们分享Spring Cloud,赶紧拿出小本子记下来吧!
Spring Cloud
1.简介
1.含义
Spring Cloud 是微服务系统架构的一站式解决方案,在平时我们构建微服务的过程中需要做如 服务发现注册 、配置中心 、消息总线 、负载均衡 、断路器 、数据监控 等操作,而 Spring Cloud 为我们提供了一套简易的编程模型,使我们能在 Spring Boot 的基础上轻松地实现微服务项目的构建。
2.与SpringBoot的关系
SpringBoot专注于开发单个个体微服务。
SpringCloud则是将一个个单体微服务整合起来并进行管理。
SpringBoot可以离开SpringCloud独立使用,而SpringCloud离不开SpringBoot。
总结:SpringBoot专注于开发单个个体微服务。SpringCloud关注于全局的服务治理。
2.Eureka 服务注册与发现
1.简介
Eureka是spring cloud中的一个负责服务注册与发现的组件。
Eureka由多个instance(服务实例)组成,这些服务实例可以分为两种:Eureka Server和Eureka Client。为了便于理解,我们将Eureka client再分为Service Provider和Service Consumer。
Eureka Server 提供服务注册和发现
Service Provider 服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
Service Consumer服务消费方,从Eureka获取注册服务列表,从而能够消费服务
2.实现流程
1.导包
org.springframework.cloud
spring-cloud-starter-eureka-server
1.4.6.RELEASE
正常的话,导入这个包就行了。但如果运行的时候报下边的错,可以导入下边的包解决。
java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present //报的错
2.编写applcation.xml文件
3.开启服务
之后访问http://localhost:7001/ 会出现以下界面。
默认为空,因为现在还没有服务注册进来。
4.服务注册
在服务项目里 导包。注意:这里导入的包和上边不一样。
在application.xml中添加配置
开启服务
5.自我保护机制
上图中的红色字体,是Eureka中的自我保护机制。含义如下。
当某一个微服务不可以用了,eureka不会立即清理,依旧会对该微服务的信息进行保存。
3.Eureka和zooKeeper的区别
CAP理论
C(Consistency) : 强一致性
A (Availability): 可用性
P (Partition tolerance): 分区容错性
一个分布式系统不可能同时满足三个原则,而P(分区容错性)是必须保证的,所以只能在A和C中选择一个。
zookeeper 是 CP。
Eureka 是 AP。
结论:Eureka可以很好地应对网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。
3.Ribbon
1.简介
Spring Cloud ribbon 是实现客户端负载均衡的工具。
负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。
简单来说,就是将用户的请求平均分摊到多个服务器上,从而达到系统的HA(高可用)。
2.实现流程
注意:我们是在客户端使用Ribbon。
1.导包
2.编写applcation.xml文件
3.开启服务
4.使用Ribbon
我们是使用RestTemplate来实现url跳转,因此在上边加注解 @LoadBalanced 就能实现负载均衡了。
将这里的URl修改成Eureka中的id。
访问http://localhost:8080/customer/dept/list ,每次刷新,读取的服务都不一样。
4.Feign
1.简介
它和Ribbon一样,也是做负载均衡的。
不过Ribbon是通过微服务名字来访问,Feign是通过接口和注解来访问。
Feign集成了Rubbon。
2.实现步骤
1.导包
在springcloud-api,springcloud-feign项目中都导入。
org.springframework.cloud
spring-cloud-starter-feign
1.4.6.RELEASE
2.在springcloud-api项目中编写service
加这个注解@FeignClient就行了
@Component
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptClientService {
@PostMapping("/dept/add")
boolean addDept(Dept dept);
@GetMapping("/dept/get/{id}")
Dept queryByid(@PathVariable("id") Long id);
@GetMapping("/dept/list")
List queryAll();
}
3.在springcloud-feign项目中编写Controlelr
@RestController
public class CustomerController {
@Autowired
private DeptClientService deptClientService=null;
@RequestMapping("/customer/dept/get/{id}")
public Dept get(@PathVariable("id")Long id){
return deptClientService.queryByid(id);
}
@RequestMapping("/customer/dept/add")
public boolean add(Dept dept){
return deptClientService.addDept(dept);
}
@RequestMapping("/customer/dept/list")
public List list(){
return deptClientService.queryAll();
}
}
4.修改主程序
5.启动项目
结果和使用 Ribbon+RestTemplate 效果一样。本人觉得这种方法更简单。
5.Hystrix 服务熔断
1.服务雪崩
假设存在如下调用链
而此时,Service A的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算Service A能扛得住请求,Service B和Service C未必能扛得住这突发的请求。
此时,如果Service C因为抗不住请求,变得不可用。那么Service B的请求也会阻塞,慢慢耗尽Service B的线程资源,Service B就会变得不可用。紧接着,Service A也会不可用,这一过程如下图所示
如上图所示,一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。
2.什么是Hystrix
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时,异常Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),**向调用方返回一个服务预期的,可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,**这样就可以保证了服务调用方的线程不会被长时间,不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
可以做什么
服务熔断
服务降级
3.服务熔断
服务熔断是对雪崩效应的一种微服务链路保护机制。
当链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快
速返回错误的响应信息。
当检测到该节点微服务调用响应正常后恢复调用链路。
在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,为5秒内20次调用失败就会启动熔断机制。
熔断机制的注解是@HystrixCommand。
4.服务熔断实现步骤
1.导入依赖
org.springframework.cloud
spring-cloud-starter-hystrix
1.4.6.RELEASE
2.修改Controller层
正常情况下,如果查询的id不存在,会返回一个500界面。添加@HystrixCommand注解后,就会调用下边的方法。
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@GetMapping("/dept/get/{id}")
@HystrixCommand(fallbackMethod = "hystrixGet") //调用失败就调用下边的方法
public Dept queryDeptByid(@PathVariable("id") Long id){
Dept dept = deptService.queryByid(id);
if (dept==null)
throw new RuntimeException("信息无法找到!!!");
return dept;
}
//备选方案
public Dept hystrixGet(@PathVariable("id") Long id){
return new Dept()
.setDeptno(id)
.setDname("没有对应的信息-> @Hystrix")
.setDb_source("no this database");
}
}
3.开启Hystrix服务
@EnableCircuitBreaker //添加对熔断的支持
//启动类
@SpringBootApplication
@EnableEurekaClient //在服务启动后自动注册到Eureka中
@EnableCircuitBreaker //添加对熔断的支持
public class DeptProvider_hystrix_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_hystrix_8001.class,args);
}
}
4.实现效果
5.服务降级
1.简介
什么是服务降级?
当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
应用场景
当整个微服务架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,我们可以将一些 不重要 或 不紧急 的服务或任务进行服务的 延迟使用 或 暂停使用。
2.使用步骤
创建 FallbackFactory类
@Component
public class DeptClientServiceFailbackFactory implements FallbackFactory {
@Override
public DeptClientService create(Throwable throwable) {
return new DeptClientService() {
@Override
public boolean addDept(Dept dept) {
return false;
}
@Override
public Dept queryByid(Long id) {
return new Dept()
.setDeptno(id)
.setDname("服务已关闭")
.setDb_source("没有数据");
}
@Override
public List queryAll() {
return null;
}
};
}
}
springcloud-api中的service层中
在springcloud-customer-feign项目中的application.yml开启服务降级
#开启服务降级
feign:
hystrix:
enabled: true
在服务器端正常工作的时候,用户可以正常访问。当服务器人为或者由于其他原因关闭时,用户进行访问时,会出现提示信息。如下图所示。
6.服务熔断和服务降级的区别
服务熔断
在服务端进行操作
某个服务超时或者异常,引发熔断 相当于保险丝
不会故意造成服务熔断
服务降级
在客户端进行
当某个服务关闭后,此时在客户端,我们会准备一个FallbackFactory,返回一个缺省值(默认值)。
可以故意造成服务降级
7.DashBoard监控
属于springCloud中熔断器监控,可以帮助我们得知在一定时间内单个服务接口被调用情况以及断路器目前处于什么状态。
1.实现监控功能
新建一个项目
导入依赖
org.springframework.cloud
spring-cloud-starter-hystrix
1.4.6.RELEASE
org.springframework.cloud
spring-cloud-starter-hystrix-dashboard
1.4.6.RELEASE
修改端口号
server:
port: 9001
编写启动类
@SpringBootApplication
@EnableHystrixDashboard //开启监控页面
public class DeptCustomerDashboard_9001 {
public static void main(String[] args) {
SpringApplication.run(DeptCustomerDashboard_9001.class,args);
}
}
2.在服务器端配置监控信息
注意:是实现了服务熔断的项目。否则后边会没有页面。
前提
在这个项目里导入了监控的包
org.springframework.boot
spring-boot-starter-actuator
在启动类中添加一个bean
@Bean
public ServletRegistrationBean hystrixMetricsStreamServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
registrationBean.addUrlMappings("/actuator/hystrix.stream");
return registrationBean;
}
在服务器端正常工作的时候,用户可以正常访问。当服务器人为或者由于其他原因关闭时,用户进行访问时,会出现提示信息。如下图所示。
6.服务熔断和服务降级的区别
服务熔断
在服务端进行操作
某个服务超时或者异常,引发熔断 相当于保险丝
不会故意造成服务熔断
服务降级
在客户端进行
当某个服务关闭后,此时在客户端,我们会准备一个FallbackFactory,返回一个缺省值(默认值)。
可以故意造成服务降级
7.DashBoard监控
属于springCloud中熔断器监控,可以帮助我们得知在一定时间内单个服务接口被调用情况以及断路器目前处于什么状态。
1.实现监控功能
新建一个项目
导入依赖
org.springframework.cloud
spring-cloud-starter-hystrix
1.4.6.RELEASE
org.springframework.cloud
spring-cloud-starter-hystrix-dashboard
1.4.6.RELEASE
修改端口号
server:
port: 9001
编写启动类
@SpringBootApplication
@EnableHystrixDashboard //开启监控页面
public class DeptCustomerDashboard_9001 {
public static void main(String[] args) {
SpringApplication.run(DeptCustomerDashboard_9001.class,args);
}
}
2.在服务器端配置监控信息
注意:是实现了服务熔断的项目。否则后边会没有页面。
前提
在这个项目里导入了监控的包
org.springframework.boot
spring-boot-starter-actuator
在启动类中添加一个bean
@Bean
public ServletRegistrationBean hystrixMetricsStreamServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
registrationBean.addUrlMappings("/actuator/hystrix.stream");
return registrationBean;
}
启动项目,按下图进行配置
进去后,出现如下界面,说明配置成功了。关于这个页面的详细信息就自己上网查资料吧。
6.Zuul路由网关
1.简介
Zuul包含了对请求的路由和过滤两个最主要的功能:
其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础
过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础
Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。
注意:Zuul服务最终还是会注册进Eureka
提供 :代理+路由+过滤三大功能
2.实现步骤
1.导入依赖
org.springframework.cloud
spring-cloud-starter-zuul
1.4.6.RELEASE
2.配置application.yml 文件
Zuul需要注册到Eureka中,所以需要配置Eureka
server:
port: 9527
spring:
application:
name: springcloud-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-zuul-9527
prefer-ip-address: true # 显示真实ip地址
info:
app.name: dzsq-springcloud
company.name: blog.dzsq.com
zuul:
routes:
mydept.serviceId: springcloud-provider-dept
mydept.path: /mydept/**
ignored-services: springcloud-provider-dept #忽略原来的路径 忽略所有的服务 "*"
3.编写启动类
@SpringBootApplication
@EnableZuulProxy //开启代理
public class ZuulApplication_9527 {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication_9527.class,args);
}
}
3.实现效果
之前我们是通过下图这种方式来访问的。这样会暴露项目的一些信息。
现在我们可以使用Zuul配置的端口号来访问,这里的 springcloud-provider-dept 是配置Spring的名字。
如果不想通过这个访问,也可以自己配置。
效果如下图所示
7.SpringCloud Config
1.简介
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
SpringCloud Config分为服务端和客户端两个部分。
服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。
客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息,配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
当一个系统中的配置文件发生改变的时候,我们需要重新启动该服务,才能使得新的配置文件生效,spring cloud config可以实现微服务中的所有系统的配置文件的统一管理,而且还可以实现当配置文件发生变化的时候,系统会自动更新获取新的配置。
2.服务端配置
1.准备工作
在GitHub或者Gitee上创建一个仓库,放入自己的一个文件。
2.导入依赖
org.springframework.cloud
spring-cloud-config-server
2.1.1.RELEASE
3.编写application.yml文件
server:
port: 3344
spring:
application:
name: springcloud-config-server
连接远程配置
cloud:
config:
server:
git:
uri: gitee.com/infiniteSta… #gitee上项目的地址
4.编写启动类
@SpringBootApplication
@EnableConfigServer
public class Config_server_3344 {
public static void main(String[] args) {
SpringApplication.run(Config_server_3344.class,args);
}
}
5.测试
成功访问到远程的配置文件。
3.客户端配置
1.导入依赖
org.springframework.cloud
spring-cloud-starter-config
2.1.1.RELEASE
2.编写application.yml文件
application.yml文件也可以用bootstrap.yml 文件代替,不同的是bootstrap.yml是系统级别的配置,application.yml是用户级别的配置。
#系统级别的配置
spring:
cloud:
config:
name: config-client #需要从git上获取的资源名称
profile: dev #选测版本
label: master #选择分支
3.编写启动类
@SpringBootApplication
public class Config_client_3355 {
public static void main(String[] args) {
SpringApplication.run(Config_client_3355.class,args);
}
}
4.在controller层中进行测试
@RestController
public class ConfigController {
@Value("${eureka.client.service-url.defaultZone}")
private String eureka;
@RequestMapping("/config")
public String config(){
return "eureka"+eureka;
}
}
5.运行结果
好啦,今天的文章就到这里,希望能帮助到屏幕前迷茫的你们