2015-04-08 1 views
1

Je construit un exemple de court-circuit Hystrix super simple basé sur @spencergibb feindre-eureka exemple de démarrage nuage de printemps. Au début, je pensais que je ne pouvais pas obtenir la valeur par défaut hystrix javanica fallbackMethod pour déclencher en raison de feindre .. maintenant, la suppression Feindre, la valeur par défaut hystrix fallbackMethod ne fonctionne toujours pas attraper des exceptions.Hystrix Javanica REPLI ne fonctionne pas au printemps Nuage 1.0

pom.xml

<parent> 
    <groupId>org.springframework.cloud</groupId> 
    <artifactId>spring-cloud-starter-parent</artifactId> 
    <version>1.0.0.RELEASE</version> 
    <relativePath /> <!-- lookup parent from repository --> 
</parent> 

<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <java.version>1.8</java.version> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.cloud</groupId> 
     <artifactId>spring-cloud-starter-eureka</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.cloud</groupId> 
     <artifactId>spring-cloud-starter-hystrix</artifactId> 
    </dependency> 
    : 
</dependencies> 

Fichier principal:

@SpringBootApplication 
@EnableDiscoveryClient 
@EnableHystrix 
@RestController 
public class HelloClientApplication { 

    @Autowired 
    HelloClientComponent helloClientComponent; 

    @RequestMapping("/") 
    public String hello() { 
    return helloClientComponent.makeMultipleCalls(); 
    } 

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

}

HelloClientComponent.java (créé parce que je sais javanica attend être à l'intérieur d'un composant géré de printemps ou d'un service):

@Component 
public class HelloClientComponent { 

@Autowired 
RestTemplate restTemplate; 

public String makeMultipleCalls() { 
    int cnt=20; 
    StringBuilder sb = new StringBuilder(); 
    while (cnt-- > 0) { 
     String response = theServerRequestRoot(); 
     sb.append(response).append(" "); 
    } 
    return sb.toString(); 
} 

public String theServersRequestRootFallback() { 
    System.out.println("BOMB!!!!!!"); 
    return "BOMB!!!!!!"; 
} 

@HystrixCommand(fallbackMethod = "theServersRequestRootFallback", commandKey = "callToServers") 
public String theServerRequestRoot() { 
     ResponseEntity<String> result = restTemplate.getForEntity("http://HelloServer", String.class); 
     System.out.println(result.getBody()); 
     return result.getBody(); 
} 
} 

Je démarre 2 serveurs, un qui réussit toujours et répond, et l'autre échouera 30% du temps avec une erreur de 500. Quand je courbe ce client (à '/') les choses vont normalement pour les appels d'échecs non forcés. Round robining fonctionne bien aussi. Lorsque le deuxième serveur renvoie l'erreur 500, le fallbackMethod n'est pas appelé et la boucle à '/' se termine et renvoie une erreur.

Mise à jour avec une solution par les suggestions de Spencer et Dave. changement à ce qui suit:

fichier d'application principal:

@SpringBootApplication 
@EnableDiscoveryClient 
@EnableHystrix 
@RestController 
public class HelloClientApplication { 

    @Autowired 
    HelloClientComponent helloClientComponent; 

@RequestMapping("/") 
public String hello() { 
    int cnt=20; 
    StringBuilder sb = new StringBuilder(); 
    while (cnt-- > 0) { 
     String response = helloClientComponent.theServerRequestRoot();  // call directly to @Component in order for @HystrixCommand to intercept via AOP 
     sb.append(response).append(" "); 
    } 
    return sb.toString(); 
} 

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

HelloClientComponent.java:

@Component 
public class HelloClientComponent { 

@Autowired 
RestTemplate restTemplate; 

public String theServersRequestRootFallback() { 
    System.out.println("BOMB!!!!!!"); 
    return "BOMB!!!!!!"; 
} 

@HystrixCommand(fallbackMethod = "theServersRequestRootFallback", commandKey = "callToServers") 
public String theServerRequestRoot() { 
     ResponseEntity<String> result = restTemplate.getForEntity("http://HelloServer", String.class); 
     System.out.println(result.getBody()); 
     return result.getBody(); 
} 
} 
+0

Je vais jeter un coup d'oeil. – spencergibb

Répondre

5

@HystrixCommand ne fonctionne que parce que le printemps fait un proxy pour appeler cette méthode sur. Si vous appelez la méthode depuis le proxy, elle ne passe pas par l'intercepteur. Vous devez appeler le @HystrixCommand à partir d'un autre @Component (ou utiliser AspectJ).

+0

déplacer yup '' makeMultipleCalls' à HelloClientApplication.hello' – spencergibb

+0

Exactement mon problème. Maintenant, il a cliqué sur pourquoi la méthode annotée avec HystrixCommand doit être dans un composant ou un service. Clarifié beaucoup avec moi. Dommage encore une fois le doc Javanica ne clarifie pas cela bien qu'il fasse maintenant allusion à l'option de configuration d'un Aspect. Je posterai une mise à jour du code pour les futurs lecteurs. – RubesMN