Hystrix 是 Netflix 開源的延遲與容錯庫,提供**熔斷**、**降級**、**隔離**等機制,防止單一服務失敗導致雪崩。本文記錄 Spring Boot 1.5.x 整合 Hystrix 核心步驟。
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.2</version>
</dependency>
# application.properties
hystrix.timeoutInMillions = 3000
對應配置類:
@Component
@ConfigurationProperties(prefix = "hystrix")
@Getter @Setter
public class HyStrixProperties {
private int timeoutInMillions;
}
繼承 HystrixCommand<Response>,實作 run()(正常邏輯)與 getFallback()(降級邏輯)。
public class MyHystrixCommand extends HystrixCommand<Response> {
private static final Logger LOGGER = LoggerFactory.getLogger(MyHystrixCommand.class);
private String url;
public MyHystrixCommand(Setter setter, String url) {
super(setter);
this.url = url;
}
@Override
protected Response run() throws Exception {
LOGGER.info("服務正被調用,線程:{}", Thread.currentThread().getName());
Request request = new Request.Builder().url(url).build();
return new OkHttpClient().newCall(request).execute();
}
@Override
public Response getFallback() {
LOGGER.error("服務調用失敗");
return null; // 或返回預設回應
}
}
組裝 Setter(群組鍵、命令鍵、超時屬性),提供同步/異步執行入口。
@Component
public class HystrixUtil {
@Autowired private HyStrixProperties hp;
public Response execute(String serviceName, String methodName, String url)
throws InterruptedException, ExecutionException {
Setter setter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(serviceName))
.andCommandKey(HystrixCommandKey.Factory.asKey(methodName))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(hp.getTimeoutInMillions()));
return new MyHystrixCommand(setter, url).execute(); // 同步
// 異步:Future<Response> f = new MyHystrixCommand(setter, url).queue(); return f.get();
}
}
@RestController
@RequestMapping("/hystrix")
public class HystrixController {
@Value("${service.hotel.url}") private String HOTEL_URL;
@Value("${service.hotel.name}") private String hotelServiceName;
@Value("${service.hotel.method.getHotelInfo}") private String methodName;
@Autowired private HystrixUtil hystrixUtil;
@GetMapping("/firstHystrix")
public String getHotelInfo(@RequestParam int id, @RequestParam String name) {
String url = String.format(HOTEL_URL, id, name);
try {
Response resp = hystrixUtil.execute(hotelServiceName, methodName, url);
if (resp != null) return resp.body().string();
} catch (Exception e) { e.printStackTrace(); }
finally { /* 關閉 response.body() */ }
return "獲取酒店信息失敗";
}
}
@RestController
@RequestMapping("/hotel")
public class HotelController {
@GetMapping("/getHotelInfo")
public Hotel getHotelInfo(@RequestParam int id, @RequestParam String name) {
// 模擬延遲測試熔斷:TimeUnit.MILLISECONDS.sleep(2000);
return new Hotel(id, name);
}
}