Spring Boot微服务+ Hystrix Circuit Breaker

时间:2020-01-09 10:44:31  来源:igfitidea点击:

在本文中,我们将介绍如何配置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键。许多失败的请求将导致电路断开,并且更改也将反映在仪表板中。