在微服务架中,所有功能均通过微服务来提供,如果其中某个关键微服务出现问题,如响应时间过长,那么所有调用这个微服务的微服务都会变慢,由于调用者微服务变慢,进一步会使其他更广泛的微服务变慢,最终整个系统可能会因为一个微服务出现问题,而使整个微服务架构出现故障。为了防止这种现象的发生,我们可以使用Spring Cloud中的Hystrix组件。
Hystrix组件的原理是对每个微服务,都会维护其当前状态,如果监测到某个微服务响应时间过长时,再有对这个微服务的访问,就会执行报告该微服务不可用的错误响应程序,通过这个微服务调用者,该微服务当前不可用。这样虽然有一些微服务调用会失败,但是就不会出一个微服务失败,拖慢整个系统的情况了。
我们首先需要在服务使用者项目中添加依赖,如下所示:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
在启动类ProductConsumerApplication上添加@EnableCircuitBreaker注解:
@EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
public class ProductConsumerApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ProductConsumerApplication.class, args);
}
}
接着我们需要添加一个新的Service类,用来处理对远程微服务的访问,如下所示:
@Service
public class ProductService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod="callProductServiceError")
public String callPrudctService() {
ResponseEntity<String> resp = restTemplate.getForEntity("http://mse001/products",
String.class);
return resp.getBody();
}
public String callProductServiceError() {
return "{\"status\": \"Error\", \"errorCode\":1001, \"errorMsg\": \"测试Hystrix\"}";
}
}
在这里我们定义了一个Service组件,将调用其他微服务的方法添加@HystrixCommand注解,其中的参数为当调用不能成功时,系统会自动调用的方法。当在实际应用中,如果被调用的微服务不可用,系统会自动调用fallbackMethod方法。如果被调服务正常的话,则与前一节的处理方式一致。
我们接下来需要适当改造一下Controller,使其调用我们新写的Service组件:
@RestController
public class ProductConsumerController {
@Autowired
ProductService productService;
@RequestMapping(value="/product-consumer", method=RequestMethod.GET)
public String callServiceExample() {
return productService.callPrudctService();
}
}
第3、4行:通过注解方式从Spring框架获取服务组件;
第8行:通过调用我们新定义的服务组件,实现对远程微服务的调用。
经过上述程序,当远程微服务不可用时,会显示错误信息,如果远程微服务可用,则返回正常的调用结果。