Spring Cloud之Hystrix
在微服务架构中,存在那么多的服务单元,若一个单元出现故障(由于网络原因或者自身原因),就很容易因依赖关系而引发故障的蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构更加不稳定。为了解决这样的问题,产生了断路器等一系列的服务保护机制。(A服务调用B服务,B服务由于自身处理逻辑等原因造成响应缓慢,会导致A服务线程被挂起,以等待B服务执行,在高并发情况下,这些挂起的线程会导致后面调用A服务的请求被阻塞,最终导致A服务也不可用)。
加入断路器后,当服务不可用时,通过断路器的故障监控,会直接执行回调函数,直接返回一串字符串,而不是等待响应超时,这样就不会使得线程调用故障服务被长时间占用不释放,从而避免了故障在分布式系统中的蔓延。
本节内容在上节内容基础上,阅读此节之前,先看上节Spring Cloud之Eureka、Ribbon
一、无断路器示例
启动上节的eureka-server、service-hello(8081/8082)、ribbon-consumer工程
在未加入断路器之前,关闭8081实例,发送GET请求到http://localhost:9000/ribbon-consumer,轮询8081/8082,当轮询到8081后(因为8081实例被关)会得到下面输出:
二、加入断路器示例
在ribbon-consumer工程的pom.xml引入下面依赖
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-hystrix</artifactId>
- </dependency>
在ribbon-consumer工程的 主类ConsumerApplication中使用@EnableCircuitBreaker注解开启断路器功能
- package com.stonegeek;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
- import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
- import org.springframework.cloud.client.loadbalancer.LoadBalanced;
- import org.springframework.context.annotation.Bean;
- import org.springframework.web.client.RestTemplate;
- /**
- * Created by StoneGeek on 2018/5/28.
- * 博客地址:http://www.cnblogs.com/sxkgeek
- */
- @EnableCircuitBreaker
- @EnableDiscoveryClient
- @SpringBootApplication
- public class RibbonConsumerApplication {
- @Bean
- @LoadBalanced
- RestTemplate restTemplate(){
- return new RestTemplate();
- }
- public static void main(String[] args) {
- SpringApplication.run(RibbonConsumerApplication.class, args);
- }
- }
改造服务消费方式,新增HelloService类,注入RestTemplate实例,然后将在ConsumerController中对RestTemplate的使用迁移到helloService函数中,最后,在helloService函数上增加@HystrixCommand注解来指定回调方法:
- package com.stonegeek.service;
- import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.web.client.RestTemplate;
- import java.util.logging.Logger;
- /**
- * Created by StoneGeek on 2018/5/29.
- * 博客地址:http://www.cnblogs.com/sxkgeek
- */
- @Service
- public class HelloService {
- private final Logger logger =Logger.getLogger(String.valueOf(getClass()));
- @Autowired
- RestTemplate restTemplate;
- @HystrixCommand(fallbackMethod = "helloFallback")
- public String helloService(){
- //加logger更清晰的看出执行时间
- long start =System.currentTimeMillis();
- String result=restTemplate.getForEntity("http://SERVICE-HELLO/hello",String.class).getBody();
- long end=System.currentTimeMillis();
- logger.info("Spend time:"+(end-start));
- return result;
- }
- public String helloFallback(){
- return "error";
- }
- }
修改RibbonConsumerApplication.class
- package com.stonegeek.controller;
- import com.stonegeek.service.HelloService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.RestController;
- import org.springframework.web.client.RestTemplate;
- /**
- * Created by StoneGeek on 2018/5/28.
- * 博客地址:http://www.cnblogs.com/sxkgeek
- */
- @RestController
- public class ConsumerController {
- /**
- * @Author: StoneGeek
- * @Date: 2018/5/29
- * @Description:之前不加断路器代码
- */
- // @Autowired
- // RestTemplate restTemplate;
- //
- // @RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)
- // public String helloConsumer(){
- // return restTemplate.getForEntity("http://SERVICE-HELLO/hello",String.class).getBody();
- // }
- /**
- * @Author: StoneGeek
- * @Date: 2018/5/29
- * @Description: 加了断路器代码
- */
- @Autowired
- HelloService helloService;
- @RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)
- public String helloConsumer(){
- return helloService.helloService();
- }
- }
此时重新来验证一下断路器实现的服务回调逻辑,此时断开8081实例,当服务消费者轮询到8081时,不再是之前的错误内容,Hystrix服务回调生效
三、模拟服务阻塞来验证断路器回调
Hystrix默认超时时间是2000毫秒
我们对service-hello的/hello接口做一些修改(重点是Thread.sleep()函数的使用):
- package com.stonegeek.controller;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.cloud.client.ServiceInstance;
- import org.springframework.cloud.client.discovery.DiscoveryClient;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.RestController;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
- import java.util.logging.Logger;
- /**
- * Created by StoneGeek on 2018/5/27.
- * 博客地址:http://www.cnblogs.com/sxkgeek
- */
- @RestController
- public class HelloController {
- private final Logger logger =Logger.getLogger(String.valueOf(getClass()));
- @Autowired
- private DiscoveryClient client;
- /**
- * @Author: StoneGeek
- * @Date: 2018/5/29
- * @Description:不加线服务塞的代码
- */
- // @RequestMapping(value = "hello",method = RequestMethod.GET)
- // public String index(){
- // ServiceInstance instance=client.getLocalServiceInstance();
- // logger.info("/hello, host:"+instance.getHost()+", service_id:"+instance.getServiceId()+"service_port:"+instance.getPort());
- // return "hello world ";
- // }
- /**
- * @Author: StoneGeek
- * @Date: 2018/5/29
- * @Description: 加了Thread.sleep(3000)的服务阻塞代码,由于Hystrix默认超时时间为2000毫秒,
- * 所以这里采用了0至3000的随机数以让处理过程有一定概率发生超时来触发断路器
- */
- @RequestMapping(value = "/hello",method = RequestMethod.GET)
- public String index() throws InterruptedException {
- ServiceInstance instance=client.getLocalServiceInstance();
- int sleepTime=new Random().nextInt();
- logger.info("sleepTime:"+sleepTime);
- Thread.sleep(sleepTime);
- logger.info("sleepTime:"+sleepTime+"/hello, host:"+instance.getHost()+", service_id:"+instance.getServiceId()+"service_port:"+instance.getPort());
- return "hello world ";
- }
- }
重新启动service-hello和ribbon-consumer模块,连续访问http://localhost:9000/ribbon-consumer几次,当RIBBON-CONSUMER的控制台输出的Spend time大于2000的时候,网页就会返回error,即服务消费者因调用的服务超时从而触发熔断请求,并调用回调逻辑返回结果
此时Spring Could Hystrix的断路器就配置完成了!!!
Spring Cloud之Hystrix的更多相关文章
- Spring Cloud中Hystrix、Ribbon及Feign的熔断关系是什么?
导读 今天和大家聊一聊在Spring Cloud微服务框架实践中,比较核心但是又很容易把人搞得稀里糊涂的一个问题,那就是在Spring Cloud中Hystrix.Ribbon以及Feign它们三者之 ...
- Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失问题分析
最近spring boot项目中由于使用了spring cloud 的hystrix 导致了threadLocal中数据丢失,其实具体也没有使用hystrix,但是显示的把他打开了,导致了此问题. 导 ...
- 笔记:Spring Cloud Feign Hystrix 配置
在 Spring Cloud Feign 中,除了引入了用户客户端负载均衡的 Spring Cloud Ribbon 之外,还引入了服务保护与容错的工具 Hystrix,默认情况下,Spring Cl ...
- 架构师系列文:通过Spring Cloud组件Hystrix合并请求
在前文里,我们讲述了通过Hystrix进行容错处理的方式,这里我们将讲述通过Hystrix合并请求的方式 哪怕一个URL请求调用的功能再简单,Web应用服务都至少会开启一个线程来提供服务,换句话说,有 ...
- 从零开始学spring cloud(十一) -------- hystrix监控
一.官方文档阅读 服务启动后,可以通过/health和hystrix.stream查看效果,实际上,访问上述两个地址,会出现404,这是因为spring boot版本的问题, 我在这里使用的sprin ...
- Spring Cloud断路器Hystrix
在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就会因依赖关系形成故障蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构就更加的不稳定.为了解决这样的问题,因此产生了断路器模式. 什么是 ...
- Spring Cloud 关于 hystrix 的异常 fallback method wasn't found
在 Spring Cloud 中使用断路器 hystrix 后,可能会遇到异常:com.netflix.hystrix.contrib.javanica.exception.FallbackDefin ...
- Spring Cloud之Hystrix服务保护框架
服务保护利器 微服务高可用技术 大型复杂的分布式系统中,高可用相关的技术架构非常重要. 高可用架构非常重要的一个环节,就是如何将分布式系统中的各个服务打造成高可用的服务,从而足以应对分布式系统环境中的 ...
- spring cloud(五) hystrix
开启feign 熔断 hystrix 整合hystrix-dashboard监控面板 1. 服务调用者boot工程 pom引入依赖 <!-- hystrix-dashboard 监控依赖 ...
- Spring Cloud 之 Hystrix.
一.概述 在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依 ...
随机推荐
- 2019icpc南昌网络赛_I_Yukino With Subinterval
题意 给定一个序列,两种操作,单点修改,询问区间\([l,r]\)值域在\([x,y]\)范围内的连续段个数. 分析 原数组为\(a\),构造一个新的数组\(b\),\(b[i]=(a[i]==a[i ...
- [1]尝试用Unity3d制作一个王者荣耀(持续更新)->AssetBundle管理器
如果已经看过本章节:目录传送门:这是目录鸭~ 1.AssetBundleManager: 首先我们创建一个文件夹,叫AssetBundleManager,再创建Csharp(即C#)脚本,名为Asse ...
- C#中Path类的常用方法
场景 打开VS,输入Path,我们可以看到其定义. 都是静态方法,所以我们可以使用类名直接调用. 实现 新建命令行程序,编码如下: string str = @"C:\Users\Admin ...
- HBase shell scan 模糊查询
0.进入hbase shell ./hbase shell help help "get" #查看单独的某个命令的帮助 1. 一般命令 status 查看状态 version 查看 ...
- POJ - 3984 迷宫问题 (搜索)
Problem Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, ...
- setInterval、setTimeout之遗忘的第三个参数
今天看阮一峰老师的ES6入门,在一个关于promise的小demo里,老师用到了setTimeout的第三个参数,惊了有没有,定时器还有第三个参数? 喏就是下面这个demo: function tim ...
- Flume系列一之架构介绍和安装
Flume架构介绍和安装 写在前面 在学习一门新的技术之前,我们得知道了解这个东西有什么用?我们可以使用它来做些什么呢?简单来说,flume是大数据日志分析中不能缺少的一个组件,既可以使用在流处理中, ...
- mysql修改数据库的存储引擎(InnoDB)
查看当前的存储引擎 show engines; 基本的差别:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不 ...
- js---电商中常见的放大镜效果
js中的放大镜效果 在电商中,放大镜效果是很常见的,如下图所示: 当鼠标悬浮时,遮罩所在区域在右侧进行放大. 在动手写之前,我们要先理清思路,分析需求,所需知识点,再将每一块进行组装,最后进行功能的完 ...
- 使用servlet+jdbc+MD5实现用户加密登录
/** * 分析流程: * 1.前端页面提交登录请求 * 2.被web.xml拦截,进入到LoginServlet(有两种方式:方式一,在web.xml文件中配置servlet拦截器;方式二,不用在w ...