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/1http://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/1http://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之服务降级的更多相关文章

  1. SpringCloud服务降级案列

    一.什么是服务降级 所有的RPC技术里面服务降级是一个最为重要的话题,所谓的降级指的是当服务的提供方不可使用的时候,程序不会出现异常,而会出现本地的操作 二.服务降级案例 1.目录展示 2.导入依赖 ...

  2. SpringCloud断路器(Hystrix)和服务降级案列

    断路器(Hystrix) 为什么需要 Hystrix? 在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC).为了保证其高可用,单个服务又必须集群部署.由于网络原因或者自 ...

  3. SpringCloud学习之Hystrix请求熔断与服务降级(六)

    我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...

  4. SpringCloud之Hystrix服务降级入门全攻略

    理论知识 Hystrix是什么? Hystrix是由Netflix开源的一个服务隔离组件,通过服务隔离来避免由于依赖延迟.异常,引起资源耗尽导致系统不可用的解决方案.这说的有点儿太官方了,它的功能主要 ...

  5. SpringCloud微服务:Sentinel哨兵组件,管理服务限流和降级

    源码地址:GitHub·点这里||GitEE·点这里 一.基本简介 1.概念描述 Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性.包括核心的独立类库,监 ...

  6. SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级

    什么是Hystrix 在分布式环境中,许多服务依赖项中的一些服务依赖不可避免地会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务 ...

  7. 学习一下 SpringCloud (四)-- 服务降级、熔断 Hystrix、Sentinel

    (1) 相关博文地址: 学习一下 SpringCloud (一)-- 从单体架构到微服务架构.代码拆分(maven 聚合): https://www.cnblogs.com/l-y-h/p/14105 ...

  8. 五. SpringCloud服务降级和熔断

    1. Hystrix断路器概述 1.1 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.这就造成有可能会发生服务雪崩.那么什么是服务雪崩呢 ...

  9. 【springcloud】服务熔断与降级(Hystrix)

    转自:https://blog.csdn.net/pengjunlee/article/details/86688858 服务熔断 服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的 ...

随机推荐

  1. (13)Linux文件系统的优缺点

    通过文件系统的方式来组织磁盘存储和数据管理.有以下几个方面的好处. 数据的读取.管理操作变得简单 文件系统给用户提供了一个简单的操作界面,用户可以通过对文件系统的简单操作,实现对磁盘的管理.虽然 Li ...

  2. cassandra权威指南读书笔记--cassandra概述

    cassandra是一个开源的.分布式.去中心化.弹性可扩展.高可用.容错.可调一致性.面向行数据库,分布式设计基于Amazon Dynamo,数据模型基于Google BigTable.cassan ...

  3. Centos8上搭建EMQ MQTT

    layout: post title: Centos8上搭建EMQ MQTT subtitle: 在阿里云Centos8搭建EMQ并配置接入 date: 2020-3-11 author: Dapen ...

  4. 关于cnblogs至github上blog的搬迁

    由于同学的强烈抗议(由于网页太卡,而且还有bug),所以在今天完成了github上blog的搭建,并且有了良好的阅读环境; Leceue

  5. CF-gym/101810 J、T-Shirts Dilemma

    题目链接:点我 题意: 给你一个区间[a,b],让你从里面选一个连续子区间[x,y](子区间可以为[a,b]),把这个区间的所有数或起来x|x+1|x+2|...|y 你要使得区间[x,y]异或起来的 ...

  6. WSL2 VS Code远程开发准备

    上一节我们在linux中创建了mvc项目,但是要是在linux中用命令行直接开发的话,就有些扯了. 我们可以使用VS Code进行远程开发,简单来说,就是在windows中打开VS Code,打开Li ...

  7. 服务注册与发现-Eureka (高可用设计)

    什么是高可用 部署需要考虑的是什么: 1.系统遇到单点失效问题,如何能够快速切换到其他节点完成任务 2.如何应对网络故障,即系统如何设计成"故障开放型"(expecting fai ...

  8. Linux系统诊断必备技能之二:日志查询常用命令详解

    一.概述 日常运维工作中,排查线上环境问题,少不了去线上查日志.而使用什么命令,能快速准确地查到我们需要查找地日志信息,也是我们需要掌握的一项技能.下面介绍一下日常工作常用到的查看日志命令:tail, ...

  9. leetcode31 下一个排列 字典序

    数字的字典序就是比大小 先想几个例子  123_>132  1243-> 1324 ,12453-> 12534 1.不可排的序列就是降序序列 2.两个相同长度的串比大小,前面相同, ...

  10. JSON简单理解

    JSON 与 JS 对象的关系 很多人搞不清楚 JSON 和 Js 对象的关系,甚至连谁是谁都不清楚.其实,可以这么理解: JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息 ...