SpringCloud 基础——Hystrix 熔断器与降级(RestTemplate 与 Feign)

源码地址:https://pan.baidu.com/s/1Hmvh1Bbss_Z1w1I7I1mwDw 提取码:e41h

在进行服务调用的时候,可能由于各种原因,服务器挂掉或是网络不稳定超时等,使得响应迟迟不能返回给客户端,而后面的请求又在不断请求这个服务,这样则很可能导致服务瘫痪。Hystrix 熔断器机制就是来处理这种情况的,服务开启熔断器时,若在规定时间内没有返回响应,则认为服务出错了,断开服务,让后面的请求直接返回。让请求直接调用本地的缓存或是本地的其他方法,这就是所谓的 服务降级
服务降级让请求调用本地的方法,去缓存查找数据,或者返回错误处理等响应信息。(如果客户发送了一个请求,却迟迟得不到回应,可能会一直发送请求,增加服务器的负担,及时返回响应的话,即使不是客户想要的结果,也可以缓解其情绪,减缓其操作)
可以说服务降级通常是熔断机制启动后的处理方法
下面在 service-rest 服务和 service-feign 服务加一些东西就可以实现熔断与服务降级了

为了更好地看效果,稍微改造一下 serviceA1 服务中 controller 类的 getList() 方法

	@RequestMapping("/getList")
	public List getList() {
		long start = System.currentTimeMillis();
		try {// 降级测试
			long sleeptime = (long) (Math.random() * 3000);
			Thread.sleep(sleeptime);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		List list = new ArrayList();
		list.add("author: xiao");
		list.add("serverPort: " + serverPort);
		
		long end = System.currentTimeMillis();
		System.out.println("响应时间:" + (end - start));
		
		return list;
	}

主要是让线程执行这个方法时,睡眠 0~3 s 再返回结果,后面会设置熔断的超时时间为 2s ,即服务调用时,若 2s 还未返回结果,则熔断请求,并进行服务降级。
再就是在 serviceA1 的控制台输出了该请求的响应时间

service-rest 服务修改

1. pom.xml 加入 hystrix 依赖

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

2. application.properties 加入如下配置

## 设置所有实例的默认值,超时时间,超过该时间未响应则熔断,不写默认 1s,这里设置为 2s
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000

3. service 类改成如下

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@Service
public class ServiceRestService {
	@Autowired
	private RestTemplate restTemplate;

	@SuppressWarnings("unchecked")
	@HystrixCommand(fallbackMethod = "getWrongInfo")
	public List getServiceA() {
		return restTemplate.getForObject("http://serviceA/getList", List.class);
//		return restTemplate.getForEntity("http://localhost:7071/getList", List.class).getBody();
	}

	// hystrix fallback方法
	public List getWrongInfo() {
		List list = new ArrayList();
		list.add("获取 A 服务异常,请稍后再试。。。");
		return list;
//		return restTemplate.getForObject("http://xxx/xxx", List.class);
	}
}

(1)在调用 A 服务的方法上加了注解 @HystrixCommand(fallbackMethod = “getWrongInfo”),指明这个请求熔断后执行 getWrongInfo 这个方法。
(2)服务降级方法方法名可以自定义,但是参数和返回值必须与请求的方法是一样的
(3)除了可以在本地处理,还可以让请求去调用其他服务器的其他方法

4. 启动类加入注解 @EnableCircuitBreaker 标识开启熔断器功能

5. 熔断降级测试
启动服务注册中心,serviceA1 服务和 service-rest 服务,输入 localhost:7073/getListRest
试着多刷新几次,看看 serviceA1 的控制台,可以发现每次调用了服务降级方法的时候,serviceA1 的响应时间都是超过了 2000 ms
在这里插入图片描述
在这里插入图片描述
SpringCloud 基础——Hystrix 熔断器与降级(RestTemplate 与 Feign)_第1张图片

service-feign 服务修改

修改内容基本差不多,只是 service-feign 服务工程的 service 层是接口,所以服务降级方法是写一个类去实现这个接口,具体如下:
1. pom.xml 加入 hystrix 依赖

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

2. application.properties 加入如下配置

## 开启熔断器
feign.hystrix.enabled=true	
### 超时时间,超过该响应时间则降级处理
### 不加该配置默认为 1s
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000

在配置文件中开启熔断器,启动类不用修改

3. 创建 ServiceFeignFallback 类实现自己工程 service 层的相应接口,本例如下:

import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
import com.xiao.service.ServiceFeignService;

@Component
public class ServiceFeignFallback implements ServiceFeignService{

	@Override
	public List getListFegin() {
		List list = new ArrayList();
		list.add("调用 A 服务异常,请稍后重试");
		return list;
	}

}

熔断后调用该降级方法

4. 修改 service 层接口

import java.util.List;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

import com.xiao.fallback.ServiceFeignFallback;

@FeignClient(value="serviceA", fallback=ServiceFeignFallback.class)
public interface ServiceFeignService {
	//请求映射路径 /serviceA/getList 同 A 服务的映射路径
	@RequestMapping(value="/getList")
	public List getListFegin();
	
}

fallback=ServiceFeignFallback.class 指定降级方法地址

5. 熔断降级测试
启动注册中心,serviceA1 服务和 service-feign 服务,输入 localhost:7074/getListFeign
在这里插入图片描述
在这里插入图片描述
ps:
(1)Feign 加入熔断器后进行测试,我发现虽然降级方法成功调用了,但是我设置的熔断超时时间没有起作用,还是超过 1s 就熔断降级了。
(2)当响应时间超过 1s 时会重试 1 次
(3)当我同时开启 serviceA1、serviceA2 服务时,A2 服务没有设置睡眠,再次发送请求,当调用 A1 超过 1s 后,会成功调用 A2。(A1、A2 是 serviceA 的集群)
(4)由于 Feign 自动集成了 Ribbon ,其中有 Ribbon 的超时、重试等情况,具体情况还没摸清楚,有知道的朋友可以留言指导一下。

博主经验尚浅,也暂无微服务相关项目经验,如果理解不到位甚至理解错误,希望评论区讨论,请多指教!

你可能感兴趣的:(springcloud,零基础学,spring,cloud)