目录
一站式微服务架构SpringCloud-Netflix熔断器Hystrix
项目中使用Hystrix
1.消费端添加Hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.启动类添加@EnableHystrix 注解
也可以将@EnableHystrix 替换成@EnableCircuitBreaker或@SpringCloudApplication
@EnableHystrix //@EnableCircuitBreaker,@SpringCloudApplication
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class SpringcloudDomeConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudDomeConsumerApplication.class, args);
}
}
3.添加配置
ribbon和hystrix的默认超时是1000,也就是一秒,不论是哪个超时时间满足都会执行服务降级的方法。
#ribbon的超时时间
ribbon.ReadTimeout=10000
ribbon.connectTimeout=10000
#默认是true,可以不用添加
#hystrix.command.default.execution.timeout.enabled=true
#hystrix的超时时间,默认是1000,这里如果3秒内没有响应就会执行服务降级的方法
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds= 3000
4.远程接口
@FeignClient(value = "SPRINGCLOUD-PRODUCER") //指定绑定服务名称
public interface UserInfoRemoteClient {
@RequestMapping(value = "get", method = RequestMethod.GET)
public List<UserInfo> producer();
}
5.调用远程方法
服务降级的返回值和接口的返回值一致
@RestController
public class UserInfoController {
@Resource
private UserInfoRemoteClient userInfoRemoteClient;
@HystrixCommand(fallbackMethod = "backFunction")
@RequestMapping("getUser")
public Map getUser() {
Map map=new HashMap<>();
List<UserInfo> userList = userInfoRemoteClient.producer();
map.put("userList",userList);
map.put("message","成功");
return map;
}
/**
* 降级服务
* @return
*/
public Map backFunction(){
Map map=new HashMap<>();
map.put("message","失败");
return map;
}
}
注解方式设置设置hystrix超时时间
如果配置文件没有设置hystrix的超时时间也可以在注解中设置
@RestController
public class UserInfoController {
@Resource
private UserInfoRemoteClient userInfoRemoteClient;
@HystrixCommand(fallbackMethod = "backFunction",commandProperties = {
@HystrixProperty(name="execution.timeout.enabled", value = "true"),
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "3000")
}
)
@RequestMapping("getUser")
public Map getUser() {
Map map=new HashMap<>();
List<UserInfo> userList = userInfoRemoteClient.producer();
map.put("userList",userList);
map.put("message","成功");
return map;
}
/**
* 降级服务
* @return
*/
public Map backFunction(){
Map map=new HashMap<>();
map.put("message","失败");
return map;
}
}
获取异常信息
只需要在服务降级的方法上添加入参Throwable
/**
* 降级服务
* @return
*/
public Map backFunction(Throwable throwable){
System.out.println(throwable.getMessage());
Map map=new HashMap<>();
map.put("message","失败");
return map;
}
禁用服务降级
添加ignoreExceptions = Throwable.class,禁用服务降级后遇到异常会直接报错
@HystrixCommand(fallbackMethod = "backFunction",ignoreExceptions = Throwable.class)
@RequestMapping("getUser")
public Map getUser() {
Map map=new HashMap<>();
List<UserInfo> userList = userInfoRemoteClient.producer();
map.put("userList",userList);
map.put("message","成功");
return map;
}
服务限流
@HystrixProperty(name = “coreSize”,value=“2”), @HystrixProperty(name = “maxQueueSize”,value=“1”)可以限制线程池的数量,同时访问线程数大于两者之和就会执行降级服务,maxQueueSize只允许放一个线程,默认线程数为10.
@HystrixCommand(fallbackMethod = "backFunction",
threadPoolKey = "user",
threadPoolProperties = {
@HystrixProperty(name = "coreSize",value="2"),
@HystrixProperty(name = "maxQueueSize",value="1")
})
@RequestMapping("getUser")
public Map getUser() {
Map map=new HashMap<>();
List<UserInfo> userList = userInfoRemoteClient.producer();
map.put("userList",userList);
map.put("message","成功");
return map;
}
Hystrix整合Feign使用Feign进行服务降级
方式一
低版本需要添加配置
feign.hystrix.enabled=true //默认false
远程调用接口和服务降级类
@FeignClient(value = "SPRINGCLOUD-PRODUCER",fallback = UserInfoRemoteClientBack.class) //指定绑定服务名称,指定服务降级类
public interface UserInfoRemoteClient {
@RequestMapping(value = "get", method = RequestMethod.GET)
public List<UserInfo> producer();
}
@Component
public class UserInfoRemoteClientBack implements UserInfoRemoteClient {
@Override
public List<UserInfo> producer() {
System.out.println("Feign的服务降级方法");
return Collections.emptyList();
}
}
调用远程方法
@RestController
public class UserInfoController {
@Resource
private UserInfoRemoteClient userInfoRemoteClient;
@RequestMapping("getUser")
public Map getUser() {
Map map=new HashMap<>();
List<UserInfo> userList = userInfoRemoteClient.producer();
map.put("userList",userList);
return map;
}
}
结论:当远程服务超时或者报错就会执行远程调用接口的实现类中的服务降级方法(也就是远程接口的实现方法)
方式二(可以得到异常信息)
低版本需要添加配置
feign.hystrix.enabled=true //默认false
远程调用接口和服务降级类
@FeignClient(value = "SPRINGCLOUD-PRODUCER",fallbackFactory = UserInfoRemoteClientBackFactory.class) //指定绑定服务名称
public interface UserInfoRemoteClient {
@RequestMapping(value = "get", method = RequestMethod.GET)
public List<UserInfo> producer();
}
@Component
public class UserInfoRemoteClientBackFactory implements FallbackFactory <UserInfoRemoteClient>{
@Override
public UserInfoRemoteClient create(Throwable throwable) {
return new UserInfoRemoteClient() {
@Override
public List<UserInfo> producer() {
System.out.println("Feign的fallbackFactory方式服务降级方法");
System.out.println(throwable.getMessage());
return Collections.emptyList();
}
};
}
}
调用远程方法
@RestController
public class UserInfoController {
@Resource
private UserInfoRemoteClient userInfoRemoteClient;
@RequestMapping("getUser")
public Map getUser() {
Map map=new HashMap<>();
List<UserInfo> userList = userInfoRemoteClient.producer();
map.put("userList",userList);
return map;
}
}
单个服务监控Hystrix仪表盘dashboard
创建dashboard项目
添加dashboard依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
设置端口
server.port=3721
启动类添加@EnableHystrixDashboard
@EnableHystrixDashboard
@SpringBootApplication
public class SpringcloudDomeHystrixDashboardApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudDomeHystrixDashboardApplication.class, args);
}
}
启动项目,访问http://localhost:3721/hystrix/
消费者项目
添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置文件添加
management.endpoints.web.exposure.include=hystrix.stream
访问消费者的actuator/hystrix.stream路径http://localhost:8081/actuator/hystrix.stream
通过仪表盘访问
必须访问一次消费者仪表盘才会显示信息
多个服务监控turbine
在上面单个服务监控Hystrix仪表盘dashboard的基础上
创建turbine项目
添加依赖
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
配置文件
server.port=3722
#实例名称
eureka.instance.instance-id=springcloud-producer-02
#Eureka链接地址
eureka.client.service-url.defaultZone=http://47.110.157.82:8761/eureka,http://47.110.157.82:8762/eureka,http://47.110.157.82:8763/eureka
#聚合两个Hystrix消费者,
turbine.app-config=springcloud-consumer-01,springcloud-consumer-02
turbine.cluster-name-expression="default"
启动类,添加@EnableTurbine
@EnableTurbine
@SpringBootApplication
public class SpringcloudDomeTurbineApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudDomeTurbineApplication.class, args);
}
}
通过仪表盘访问turbine:http://localhost:3722/turbine.stream
同时监控了8081,8082两个服务