一、Hystrix介紹
Hystrix是一個延遲容錯庫。在分佈式環境中,許多服務依賴項中的一些不可避免地會失敗。如果這時候有大量的請求請求這個故障的服務,由於服務之間的依賴關係,故障會進行蔓延,這時候會導致調用服務自身也出現不可用的情況,使用Hystrix可以解決這個問題。當某個服務發生故障(類似用電器發生短路)之後,通過斷路器的故障監控(類似熔斷保險絲),向調用方返回一個錯誤響應,而不是長時間的等待。這樣就不會使得線程因調用故障服務被長時間佔用不釋放,避免了故障在分佈式系統中的蔓延。
二、服務熔斷
基於上個博客搭建的工程改造
- 單獨服務熔斷
更改服務調用者
<!-- 依賴 Spring Cloud Netflix Hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
@Override
@HystrixCommand(
// Command 配置,設置操作時間爲 100 毫秒
commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100")},
// 設置 fallback 方法
fallbackMethod = "fallbackForGetUsers"
)
public List<UserDto> findAll() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
return userService.findAll();
}
/**
* 超過100毫秒就返回空集合
* @return
*/
public List<UserDto> fallbackForGetUsers() {
System.err.println("超時熔斷");
return new ArrayList<>();
}
先調用增加用戶,在調用查看用戶
- 基於Feign熔斷
Api工程改造(spring-cloud-interface-demo)
//增加回調
@FeignClient(name="service-demo",fallback = UserFallback.class)
@Slf4j
@Component
public class UserFallback implements UserService{
@Override
public boolean saveUser(UserDto user) {
System.err.println("新增進入熔斷");
return false;
}
@Override
public List<UserDto> findAll() {
System.err.println("查詢進入熔斷");
return new ArrayList<>();
}
}
服務提供者改造(spring-cloud-interface-demo)
@GetMapping("find/all")
public List<UserDto> findAll() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return userService.findAll();
}
服務提供者改造(spring-cloud-interface-demo)
#開啓熔斷 默認false
feign:
hystrix:
enabled: true
ribbon:
ServerListRefreshInterval: 15000 # 從註冊中心刷新servelist的時間 默認30秒,單位ms
ConnectTimeout: 500 # 請求連接的超時時間 默認1秒,單位ms
ReadTimeout: 200 # 請求處理的超時時間 默認1秒,單位ms
MaxAutoRetries: 1 # 對當前實例的重試次數 默認0
MaxAutoRetriesNextServer: 0 # 切換實例的重試次數 默認1
hystrix:
command:
#修改這裏可以爲一個服務或者一個方法設置超時時長
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
@Slf4j
@RestController
public class DemoController implements UserService {
//UserService@FeignClient註解默認primary是true,相當於代理
@Autowired
private UserService userService;
//這裏使用Feign的繼承特性,會將UserService裏面的@RequestMapping繼承過來但是@RequestBoday是不會繼承過來的
@Override
public boolean saveUser(@RequestBody UserDto user) {
return userService.saveUser(user);
}
@Override
public List<UserDto> findAll() {
return userService.findAll();
}
}
先新增用戶,在查詢用戶即可看到效果