知識庫 / Spring RSS 訂閱

Spring 應用中 Hystrix 集成

Cloud,Spring
HongKong
5
02:47 PM · Dec 06 ,2025

1. 概述

在上一篇文章中,我們探討了 Hystrix 的基本原理以及它如何幫助構建容錯和彈性應用程序。

許多現有的 Spring 應用程序會調用外部系統,這些系統可以通過 Hystrix 獲得好處。不幸的是,由於種種原因,可能無法重寫這些應用程序以集成 Hystrix,但藉助 Spring AOP,可以實現一種非侵入式的集成方式。

在本文中,我們將探討如何將 Hystrix 集成到現有的 Spring 應用程序中。

2. 將 Hystrix 集成到 Spring 應用中

2.1. 現有應用程序

讓我們來查看應用程序的現有客户端調用,該調用向我們之前文章中創建的 RemoteServiceTestSimulator 發出請求:

@Component("springClient")
public class SpringExistingClient {

    @Value("${remoteservice.timeout}")
    private int remoteServiceDelay;

    public String invokeRemoteServiceWithOutHystrix() throws InterruptedException {
        return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
    }
}

如上代碼片段所示,invokeRemoteServiceWithOutHystrix方法負責向RemoteServiceTestSimulator遠程服務發起調用。當然,實際應用中不會如此簡單。

2.2. 創建環繞建議

為了演示如何集成 Hystrix,我們將此客户端作為示例。

為此,我們將定義一個 Around 建議,該建議將在 invokeRemoteService 執行時生效:

@Around("@annotation(com.baeldung.hystrix.HystrixCircuitBreaker)")
public Object circuitBreakerAround(ProceedingJoinPoint aJoinPoint) {
    return new RemoteServiceCommand(config, aJoinPoint).execute();
}

上述建議旨在作為 Around 建議,在帶有 @HystrixCircuitBreaker 註解的點切上執行。

現在讓我們來查看 HystrixCircuitBreaker 註解的定義:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HystrixCircuitBreaker {}

2.3. 熔斷器邏輯

現在我們來查看 RemoteServiceCommand。它作為樣代碼中的一個 靜態內部類實現,以便封裝熔斷器調用邏輯:

private static class RemoteServiceCommand extends HystrixCommand<String> {

    private ProceedingJoinPoint joinPoint;

    RemoteServiceCommand(Setter config, ProceedingJoinPoint joinPoint) {
        super(config);
        this.joinPoint = joinPoint;
    }

    @Override
    protected String run() throws Exception {
        try {
            return (String) joinPoint.proceed();
        } catch (Throwable th) {
            throw new Exception(th);
        }
    }
}

整個 Aspect 組件的實現可以在源代碼中找到。

2.4. 使用 @HystrixCircuitBreaker</em/> 註解

一旦切面已定義,就可以使用 @HystrixCircuitBreaker</em/> 註解來標記客户端方法,如以下示例所示。Hystrix 會在對標記了該註解的方法進行調用時被觸發。

@HystrixCircuitBreaker
public String invokeRemoteServiceWithHystrix() throws InterruptedException{
    return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
}

以下集成測試將演示 Hystrix 路由和非 Hystrix 路由之間的差異。

2.5. 測試集成

為了演示目的,我們定義了兩種方法執行路徑:一種包含 Hystrix,另一種不包含。

public class SpringAndHystrixIntegrationTest {

    @Autowired
    private HystrixController hystrixController;

    @Test(expected = HystrixRuntimeException.class)
    public void givenTimeOutOf15000_whenClientCalledWithHystrix_thenExpectHystrixRuntimeException()
      throws InterruptedException {
        hystrixController.withHystrix();
    }

    @Test
    public void givenTimeOutOf15000_whenClientCalledWithOutHystrix_thenExpectSuccess()
      throws InterruptedException {
        assertThat(hystrixController.withOutHystrix(), equalTo("Success"));
    }
}

當測試執行時,你可以看到不使用 Hystrix 的方法調用會等待遠程服務的完整執行時間,而使用 Hystrix 路由的方法會在定義的超時時間(在本例中為 10 秒)內短路並拋出 HystrixRuntimeException

3. 結論

我們可以為每個遠程服務調用創建不同的方面,以便使用不同的配置進行交互。在下一篇文章中,我們將探討如何從項目的開端開始集成 Hystrix。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.