Spring Cloud(五) :断路器(Hystrix)

Hystrix是一款Netflix开源的熔断中间件,能够提供断路,降级,监控等多种服务。
就如我们日常生活中的电路保险丝,当接入电源的电器过多,导致整体负载过大时,保险丝会自动熔断,以此保护电器不会受损。
而在微服务架构中,当一个服务接口不堪重负,出现超时或宕机等无法使用的情况时,下游服务因获取不到数据,导致服务不可用,然后恶性循环导致整个服务体系宕机,形成雪崩效应。此时熔断器就充当了保险丝的作用,在服务接口超时或不可用时,马上返回一个错误信息,让整个服务可以继续运行,保护了整个服务体系。

PS:本文Spring Boot为2.X版本

代码下载

这里将会在上一篇Spring Cloud(四) :微服务间的互相调用和负载均衡实现(ribbon+restTemplate和feign)的基础上进一步扩展。
用到的项目为
1.SpringCloudServiceCenter 注册中心
2.SpringCloudConfig 配置中心
3.SpringCloudServiceI 服务I
4.SpringCloudServiceIII 服务III
5.SpringCloudCustomerI ribbon
6.SpringCloudCustomerII feign

服务熔断

一.在ribbon中使用hystrix

SpringCloudCustomerI 基础上扩展
1.添加依赖

		<!-- 熔断/降级 -->
		<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
		</dependency>

2.修改MyCustomerController.java。
添加如下内容
添加@HystrixCommand(fallbackMethod = "fallbackInfo")注解,fallbackMethod 为服务不可用时将会调用的方法

	@ResponseBody
	@RequestMapping(value="/CgetServiceIData")
	@HystrixCommand(fallbackMethod = "fallbackInfo")
	public String getServiceIData() {
		return getServiceI();
	}
	
	String fallbackInfo() {
		return "The service is down!";
	}

3.启动项SpringCloundCustomerIApplication.java
添加注解。

//两个里选一个即可
@EnableHystrix
@EnableCircuitBreaker

之前看各种博客时总能看到@EnableHystrix@EnableCircuitBreaker交替出现,那么它们有什么区别呢?其实只要点开看一下就知道了。
@EnableHystrix

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@EnableCircuitBreaker
public @interface EnableHystrix {

}

@EnableCircuitBreaker

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableCircuitBreakerImportSelector.class)
public @interface EnableCircuitBreaker {

}

实际上@EnableHystrix其实就是调用的@EnableCircuitBreaker。

4.测试
(1)启动注册中心,配置中心,服务I,服务III,服务消费者I。
查看注册中心http://localhost:8761/
在这里插入图片描述
尝试访问http://localhost:8770/CApi/CgetServiceIData
在这里插入图片描述
在这里插入图片描述
因为服务I和III都启动且没问题,所以输出会以上面的情况交替。
(2)然后我们尝试关闭服务I。
在这里插入图片描述
关闭该服务,查看注册中心该服务是否关闭了。
在这里插入图片描述
然后尝试访问http://localhost:8770/CApi/CgetServiceIData
在这里插入图片描述
会发现一直都是如上输出,从这点看,我这里的ribbon应该默认设置成超时断连了。如果你那边没有设置的话,应该有时会出现The service is down!内容。
(3)然后尝试下让服务I的服务超时。
修改SpringCloudServiceI项目的ServiceApiController.java中的getInfo方法
添加一个3秒的线程休眠。

@ResponseBody
	@RequestMapping(value="/getInfo")
	public String getInfo() {
        try {
            Thread.sleep(3000);//hystrix熔断默认超时时间为2秒,这里模拟超时
        } catch (InterruptedException e) {
            e.printStackTrace();
        }		
		return "serviceI+"+name;
	}

然后启动服务I,查看注册中心
在这里插入图片描述

尝试访问http://localhost:8770/CApi/CgetServiceIData
在这里插入图片描述
在这里插入图片描述
能看到服务III还能正常提供数据,但是服务I会因为超时而返回之前写好的错误信息。


二.在feign中使用hystrix

SpringCloudCustomerII 基础上扩展
1.因为feign中就已经包含了hystrix,所以不需要额外添加依赖,保持原来的即可。
2.如果你使用的Spring Cloud是低版本的话,需要在配置文件application.properties中添加配置。因为老版本Spring Cloud的话,feign中的hystrix是默认关闭的。

feign.hystrix.enabled=true

3.修改MyCustomerController.java
添加一个服务接口,只获取服务I和服务III的信息

	@ResponseBody
	@RequestMapping(value="/getServiceIData")
	public String getServiceIData(@RequestParam String name) {
		String result="";
		
		result+=name+myServiceIService.getInfo();
		
		return result;
	}

4.修改MyServiceIService.java接口
因为集成了hystrix,所以可以直接使用fallback来指定访问失败时返回的方法。
并且fallback后填写的类需要实现被填写的接口。即MyServiceIErrorService要实现MyServiceIService

@Component
@FeignClient(value="myServiceI",fallback=MyServiceIErrorService.class)
public interface MyServiceIService {
	@ResponseBody
	@RequestMapping(value="/myServiceI/Api/getInfo")
	public String getInfo();
}

5.添加MyServiceIErrorService.java
实现MyServiceIService,这样在访问MyServiceIServicegetInfo方法失败后就会返回MyServiceIErrorServicegetInfo方法

package com.my.customerII.api;

import org.springframework.stereotype.Component;

@Component
public class MyServiceIErrorService implements MyServiceIService{
	public String getInfo() {
		return "The Service is down!";
	}
}

6.启动测试,什么?你问启动项不用加什么注解吗?确实不用,都集成在@EnableFeignClients中了_(:з」∠*)_
启动服务注册中心,配置中心,服务I,服务III,服务消费者II。
访问注册中心http://localhost:8761/
在这里插入图片描述
访问http://localhost:8771/CApi/getServiceIData?name=123
多访问几次,可以看到如下两种输出,因为服务I中的接口故意添加睡眠3S。而hystrix认定超时时间是2S,所以这里在负载均衡到服务I时,就会判断该服务挂掉了,就会返回预设的错误信息。而服务III的接口还是访问正常。
在这里插入图片描述
在这里插入图片描述
可以试下关闭服务I,结果应该是如上一样。


三.hystrix监控

hystrix可以监控添加了hystrix熔断器接口,并返回访问成功率,访问速度等等。
这里在
1.添加依赖

		<!-- hystrix监控 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
		</dependency>

2.启动器
添加如下注解SpringCloundCustomerIApplication.java

@EnableHystrixDashboard

然后如果用的是Spring Boot 2.X 版本的话,恭喜,你需要多配置一点东西。
在启动项里加上这个就行了。

registrationBean.addUrlMappings("/hystrix.stream");会影响到之后访问监控

/**
	 * spring boot 2.X
	 * @return
	 */
	@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;
    }

3.测试
启动注册中心,配置中心,服务I,服务III,服务消费者I。
在这里插入图片描述
访问http://localhost:8770/hystrix
如果之前配置的是registrationBean.addUrlMappings("/hystrix.stream")的话,就在第一个空格中填写http://localhost:8770/hystrix.stream,title随便填一个值即可,然后点击montor stream按钮。
在这里插入图片描述
然后可以看到如下界面,如果出现如下界面,那么表示你用的是Spring Boot 2.X版本了,需要做第2步操作
在这里插入图片描述
正常的话是下图
在这里插入图片描述
然后新开一个页面访问http://localhost:8770/CApi/CgetServiceIData几次
再去看刚才的hystrix监控中心,可以看到如下
在这里插入图片描述
然后就可以看到服务接口的统计信息了。

代码下载

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章