Spring Boot微服务+ Hystrix Circuit Breaker
在本文中,我们将介绍如何配置Netflix Hystrix容错库以及Spring Boot微服务。 Hystrix库提供了断路器模式的实现,我们可以使用该模式将断路器应用于可能失败的方法调用。我们还可以指定一个备用方法,Hystrix将失败的方法调用重定向到该方法。
Hystrix Circuit Breaker如何工作
Spring Cloud Netflix Hystrix寻找任何带有@HystrixCommand注释的方法。这种方法被包装在连接到断路器的代理中,以便Hystrix可以对其进行监视。
如果对实际方法的远程调用失败,则Hystrix会调用fallback方法。
例如
@GetMapping(value="/{id}") @HystrixCommand(fallbackMethod = "defaultAccounts") public List<Account> showEmployees(@PathVariable("id") String id) { ... ... }
如果由于任何原因(例如网络问题)而对showEmployees()的调用仍然失败,Hystrix会在showEmployees()方法上打开一个电路,然后回退到fallback方法上,以至少向用户显示某些内容,而不显示任何内容或者堆栈跟踪基本异常。
带Hystrix的Spring Boot微服务示例
我们将以本篇Spring Boot Microservices示例中使用的示例为基础,并进行更改以配置Hystrix。
在该示例中,有两个微服务用户和帐户,并且从用户那里调用了帐户以获取所传递ID的帐户详细信息。在该应用程序中,Eureka用于注册服务和发现服务。
Hystrix断路器的更改
在Spring Boot项目中,对于Eureka Server和帐户服务应用程序都不需要进行任何更改。
在User Spring Boot项目中,必须添加对Hystrix的依赖关系,并且必须使用以下Rest Controller类和Service类。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
UserController类
有一个方法showEmployees,它又在UserService类中调用该方法。
import java.util.Collections; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @Autowired private UserService userService; @GetMapping(value="/{id}") public List<Account> showEmployees(@PathVariable("id") String id) { //System.out.println(id); List<Account> accounts = userService.showEmployees(id); return accounts; } }
UserService类
从showEmployees()方法中,调用Account微服务以获取传递的员工ID的所有关联帐户。为了进行远程调用,使用RestTemplate实例。
ShowEmployees()方法带有@HystrixCommand注释,该注释还指定了在无法调用远程微服务的情况下要使用的后备方法(defaultAccounts)。
后备方法defaultAccounts()返回一个空列表。
import java.util.Collections; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @Service public class UserService { @Autowired private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "defaultAccounts") public List<Account> showEmployees(@PathVariable("id") String id) { System.out.println(id); // List<Account> accounts = new RestTemplate().exchange( // "http://localhost:9000/accounts/{empId}", HttpMethod.GET, null, new // ParameterizedTypeReference<List<Account>>(){}, id).getBody(); List<Account> accounts = restTemplate.exchange( "http://ACCOUNT/accounts/{empId}", HttpMethod.GET, null, new ParameterizedTypeReference<List<Account>>(){}, id).getBody(); for(Account acct : accounts) { System.out.println(acct.getEmpId()); System.out.println(acct.getAccountId()); System.out.println(acct.getBranch()); } return accounts; } // Fall back method used in case circuit is opened public List<Account> defaultAccounts(String id) { return Collections.emptyList(); } }
SpringBootUserApplication类
具有主要方法的应用程序类使用@SpringCloudApplication注释进行注释,这是一种方便的注释,包括@ SpringBootApplication,@ EnableDiscoveryClient和@EnableCircuitBreaker注释。要使用Hystrix @EnableCircuitBreaker注释启用断路器模式,则需要使用该注释。
@SpringCloudApplication public class SpringBootUserApplication { public static void main(String[] args) { SpringApplication.run(SpringBootUserApplication.class, args); } }
现在,如果所有项目EurekaServer,User和Account都在运行,则访问URL http:// localhost:8080/1即可得到结果。
现在停止帐户服务,以查看断路器的工作方式。访问URL http:// localhost:8080/1现在返回一个空列表。
使用Hystrix仪表板监控电路
我们已经配置了断路器,实现了一种故障预置方法,如果远程服务中断,则必须执行该故障预置方法。但是问题是我们如何监视电路是开路还是闭合?为此,我们可以使用Hystrix仪表板。在本节中,我们将看到如何使用Hystrix仪表板来监视单个应用程序。
对于Hystrix仪表板,我们将创建一个新的Spring Boot Application,并选择启动器作为Hystrix仪表板,它会添加以下依赖项。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
在application.properties文件中添加端口
server.port=7900
我将这个SpringBoot应用程序命名为SpringBootHystrix,因此该应用程序类为SpringBootHystrixApplication,在该类中还与@SpringBootApplication一起添加了@EnableHystrixDashboard注释。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; @SpringBootApplication @EnableHystrixDashboard public class SpringBootHystrixApplication { public static void main(String[] args) { SpringApplication.run(SpringBootHystrixApplication.class, args); } }
用户微服务的变化
每个直接或者通过@SpringCloudApplication应用@EnableCircuitBreaker注释的微服务都有一个/hystrix.stream端点,该端点输出电路指标。在我们的例子中,使用@EnableCircuitBreaker的是User微服务,因此需要进行一些更改才能将hystrix.stream公开为端点。
将执行器添加为依赖项
我们需要在项目中添加执行器依赖项。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
application.properties中的更改
在application.properties中添加端点
management.endpoints.web.exposure.include=hystrix.stream, health, info
这里还添加了运行状况和信息,但是对于Hystrix仪表板,必须要有hystrix.stream。
通过这些更改和启动的应用程序,我们可以使用URL-http:// localhost:7900 / hystrix /访问Hystrix仪表板
在此页面上,我们可以输入公开/hystrix.stream端点的服务的URL。因此,输入URLhttp:// localhost:8080 / actuator / hystrix.stream并为Title输入一些值。然后单击"监视流"。
要检查电路是否断开,我们可以关闭帐户服务(无法访问意向帐户服务),并创建一个模拟器,以便在几毫秒后将请求发送到http:// localhost:8080/1. 或者,我们可以在浏览器窗口中输入此URL后多次按Enter键。许多失败的请求将导致电路断开,并且更改也将反映在仪表板中。