博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Cloud中的断路器Hystrix
阅读量:6196 次
发布时间:2019-06-21

本文共 2909 字,大约阅读时间需要 9 分钟。

什么是微服务?举个简单的例子,我想做一个用户管理项目,里边就三个功能:用户注册、用户登录、用户详情浏览。按照传统的软件开发方式直接创建一个Web项目,分分钟就把这三个功能开发出来了,但是我现在想使用微服务+服务治理的方式来开发:首先我将这个项目拆分为四个微服务,四个微服务各建一个模块,分别是用户注册模块、用户登录模块、用户详情浏览模块和数据库操作模块,这四个模块通过内部服务治理互相调用。但是现在存在一个问题,这四个模块通过服务注册与订阅的方式互相依赖,如果一个模块出现故障会导致依赖它的模块也发生故障从而发生故障蔓延,进而导致整个服务的瘫痪。比如说这里的登录模块依赖于数据库模块,如果数据库模块发生故障,那么当登录模块去调用数据库模块的时候可能得不到响应,这个调用的线程被挂起,如果处于高并发的环境下,就会导致登录模块也崩溃。当一个系统划分的模块越多,这种故障发生的频率就会越高,对于这个问题,Spring Cloud中最重要的解决方案就是断路器,那么本文我们就来看看什么是断路器。


本文是Spring Cloud系列的第十篇文章,了解前九篇文章内容有助于更好的理解本文:

1.

2.
3.
4.
5.
6.
7.
8.
9.


在之前的文章中我们已经成功的搭建出服务注册中心、服务提供者和服务消费者三个微服务,本文的案例我们依然在这三个案例的基础上来实现(文末提供源码下载)。

首先我们分别启动服务注册中心,再启动两个服务提供者的实例,端口号分别是8080和8081,然后再启动一个服务消费者,服务消费者的端口号为9000,这几个都启动成功之后,我们访问http://localhost:9000/ribbon-consumer这个地址,可以看到如下效果:

图片描述

此时我们关闭掉任意一个服务提供者,再去访问这个地址,会看到如下效果:

图片描述

通过前面几篇文章的学习,大家知道Spring Cloud中采取的默认负载均衡策略就是轮询,所以当一个服务提供者关掉之后,刷新的时候服务请求成功和请求失败是成对出现的:当服务消费者去请求那个被关掉的服务提供者的时候就会请求失败,当服务消费者去请求正常的服务提供者时就能获得期望的结果。请求失败时不能给用户展示这样一个ErrorPage,而应该是一个可控的页面,OK,我们来看看如何使用断路器来解决这个问题。

服务消费者中加入断路器

首先我们需要在服务消费者中引入hystrix,如下:

org.springframework.cloud
spring-cloud-starter-hystrix

修改服务消费者启动入口类

引入hystrix之后,我们需要在入口类上通过@EnableCircuitBreaker开启断路器功能,如下:

@EnableCircuitBreaker@SpringBootApplication@EnableDiscoveryClientpublic class RibbonConsumerApplication {    public static void main(String[] args) {        SpringApplication.run(RibbonConsumerApplication.class, args);    }    @LoadBalanced    @Bean    RestTemplate restTemplate() {        return new RestTemplate();    }}

我们也可以使用一个名为@SpringBootApplication的注解代替这三个注解,@SpringBootApplication注解的定义如下:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootApplication@EnableDiscoveryClient@EnableCircuitBreakerpublic @interface SpringCloudApplication {}

实际上就是这三个注解的一个整合。

修改Controller

然后我们创建一个HelloService类,如下:

@Servicepublic class HelloService {    @Autowired    private RestTemplate restTemplate;    @HystrixCommand(fallbackMethod = "error")    public String hello() {        ResponseEntity
responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class); return responseEntity.getBody(); } public String error() { return "error"; }}

关于这个HelloService类我说如下几点:

1.RestTemplate执行网络请求的操作我们放在HelloService中来完成。

2.error方法是一个请求失败时回调的方法。
3.在hello方法上通过@HystrixCommand注解来指定请求失败时回调的方法。

OK,最后我们将ConsumerController的逻辑修改成下面这样:

@RestControllerpublic class ConsumerController {    @Autowired    private HelloService helloService;    @RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)    public String helloController() {        return helloService.hello();    }}

此时我们就开启了断路器功能。

测试

我们先确认服务注册中心,两个服务提供者的实例,端口号分别是8080和8081,一个服务消费者,端口号为9000,一共四个实例都启动成功,启动成功之后,我们再关掉一个服务提供者,此时访问http://localhost:9000/ribbon-consumer,结果如下:

图片描述

OK,小伙伴们看到,此时如果服务调用失败,就会调用失败的那个回调方法。

事实上,不仅仅是服务提供者被关闭时我们需要断路器,如果请求超时也会触发熔断请求,调用回调方法返回数据。

案例地址:

更多JavaEE资料请关注公众号:

图片描述

以上。

转载地址:http://uvyca.baihongyu.com/

你可能感兴趣的文章
4.ASCII码排序
查看>>
关于H5唤醒APP的功能实现
查看>>
java 判断请求来自手机端还是电脑端
查看>>
SQL SERVER的整型运算,让人大吃一惊
查看>>
掀开图片显示介绍的css效果
查看>>
SQL Server基础知识
查看>>
soket.io.js + angular.js + express.js(node.js)
查看>>
开源CMS比较
查看>>
Unity 灯光探针用法教程
查看>>
最高优先级算法——进程调度
查看>>
转载:SVN分支合并
查看>>
nginx 负载均衡5种配置方式
查看>>
LR C语言语句复习,几个简单代码
查看>>
Oracle 内存参数设置
查看>>
HDU4813 Hard Code
查看>>
自测之Lesson16:并发通信
查看>>
2-SAT问题
查看>>
CodeForces - 805D
查看>>
Java三大框架之——Hibernate
查看>>
udp示例
查看>>