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 服务熔断 服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的 ...
随机推荐
- Python初学者随笔(一)_ 用Python写的第一个游戏“猜数字”
如标题所写,这篇随笔主要记录下学习Python过程中用Python写的第一个游戏--"猜数字"_跟着"小甲鱼"学Python,链接: https://b23.t ...
- idea2018 快捷键
Alt+Enter将光标放到缺少包的错误提示处自动导入包Ctrl+Alt+Space光标处会有会出现界面提示需要补全的信息也可以在new完对象后使用.var后将会自动补 Ctrl+O可以选择父类的方法 ...
- 记一次由sql注入到拿下域控的渗透测试实战演练(下)
本次渗透使用工具: mimikatz,PsExec 本次渗透网络拓扑图: 开始渗透: 上一篇文章中我们讲到我们成功渗透了目标内网中web服务器并提取其管理员明文密码,通过明文密码又成功登陆了内网中的另 ...
- B - 规律题2
10 123456 1:f(y)=1+2+3+4+5+6=21 2:f(y)=3 3 3 b进制,<b; 10 123 1+2+3=6;是3的倍数 1234 =(999)*1+99 ...
- BSGS及其扩展
目录 定义 原理 朴素算法 数论分块 例题 Luogu2485 [SDOI2011]计算器 题解 代码 扩展 例题 Luogu4195 [模板]exBSGS/Spoj3105 Mod 代码 之前写了一 ...
- HDU - 2825 Wireless Password (AC自动机+状压DP)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2825 题意:给一些字符串,构造出长度为n的字符串,它至少包含k个所给字符串,求能构造出的个数. 题解: ...
- 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))
扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...
- C#之抛异常
using System; namespace Demo { class Program { static void Main(string[] args) { try { BLLLayer(); } ...
- Petrozavodsk Winter Training Camp 2017G(栈)题解
题意: \(M_i\)为一个\(m*m\)矩阵,已知 \[\begin{aligned} &M_0=A\\ &M_i=(\prod_{j=c_i}^{i+1}M_j)B \end{al ...
- Redis-第八章节-应用场景
目录 概述 详解 1.概述 Redis支持五种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合). 2.详解 1.String(字符串) 定义: ...