在微服务架构中,存在那么多的服务单元,若一个单元出现故障(由于网络原因或者自身原因),就很容易因依赖关系而引发故障的蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构更加不稳定。为了解决这样的问题,产生了断路器等一系列的服务保护机制。(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的更多相关文章

  1. Spring Cloud中Hystrix、Ribbon及Feign的熔断关系是什么?

    导读 今天和大家聊一聊在Spring Cloud微服务框架实践中,比较核心但是又很容易把人搞得稀里糊涂的一个问题,那就是在Spring Cloud中Hystrix.Ribbon以及Feign它们三者之 ...

  2. Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失问题分析

    最近spring boot项目中由于使用了spring cloud 的hystrix 导致了threadLocal中数据丢失,其实具体也没有使用hystrix,但是显示的把他打开了,导致了此问题. 导 ...

  3. 笔记:Spring Cloud Feign Hystrix 配置

    在 Spring Cloud Feign 中,除了引入了用户客户端负载均衡的 Spring Cloud Ribbon 之外,还引入了服务保护与容错的工具 Hystrix,默认情况下,Spring Cl ...

  4. 架构师系列文:通过Spring Cloud组件Hystrix合并请求

    在前文里,我们讲述了通过Hystrix进行容错处理的方式,这里我们将讲述通过Hystrix合并请求的方式 哪怕一个URL请求调用的功能再简单,Web应用服务都至少会开启一个线程来提供服务,换句话说,有 ...

  5. 从零开始学spring cloud(十一) -------- hystrix监控

    一.官方文档阅读 服务启动后,可以通过/health和hystrix.stream查看效果,实际上,访问上述两个地址,会出现404,这是因为spring boot版本的问题, 我在这里使用的sprin ...

  6. Spring Cloud断路器Hystrix

    在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就会因依赖关系形成故障蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构就更加的不稳定.为了解决这样的问题,因此产生了断路器模式. 什么是 ...

  7. Spring Cloud 关于 hystrix 的异常 fallback method wasn't found

    在 Spring Cloud 中使用断路器 hystrix 后,可能会遇到异常:com.netflix.hystrix.contrib.javanica.exception.FallbackDefin ...

  8. Spring Cloud之Hystrix服务保护框架

    服务保护利器 微服务高可用技术 大型复杂的分布式系统中,高可用相关的技术架构非常重要. 高可用架构非常重要的一个环节,就是如何将分布式系统中的各个服务打造成高可用的服务,从而足以应对分布式系统环境中的 ...

  9. spring cloud(五) hystrix

    开启feign 熔断 hystrix    整合hystrix-dashboard监控面板 1. 服务调用者boot工程 pom引入依赖 <!-- hystrix-dashboard 监控依赖 ...

  10. Spring Cloud 之 Hystrix.

    一.概述  在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依 ...

随机推荐

  1. PHP. 02®. Ajax异步处理、常见的响应状态、XMLHttpRequest对象及API、ajax的get/post方法、

    异步对象 a)创建异步对象 b)设置请求的url等参数 c)  发送请求 d)注册时间 e)在注册的事件中获取返回的内容并修改页面显示的内容 布尔类型不能直接用echo输出 常见的响应状态 Ajax概 ...

  2. Loadrunner 11 的安装

    安装包可以直接在我的百度网盘下载,这里用的是LR11的版本.电脑系统是win7 链接: https://pan.baidu.com/s/1OApfUemG3oVjLUE79qaikw 提取码: 7n3 ...

  3. Go语言基础之并发

    并发是编程里面一个非常重要的概念,Go语言在语言层面天生支持并发,这也是Go语言流行的一个很重要的原因. Go语言中的并发编程 并发与并行 并发:同一时间段内执行多个任务(你在用微信和两个女朋友聊天) ...

  4. JSP学习笔记(6)—— 自定义MVC框架

    仿照SpringMVC,实现一个轻量级MVC框架,知识涉及到了反射机制.注解的使用和一些第三方工具包的使用 思路 主要的总体流程如下图所示 和之前一样,我们定义了一个DispatchServlet,用 ...

  5. docker-将自己的Linux打包为镜像

    基于原始文件和目录从0开始制作镜像: 1).基于CentOS7 Linux纯净系统(初始化安装完成),将Linux整个系统打包成tar文件即可: cd /root/ tar --numeric-own ...

  6. ios打包时候提示三方文件库错误,整理下解决的思路

    这一短时间一直在打包APP上线,今天突然打包的时候碰到的头文件找不到 一开始我以为是路径的问题,检查了targets---Build settings----search Paths----heade ...

  7. C++解决最基本的迷宫问题

    问题描述:给定一个最基本的迷宫图,用一个数组表示,值0表示有路,1表示有障碍物,找一条,从矩阵的左上角,到右下角的最短路.求最短路,大家最先想到的可能是用BFS求,本文也是BFS求最短路的. 源代码如 ...

  8. 新手学习FFmpeg - 调用API完成两个视频的任意合并

    本次尝试在视频A中的任意位置插入视频B. 在上一篇中,我们通过调整PTS可以实现视频的加减速.这只是对同一个视频的调转,本次我们尝试对多个视频进行合并处理. Concat如何运行 ffmpeg提供了一 ...

  9. Android静态注册广播无法接收的问题(8.0+版本)

    如果你静态注册的广播无法接收到消息,请先检查下:你的安卓版本是不是8.0+ * 前言** Google官方声明:Beginning with Android 8.0 (API level 26), t ...

  10. [LeetCode] 由 “中缀表达式 --> 后缀表达式" 所想

    如何利用栈解决问题. Ref: 如何在程序中将中缀表达式转换为后缀表达式? 本文的引申:如何手写语法分析器 实现调度场算法 “9+(3-1)*3+10/2” --> “9 3 1-3*+ 10 ...