线程隔离和服务降级
触发条件
1.线程池满
2.请求超时
引入jar包
在consumer-service
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
启动类添加配置@EnableCircuitBreaker
package cn.itcast;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
//@EnableCircuitBreaker
//@EnableDiscoveryClient
//@SpringBootApplication
//三个合并成一个
@SpringCloudApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class);
System.out.println("consumer-demo启动成功");
}
//注册这个对象把他给spring容器管理这样我们以后就可以在其他的方法中调用了控制反转(IOC)
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
方法设值ConsumerController
在要配置的方法上添加@HystrixCommand注解,配置发生异常情况执行的方法queryByIdFallback,注意的时这两个方法的返回值和参数必须是一样的。
@GetMapping("{id}")
@HystrixCommand(fallbackMethod ="queryByIdFallback" )
public String queryById(@PathVariable("id")Long id){
String url = "http://user-service/user/"+id;
String user = restTemplate.getForObject(url,String.class);
return user;
}
public String queryByIdFallback(Long id){
return "不好意思,服务器太拥挤";
}
容灾测试
给user-service的方法设置一个睡眠,然后我们在访问consumer-demo中的方法http://localhost:8088/consumer/1;
一般默认为1.0秒超过1秒就降级了
public User queryBtyId(Long id){
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return userMapper.selectByPrimaryKey(id);
}
可以把注释放到类上@DefaultProperties(defaultFallback = “queryByIdFallback”) 使用的是不带参数的方法
package cn.itcast.consumer.web;
import cn.itcast.consumer.pojp.User;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("consumer")
@DefaultProperties(defaultFallback = "queryByIdFallback")
public class ConsumerController {
//这是在启动类的时候给spring 容器管理了
@Autowired
private RestTemplate restTemplate;
// @Autowired
// private DiscoveryClient discoverClient;
// private RibbonLoadBalancerClient client;
@GetMapping("{id}")
@HystrixCommand
public String queryById(@PathVariable("id")Long id){
String url = "http://user-service/user/"+id;
String user = restTemplate.getForObject(url,String.class);
return user;
}
public String queryByIdFallback(Long id){
return "不好意思,服务器太拥挤";
}
//当配置写道类上就执行该方法
public String queryByIdFallback(){
return "不好意思,服务器太拥挤";
}
}
自定义超时时长
1.单个配
@GetMapping("{id}")
@HystrixCommand(commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000") //超市时长调成了3秒
})
public String queryById(@PathVariable("id")Long id){
String url = "http://user-service/user/"+id;
String user = restTemplate.getForObject(url,String.class);
return user;
}
2.整体配先把方法上的注释调,然后再application.yml
#配置全局超时
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
#这边是争对方法,只针对这个服务或方法
# user-service: #或者queryById 针对这个方法
# execution:
# isolation:
# thread:
# timeoutInMilliseconds: 3000