SpringCloud之服务降级
1.Hystrix(断路器)
1.1定义
扇出:多个微服务调用的时候,假设微服务A调用微服务B和C,微服务B和C又调用其他的服务。
服务雪崩:如果扇出的链路上某个微服务的调用时间过长或不可用,对微服务A的调用就会越来多的系统资源,进而引起系统崩溃。
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,能够保证在一个依赖出现问题的情况下,不会导致整体服务失败,从而提高分布式系统的弹性。它的功能有服务降级、服务熔断、服务限流等。
断路器:一种开关装置,当某个服务单元发生故障后,通过断路器的故障监控向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或抛出异常。
服务熔断:当扇出链路的某个微服务不可用火响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。
服务降级:在客户端实现的
1.2项目开发
源代码:https://github.com/zhongyushi-git/cloud-hystrix.git
1.2.1服务提供者进行服务降级
1)参考feign的搭建来搭建hystrix的项目,只需要eureka集群、api和consumer80。
2)按照provider8001创建服务提供者cloud-provider-hystrix-8001,再导入hystrix依赖
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
3)对发生异常的方法进行处理
在服务提供者的UserController中的get方法添加结果为空的异常处理
@GetMapping("/get/{id}")
@HystrixCommand(fallbackMethod = "hystrix_get")
public User getUser(@PathVariable("id")long id){
User user=userService.getUser(id);
//数据为空就抛出异常
if(user==null){
throw new RuntimeException("未查询到数据");
}
return user;
} //服务熔断
public User hystrix_get(@PathVariable("id")long id){
User user=new User();
user.setId(id);
user.setName("未查询到数据");
user.setPhone(new Date().toString());
return user;
}
4)在服务提供者启动类添加注解@EnableCircuitBreaker
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class ProviderMain8001 {
public static void main(String[] args) {
SpringApplication.run(ProviderMain8001.class, args);
}
}
5)启动测试
先启动eureka集群,然后启动8001。分别访问http://localhost:8001/user/get/1和http://localhost:8001/user/get/123,get/1能获取正常数据,get/123不能获取正常数据而显示的错误信息。
1.2.2服务消费者进行服务降级
1)把服务提供者进行异常处理的地方给注释掉
@GetMapping("/get/{id}")
@HystrixCommand(fallbackMethod = "hystrix_get")
public User getUser(@PathVariable("id")long id){
User user=userService.getUser(id);
//数据为空就抛出异常
// if(user==null){
// throw new RuntimeException("未查询到数据");
// }
return user;
}
2)在cloud-feign-consumer80导入hystrix依赖
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
3)修改cloud-feign-consumer80的yml
feign:
hystrix:
enabled: true
4)创建service接口,用于feign获取服务
package com.zys.cloud.serivce; import com.zys.cloud.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; //添加注解,指定微服务名称
@FeignClient(value="CLOUD-PROVIDER")
public interface UserClientService { @GetMapping("/user/get/{id}")
public User getUser(@PathVariable("id")long id); @PostMapping("/user/add")
int addUser(User user);
}
5)创建controller
package com.zys.cloud.controller; import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.zys.cloud.entity.User;
import com.zys.cloud.serivce.UserClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import javax.annotation.Resource;
import java.util.Date; @RestController
@RequestMapping("/consumer")
public class UserController { @Resource
private UserClientService userClientService; @GetMapping("/get/{id}")
// @HystrixCommand(fallbackMethod = "hystrix_get")
public User getUser(@PathVariable("id") long id){
User user=userClientService.getUser(id);
//数据为空就抛出异常
if(user==null){
throw new RuntimeException("抱歉,未查询到数据");
}
return user;
}
//服务熔断
public User hystrix_get(@PathVariable("id")long id){
User user=new User();
user.setId(id);
user.setName("抱歉,未查询到数据");
user.setPhone(new Date().toString());
return user;
} @PostMapping("/add")
public int addUser(User user){
return userClientService.addUser(user);
} }
6)在服务消费者启动类添加注解@EnableHystrix
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class ConsumerFeignMain80 {
public static void main(String[] args) {
SpringApplication.run(ConsumerFeignMain80.class, args);
}
}
7)启动测试
先启动eureka集群,然后启动8001,最后80启动。分别访问http://localhost/consumer/get/1和http://localhost/consumer/get/123,get/1能获取正常数据,get/123不能获取正常数据而显示的错误信息。然后关闭8001,再次访问http://localhost/consumer/get/1也是显示错误信息。
1.2.3服务降级优化
在上面的服务提供者和消费者中,对服务进行降级,都有一些问题。就是要对每一个方法进行降级,降级的方法又混合在controller中,显示很繁琐,配置起来也很麻烦。不过是可以进行全局配置的。
(1)DefaultProperties设置默认的处理方法
在80的controller中加入注解进行配置
package com.zys.cloud.controller; import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.zys.cloud.entity.User;
import com.zys.cloud.serivce.UserClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import javax.annotation.Resource;
import java.util.Date; @RestController
@RequestMapping("/consumer")
@DefaultProperties(defaultFallback = "globalFallBack")
public class UserController { @Resource
private UserClientService userClientService; @GetMapping("/get/{id}")
// @HystrixCommand(fallbackMethod = "hystrix_get")
//未指定fallback,就使用默认的
@HystrixCommand
public User getUser(@PathVariable("id") long id){
User user=userClientService.getUser(id);
//数据为空就抛出异常
if(user==null){
throw new RuntimeException("抱歉,未查询到数据");
}
return user;
}
//服务熔断
public User hystrix_get(@PathVariable("id")long id){
User user=new User();
user.setId(id);
user.setName("抱歉,未查询到数据");
user.setPhone(new Date().toString());
return user;
} @PostMapping("/add")
public int addUser(User user){
return userClientService.addUser(user);
} //设置全局的fallback
public User globalFallBack(){
User user=new User();
user.setName("服务器维护中,请稍后再试!");
user.setPhone(new Date().toString());
return user;
} }
当没有指定fallback时,就会去使用默认的fallback。
(2)代码解耦
在service中新建一个类UserClientServiceFallBackFactory,实现FallbackFactory
package com.zys.cloud.serivce; import com.zys.cloud.entity.User;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component; @Component
public class UserClientServiceFallBackFactory implements FallbackFactory<UserClientService> {
@Override
public UserClientService create(Throwable throwable) {
return new UserClientService() {
@Override
public User getUser(long id) {
User user=new User();
user.setId(id);
user.setName("未查询到数据,服务降级-停止服务");
return user;
} @Override
public int addUser(User user) {
return 0;
}
};
}
}
在UserClientService中给FeignClient注解加fallbackFactory属性
@FeignClient(value="CLOUD-PROVIDER",fallbackFactory = UserClientServiceFallBackFactory.class)
1.3服务监控
对于微服务,也是需要进行监控的。Hystrix也提供了准实时的服务监控(Hystrix Dashboard),它会持续的记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展现给用户。在1.2的基础上继续开发。
1)新建cloud-feign-hystrix-dashboard-consumer9001的maven工程
2)在pom中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3)配置yml文件
server:
port: 9001
4)在包com.zys.cloud下创建启动类并添加注解@EnableHystrixDashboard
package com.zys.cloud; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; @SpringBootApplication
@EnableHystrixDashboard
public class ConsumerFeignHystrixDashboardMain9001 {
public static void main(String[] args) {
SpringApplication.run(ConsumerFeignHystrixDashboardMain9001.class, args);
}
}
5)在8001的启动类加配置方法
//指定监控路径
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
6)启动测试
先启动9001,然后启动eureka集群,然后启动8001。然后在浏览器输入http://localhost:9001/hystrix,可以看到下面的界面,说明配置成功。
在第一个输入框输入http://localhost:8001/hystrix.stream,点击下面的按钮,可以进入服务的监控页面。
再输入http://localhost:8001/user/get/1,快速的刷新几次,再回到监控页面看到有图形在实时变化,这就是实时的监控效果。
SpringCloud之服务降级的更多相关文章
- SpringCloud服务降级案列
一.什么是服务降级 所有的RPC技术里面服务降级是一个最为重要的话题,所谓的降级指的是当服务的提供方不可使用的时候,程序不会出现异常,而会出现本地的操作 二.服务降级案例 1.目录展示 2.导入依赖 ...
- SpringCloud断路器(Hystrix)和服务降级案列
断路器(Hystrix) 为什么需要 Hystrix? 在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC).为了保证其高可用,单个服务又必须集群部署.由于网络原因或者自 ...
- SpringCloud学习之Hystrix请求熔断与服务降级(六)
我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...
- SpringCloud之Hystrix服务降级入门全攻略
理论知识 Hystrix是什么? Hystrix是由Netflix开源的一个服务隔离组件,通过服务隔离来避免由于依赖延迟.异常,引起资源耗尽导致系统不可用的解决方案.这说的有点儿太官方了,它的功能主要 ...
- SpringCloud微服务:Sentinel哨兵组件,管理服务限流和降级
源码地址:GitHub·点这里||GitEE·点这里 一.基本简介 1.概念描述 Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性.包括核心的独立类库,监 ...
- SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级
什么是Hystrix 在分布式环境中,许多服务依赖项中的一些服务依赖不可避免地会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务 ...
- 学习一下 SpringCloud (四)-- 服务降级、熔断 Hystrix、Sentinel
(1) 相关博文地址: 学习一下 SpringCloud (一)-- 从单体架构到微服务架构.代码拆分(maven 聚合): https://www.cnblogs.com/l-y-h/p/14105 ...
- 五. SpringCloud服务降级和熔断
1. Hystrix断路器概述 1.1 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.这就造成有可能会发生服务雪崩.那么什么是服务雪崩呢 ...
- 【springcloud】服务熔断与降级(Hystrix)
转自:https://blog.csdn.net/pengjunlee/article/details/86688858 服务熔断 服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的 ...
随机推荐
- 20.LVM
1.在硬盘分好区或者部署为RAID 磁盘阵列之后,再想修改硬盘分区大小就不容易了.换句话说,当用户想要随着实际需求的变化调整硬盘分区的大小时,会受到硬盘"灵活性"的限制. 这时就需 ...
- (6)dd命令安装Linux
1.面对大批量服务器的安装,人们往往热衷于选择"无人值守安装"的方式,而此方式需要对服务器进行过多的配置,并不适合初学者. 无人值守安装(Kickstart),又称全自动安装,其工 ...
- Pytest(16)随机执行测试用例pytest-random-order
前言 通常我们认为每个测试用例都是相互独立的,因此需要保证测试结果不依赖于测试顺序,以不同的顺序运行测试用例,可以得到相同的结果. pytest默认运行用例的顺序是按模块和用例命名的 ASCII 编码 ...
- django开发东京买菜,全栈项目,前端vue,带手机GPS精准定位,带发票系统,带快递系统,带微信/支付宝/花呗/银行卡支付/带手机号一键登陆,等等
因为博客园不能发视频,所以,完整的视频,开发文档,源码,请向博主索取 完整视频+开发文档+源码,duanshuiLu.com下载 vue+django手机购物商城APP,带支付,带GPS精准定位用户, ...
- Codeforces Round #631 (Div. 2)
Contest Info Practice Link Solved A B C D E F 4/6 O O Ø O 在比赛中通过 Ø 赛后通过 ! 尝试了但是失败了 - 没有尝试 Solu ...
- Codeforces Round #680 (Div. 2, based on Moscow Team Olympiad)【ABCD】
比赛链接:https://codeforces.com/contest/1445 A. Array Rearrangment 题意 给定两个大小均为 \(n\) 的升序数组 \(a\) 和 \(b\) ...
- HDU 6900 Residual Polynomial【分治 NTT】
HDU 6900 Residual Polynomial 题意: 给出一个多项式\(f_1(x) = \sum_{i=0}^na_ix^i\) 对于任意\(i>=2\),满足\(f_i(x) ...
- Codeforces Round #691 (Div. 2) C. Row GCD (数学)
题意:给你两个数组\(a\)和\(b\),对于\(j=1,...,m\),找出\(a_1+b_j,...,a_n+b_j\)的\(gcd\). 题解:我们很容易的得出\(gcd\)的一个性质:\(gc ...
- java——类、对象、private、this关键字
一.定义 二.类的使用 实例:定义的类要在一个class文件内,实例化类的对象要在另一个文件内 类文件: 实例文件: 对象内存图: 先主函数入栈,之后新开一个对象存入堆内存中,之后调用的call方法 ...
- Vitya and Strange Lesson CodeForces - 842D 字典树+交换节点
题意: Today at the lesson Vitya learned a very interesting function - mex. Mex of a sequence of number ...