0

Unsere Anwendung ist in anit-zerbrechlichen Weise geschrieben, indem Leistungsschalter Muster mit Hilfe von Hystrix implementiert.Test-Treiber Hystrix Circuit Breaker Konfiguration

Die gesamte Anwendung wird mit testgetriebener Praxis erstellt, ist aber an dem Punkt hängen geblieben, an dem wir die Schutzschalterstrategie implementieren müssen, indem wir dieselbe für die Methoden konfigurieren.

Im Folgenden finden Sie die Beispielkonfiguration von uns verwendeten -

@HystrixCommand(commandProperties = { 
     @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), 
     @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "8"), 
     @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "25"), 
     @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")}, 
     fallbackMethod = "retrieveMapFallback") 

Kann jemand Kommentar, wenn es eine verfügbare Funktion oder die Möglichkeit, treiben es in meinem Integrationstest zu testen (die die gesamte WebApplicationContext lädt und damit kennt alle Konfigurationen, die mit der Anwendung verfügbar sind)?

Oder wenn dies in meinem App-Kontext überhaupt nicht verifiziert werden kann?

Alle Eingänge sind von Wert.

Antwort

1

Sie können Ihre Leistungsschalterkonfiguration Hystrix testen.

Nehmen Sie zum Beispiel einen Blick auf dieses Beispiel-Anwendung mit Spring Boot 1.4:

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 
import org.springframework.stereotype.Component; 

@EnableCircuitBreaker 
@SpringBootApplication 
public class HystrixDemo { 

    public static void main(String[] args) { 
     SpringApplication.run(HystrixDemo.class, args); 
    } 

    @Component 
    static class MyService { 

     static final String COMMAND_KEY = "MyCommandKey"; 

     private final Outbound outbound; 

     MyService(Outbound outbound) { 
      this.outbound = outbound; 
     } 

     @HystrixCommand(
       commandKey = COMMAND_KEY, 
       commandProperties = { 
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2016") 
       }) 
     void process() { 
      outbound.call(); 
     } 
    } 

    interface Outbound { 
     void call(); 
    } 
} 

Ihre Konfigurationstests aussehen wie diese:

import com.netflix.hystrix.HystrixCommandKey; 
import com.netflix.hystrix.HystrixCommandMetrics; 
import com.netflix.hystrix.HystrixCommandProperties; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.boot.test.mock.mockito.MockBean; 
import org.springframework.test.context.junit4.SpringRunner; 

import static org.junit.Assert.assertTrue; 

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class MyServiceCircuitBreakerConfigurationTests { 

    @Autowired 
    private HystrixDemo.MyService myService; 

    @MockBean 
    private HystrixDemo.Outbound outbound; 

    @Before 
    public void setup() { 
     warmUpCircuitBreaker(); 
    } 

    @Test 
    public void shouldHaveCustomTimeout() { 
     assertTrue(getCircuitBreakerCommandProperties().executionTimeoutInMilliseconds().get() == 2016); 
    } 

    private void warmUpCircuitBreaker() { 
     myService.process(); 
    } 

    public static HystrixCommandProperties getCircuitBreakerCommandProperties() { 
     return HystrixCommandMetrics.getInstance(getCommandKey()).getProperties(); 
    } 

    private static HystrixCommandKey getCommandKey() { 
     return HystrixCommandKey.Factory.asKey(HystrixDemo.MyService.COMMAND_KEY); 
    } 
} 

Darüber hinaus, wenn Sie möchten, Schutzschalter testen Sie können einen Blick auf diesen Test werfen:

import com.netflix.config.ConfigurationManager; 
import com.netflix.hystrix.Hystrix; 
import com.netflix.hystrix.HystrixCircuitBreaker; 
import com.netflix.hystrix.HystrixCommandKey; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.boot.test.mock.mockito.MockBean; 
import org.springframework.test.context.junit4.SpringRunner; 

import static org.junit.Assert.assertFalse; 
import static org.junit.Assert.assertTrue; 
import static org.junit.Assert.fail; 
import static org.mockito.BDDMockito.willThrow; 

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class MyServiceCircuitBreakerTests { 

    @Autowired 
    private HystrixDemo.MyService myService; 

    @MockBean 
    private HystrixDemo.Outbound outbound; 

    @Before 
    public void setup() { 
     resetHystrix(); 
     warmUpCircuitBreaker(); 
     openCircuitBreakerAfterOneFailingRequest(); 
    } 

    @Test 
    public void shouldTripCircuit() throws InterruptedException { 
     willThrow(new RuntimeException()).given(outbound).call(); 

     HystrixCircuitBreaker circuitBreaker = getCircuitBreaker(); 

     // demonstrates circuit is actually closed 
     assertFalse(circuitBreaker.isOpen()); 
     assertTrue(circuitBreaker.allowRequest()); 

     try { 
      myService.process(); 
      fail("unexpected"); 
     } catch (RuntimeException exception) { 
      waitUntilCircuitBreakerOpens(); 
      assertTrue(circuitBreaker.isOpen()); 
      assertFalse(circuitBreaker.allowRequest()); 
     } 
    } 

    private void waitUntilCircuitBreakerOpens() throws InterruptedException { 
     /* one second is almost sufficient 
      borrowed from https://github.com/Netflix/Hystrix/blob/v1.5.5/hystrix-core/src/test/java/com/netflix/hystrix/HystrixCircuitBreakerTest.java#L140 
     */ 
     Thread.sleep(1000); 
    } 

    private void resetHystrix() { 
     Hystrix.reset(); 
    } 

    private void warmUpCircuitBreaker() { 
     myService.process(); 
    } 

    public static HystrixCircuitBreaker getCircuitBreaker() { 
     return HystrixCircuitBreaker.Factory.getInstance(getCommandKey()); 
    } 

    private static HystrixCommandKey getCommandKey() { 
     return HystrixCommandKey.Factory.asKey(HystrixDemo.MyService.COMMAND_KEY); 
    } 

    private void openCircuitBreakerAfterOneFailingRequest() { 
     ConfigurationManager.getConfigInstance().setProperty("hystrix.command." + HystrixDemo.MyService.COMMAND_KEY + ".circuitBreaker.requestVolumeThreshold", 1); 
    } 
} 
+0

Es ist eine gute Antwort. Danke dafür @ksokol. Ich werde es ausprobieren und ggf. Inputs teilen. –