在ribbon项目中添加Hystrix的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
在启动类中添加启动容错保护的注解
package com.ribbon;
import com.ribbon.MyInterceptor.MyLoadBalanced;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
//@EnableHystrixDashboard
@EnableCircuitBreaker//开启断路器
public class RibbonApplication {
@Bean
// @LoadBalanced //客户端负载均衡
@MyLoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}
然后写一个service
public class UserService {
@Autowired
private RestTemplate restTemplate;
/**
*同步
* @param id
* @return
*/
@HystrixCommand(fallbackMethod = "defaultUser")
public User getUserById(Long id){
return restTemplate.getForObject("http",User.class,id);
}
//这是降级方法
public User defaultUser(){
throw new RuntimeException("failed");
}
}
现在改造Controller,注入service,直接请求service方法
@RestController
public class ConsumerController {
@Autowired
private HelloService helloService;
@RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)
public String helloConsumer() {
return helloService.helloConsumer();
}
}
启动各个项目,请求这个controller,如果service请求失败(超时从而出发熔断请求)就会直接调用降级方法,保证这次请求不会报错。
原理分析:
1,HystrixCommand和HystrixObservableCommand
HystrixCommand:用于依赖的服务返回单个操作结果的时候
HystrixObservableCommand:用于返回多个操作结果的时候
命令模式:将来自客户端的请求封装成一个对象,从而让你可以使用不用的请求客对户端进行参数化,实现请求者和实现者的解耦。
/**
* 接收者,请求的实现者,
*
* @author admin
*
* 2018年8月23日
*/
public class Receiver {
public void action() {
System.out.println("这里执行业务逻辑");
}
}
/**
* 抽象命令,将请求抽出来
*
* @author admin
*
* 2018年8月23日
*/
public interface Command {
void execute();
}
/
命令接口的实现类
package com.zhonghui.study.webapp.Command;
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;//将接收者注入进来
}
@Override
public void execute() {
this.receiver.action();//执行接收者方法
}
}
//
package com.zhonghui.study.webapp.Command;
/**
* 客户端调用者
*
* @author admin
*
* 2018年8月23日
*/
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;//将命令注入
}
public void action() {
this.command.execute();//只需执行命令的方法就行
}
}
/
public class Test {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.action();
}
}
调用者invoker与实现者receiver通过Command实现了解耦,所以HystrixCommand和HystrixObservableCommand也是命令类。
2,命令执行
HystrixCommand:
execute():同步执行
queue():异步执行,直接返回一个Future对象
HystrixObservableCommand:
observe():返回Observeabe对象,代表了多个结果,会立即执行
toObservable():返回Observeable对象,代表了多个结果,但不会立即执行。
3,结果是否有缓存
如果缓存功能由被开启,就会先去查看有没有缓存,有则直接返回缓存内容
4,断路器是否打开
如果打开,则不会执行Hystrix,而是转接到fallback处理逻辑,如果关闭,则检查是都有可用资源来执行命令,就是第五步
5,线程池/请求队列/信号量是都占满
如果占满也会转到fallback处理
6,run():返回单一结果,construct():返回多个结果。
7,计算断路器的健康度
断路器会记录请求的信息,不管成功还是失败,
8,fallback处理
9,返回成功响应
学习资料《SpringCloud 微服务实战》《SpringCloud 微服务全栈技术与案例解析》