SpringCloud可以通过RestTemplate + Ribbon和Feign来进行服务与服务之间的相互调用。但是服务并不能保证时时可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,如果有大量请求涌入,就会导致Servlet容器(Tomcat)线程资源消耗完毕,服务就瘫痪了。服务与服务之间的故障传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
所以 就有了断路器的模型
什么是断路器呢 又是干什么呢。来简单看一下(ps:好了我又该画图了)
Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。在微服务架构中,一个请求调用多个服务是很常见的
如果某一个服务出现了故障,会导致连锁故障。当对特定的服务的调用的不可用达到了一个阀值(Hystrix是5秒20次)断路器将被打开
断路器打开后 可用避免连锁操作,fallback()方法可以临时返回一个固定值。
我们还是用之前用的工程,先启动一个serv8761和一个client8762
我们先在ribbon中使用断路器,首先加入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
在启动类加入 @EnableHystrix注解开启Hystrix
package com.ribbon.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
//@EnableHystrixDashboard
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonApplication.class, args);
}
// 开启负载均衡并向ioc容器注入
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
改造之前的DemoService,加入失败时的临时返回结果
package com.ribbon.demo.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.ribbon.proxy.annotation.Hystrix;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
/**
* @author chunying
*/
@Service
public class DemoService {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "fun1Error")
public String fun1(String name) {
return restTemplate.getForObject("http://HELLO/hello?name=" + name , String.class);
}
public String fun1Error(String name) {
return "sorry !" + name + ",error";
}
}
在要改造的方法上加入@HystrixCommand注解有属性fallbackMethod=“返回的方法名”,当然要加上这个方法 (fun1Error) 返回一个错误结果
启动工程 访问 http://localhost:8764/hello?name=ying 出现结果
hello!8762,ying,come here
关闭client 工程 返回结果 就是我们自定义的错误返回结果
sorry !ying,error
说明当client工程不可用的时候(Hello服务不可用的时候),service_ribbon调用hello的接口时,会执行失败方法,返回一组我们定义好的字符串,而不是等待超时,这样就有效的避免了线程阻塞。
接下来是Feign使用断路器
Feign是自带断路器的,需要在配置文件中开启
feign.hystrix.enabled=true
还是基于我们之前的service_feign进行改造
package com.chunying.feign.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @author chunying
*/
@FeignClient(value = "hello" , fallback = HelloServiceError.class)
public interface HelloService {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String helloFromClient(@RequestParam(value="name") String name);
}
在我们之前的HelloService 中注解@FeignClient中加一个属性fallback="类名"
当然这个类就是我们需要实现的错误方法类了 这个类需要实现我们的HelloService
package com.chunying.feign.service;
import org.springframework.stereotype.Component;
/**
* @author chunying
*/
@Component
public class HelloServiceError implements HelloService {
@Override
public String helloFromClient(String name) {
return "sorry !" + name + ",error";
}
}
把类加入到ioc容器中
重写接口中的方法 返回值还是我们自定义的 这样在方法执行错误时就会执行我们这个实现类了
启动工程端口8765
访问http://localhost:8765/hello?name=ying
结果和我们之前的service_ribbon是一样的 就证明断路器起作用了
断路器就到这里了 使用并不是很难
Hystrix 还有一个仪表盘 可以方便我们查询实时的动态,叫做Hystrix Dashboard
我们用service_ribbon工程做记录,Feign是一样的
首先还是加入依赖 Hystrix Dashboard本身不需要依赖Eureka的 需要加入两个依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
主类中加入注解@EnableHystrixDashboard开启dashboard功能
package com.ribbon.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
@EnableHystrixDashboard
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonApplication.class, args);
}
// 开启负载均衡并向ioc容器注入
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
启动工程 ,浏览器访问http://localhost:8764/hyxtrix 就会打开界面
输入我们需要监控的路径,起一个名字 点击
会进入到监控界面
这样就可以实时监控hystrix的动态咯
断路器就到这里 我会继续学习并记录的~