Java后端爱上SpringCloud 第三节:熔断器 Hystrix
PS:本来我都把这篇都写过了,不过没有保存,现在重写一遍。还有就是Hystrix这个东西,已经没有人继续升级了,但是重在稳定,而且BUG还是在修复的。
一些链接
- Eureka+Zuul+Ribbon+Feign+Hystrix构建微服务架构
- 一系列很详细的Hystrix
- SpringCloud之Feign与Hystrix的整合
- 网上介绍熔断器 Hystrix的还很多的
为什么要用熔断器?
Ribbon结合Hystrix
继续My-Spring-Ribbon工程。引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
我们再改造一下RibbonControler类。
package com.hyn.cloud.ribbon.controler;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.hyn.cloud.ribbon.service.RibbonService;
@RestController
@RequestMapping("/ribbon")
public class RibbonControler {
@Autowired
RibbonService iRibbonService;
@RequestMapping(value = "/name",method=RequestMethod.GET)
@ResponseBody
public String ribbon(@RequestParam String name){
return iRibbonService.sendFeignServer(name);
}
@RequestMapping(value = "/name2",method=RequestMethod.GET)
@ResponseBody
public String ribbon2(@RequestParam String name){
String respResult="I am ribbon,My name2 is "+name;
return respResult;
}
}
再来改造一下:
package com.hyn.cloud.ribbon.service;
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;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
@Service
public class RibbonService {
/**
* 注入RestTemplate
*/
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "errorSendFeignServer",
commandProperties = {
指定多久超时,单位毫秒。超时进fallback
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "4000"),
//判断熔断的最少请求数,默认是10;只有在一个统计窗口内处理的请求数量达到这个阈值,才会进行熔断与否的判断
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
//判断熔断的阈值,默认值50,表示在一个统计窗口内有50%的请求处理失败,会触发熔断
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "10"),
}
)
public String sendFeignServer(String name)
{
String respResult="I am ribbon,My name is "+name;
String url="http://SPRING-BOOT-FEIGN/feign/name?name=";
return restTemplate.getForObject(url+respResult, String.class);
}
public String errorSendFeignServer(String name)
{
return "feign server is die!";
}
}
依次启动一下:My-Spring-Eureka,My-Spring-Admin,My-Spring-Feign,My-Spring-Ribbon
正常现在请求:
http://127.0.0.1:8765/ribbon/name?name=hyn
关闭My-Spring-Feign工程:
Feign结合Hystrix
feign不用引入Hystrix依赖,因为本身就集成这。但是feign默认是不开启熔断功能的要在application.yml添加以下配置:
feign:
hystrix:
enabled: true
改造FeignControler
package com.hyn.cloud.feign.controler;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.hyn.cloud.feign.service.FeignService;
@RestController
@RequestMapping("/feign")
public class FeignControler {
@Autowired
FeignService feignService;
@RequestMapping(value = "/name",method=RequestMethod.GET)
public String feign(@RequestParam String name){
return feignService.getName(name);
}
}
改造FeignService
package com.hyn.cloud.feign.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "SPRING-BOOT-RIBBO",fallback=FeignServiceHystric.class,configuration=FeignDisableHystrixConfiguration.class )
public interface FeignService {
@RequestMapping(value = "/ribbon/name2",method = RequestMethod.GET)
String getName(@RequestParam("name")String name);
}
新增HystrixFeignConfiguration
package com.hyn.cloud.feign.service;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import com.netflix.hystrix.HystrixCommand;
import feign.Feign;
import feign.hystrix.HystrixFeign;
@Configuration
public class FeignDisableHystrixConfiguration {
@Configuration
@ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })
protected static class HystrixFeignConfiguration {
@Bean
@Scope("prototype")
public Feign.Builder feignHystrixBuilder() {
return HystrixFeign.builder();
}
}
}
新增FeignServiceHystric
package com.hyn.cloud.feign.service;
import org.springframework.stereotype.Component;
@Component
public class FeignServiceHystric implements FeignService{
@Override
public String getName(String name) {
return "ribbon server is die!";
}
}
测试一下:
依次启动一下:My-Spring-Eureka,My-Spring-Admin,My-Spring-Feign,My-Spring-Ribbon
正常请求:
关闭My-Spring-Ribbon:
有兴趣的同学,可以自行测一下超时的请求。异常的请求。