Spring Cloud 第四篇:Hystrix 断路器(防止线程阻塞)

Hystrix简介

Netflix has created a library called Hystrix that implements the circuit breaker pattern. In a microservice architecture it is common to have multiple layers of service calls.

. —-摘自官网

译文:Netflix创建了一个名为Hystrix的库,实现了断路器模式。在微服务体系结构中,通常有多个服务调用层。

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用,在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。

Ribbon + RestTemplate 开启断路器功能

准备工作

基于上一篇功能,启动EurekaService 注册中心 端口号:8761,服务提供方service-hi 端口号:8763

改造servcie-ribbon 项目,pom.xml添加Hystix依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
	<version>2.0.0.RELEASE</version>
</dependency>

启动类添加 @EnableHystrix 注解 开启  熔断路由功能

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	@Bean
	@LoadBalanced
	RestTemplate restTemplate(){
		return new RestTemplate();
	}
}

修改HelloService 添加 @HystrixCommand 注解,该注解对该方法创建了熔断器功能,并用fallbackMethod指定熔断方法,该方法返回一个字符串,代码如下:

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "hiError")
    public String hiService(String name) {
        return restTemplate.getForObject("http://SERVICE-HI/hi?name=" + name, String.class);
    }

    public String hiError(String name){
        return "hi," + name + ",sorry,error!";
    }
}

启动:service-ribbon 工程,当我们访问http://localhost:8764/hi?name=szy,浏览器显示:

然后关闭 service-hi 实例 端口号:8763,继续访问浏览器显示:

这就说明当 service-hi 工程不可用的时候,service-ribbon调用 service-hi的API接口时,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。

Feign使用断路器

Feign是自带断路器的,Spring Cloud它没有默认打开。

需要在配置文件中配置打开它,在配置文件加以下代码feign.hystrix.enabled=true

eureka.client.service-url.defaultZone=http://localhost:8761/eureka

server.port=8765

spring.application.name=service-feign

feign.hystrix.enabled=true

并在接口注解上 加上fallback指定类:

@FeignClient(value = "service-hi",fallback = HelloServiceImpl.class)
public interface HelloService {

    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    String sayHelloPort(@RequestParam("name") String name);
}

然后实现该接口并注入到IOC 中:

@Component
public class HelloServiceImpl implements HelloService{

    @Override
    public String sayHelloPort(String name) {
        return "hi "+name+",sorry!";
    }
}

启动所有服务,浏览器输入http://localhost:8765/hi?name=szy 显示如下:

然后关闭 service-hi 实例 端口号:8763,继续访问浏览器显示:

这证明断路器起到作用了。

猜你喜欢

转载自blog.csdn.net/szy_2565/article/details/83178460