在微服務系統中,我們把系統拆分成了很多小的服務,各個服務之間通過不同的方式進行依賴和調用,爲了保證服務的高可用性,單個服務通常會集羣部署,此時,許多服務由於各種問題可能會調用失敗,比如超時、異常等。如何能夠保證在一個依賴出問題的情況下,不會出現故障傳播,導致整體服務失敗,這個就是Hystrix需要做的事情。Hystrix提供了熔斷、隔離、Fallback、cache、監控等功能,能夠在一個、或多個依賴同時出現問題時保證系統依然可用。
本文介紹如何結合上一文SpringCloud教程(Finchley版本)-03:負載均衡(Ribbon),使用Hystrix來實現斷路器功能。主要分爲以下幾個步驟:
- 1.創建項目
- 2.引入依賴
- 3.修改配置文件
- 4.添加啓動註解
- 5.注入模板類
- 6.跨服務調用
- 7.啓動項目,測試
1.創建項目
新建一個Springboot項目hystrix_ribbon_server1。
2.引入依賴
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--eureka ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--springcloud依賴管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
3.修改配置文件
server:
port: 8017
spring:
application:
name: hystrix-ribbon-server
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
4.添加啓動註解
5.注入模板類
4.5步驟和前文的Ribbon一樣。
package com.java4all.hystrix_ribbon_server1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableHystrix
@EnableEurekaClient
@SpringBootApplication
public class HystrixRibbonServer1Application {
/**
*
* @Bean : 注入一個名爲restTemplate的bean
* @LoadBalanced :表明這個 restTemplate 開啓了負載均衡的功能
*
* */
@Bean
@LoadBalanced
RestTemplate restTemplate(){return new RestTemplate();}
public static void main(String[] args) {
SpringApplication.run(HystrixRibbonServer1Application.class, args);
}
}
6.跨服務調用
寫一套簡單的業務代碼,然後調用前面創建的company-server服務提供的接口。
6.1 controller
@RestController
@RequestMapping(value = "hrs")
public class HrsController {
@Autowired
private HrsService hrsService;
@GetMapping(value = "getCompany")
public String getCompany(String id){
String company = hrsService.getCompany(id);
System.out.println(company);
return company;
}
}
6.2 service
public interface RibbonService {
String getCompany(String id);
}
6.3 serviceImpl
在serviceImpl實現類中,我們引入前面的RestTemplate模板類,來跨服務調用,並開啓了負載均衡功能。
在getCompany方法上添加@HystrixCommand註解。該註解對該方法創建了熔斷器的功能,並指定了fallbackMethod熔斷方法erroCompany,熔斷方法直接返回了一個字符串
@Service
public class HrsServiceImpl implements HrsService{
//啓動類中注入了此模板,並且開啓了負載均衡功能
@Autowired
RestTemplate restTemplate;
//給方法添加熔斷器的功能,並指定熔斷方法
@HystrixCommand(fallbackMethod = "erroCompany")
@Override
public String getCompany(String id) {
//程序名替代服務地址,ribbon會根據服務名自動選擇服務實例
String company = restTemplate
.getForObject("http://company-server/company/get?id=" + id, String.class);
return company;
}
/**熔斷方法*/
public String erroCompany(String id){
return "服務出錯,返回默認企業:"+id;
}
}
7.啓動項目,測試
此時,啓動項目,訪問http://localhost:8017/hrs/getCompany?id=234,我們這個項目的接口會去調用前面啓動的企業服務,由於企業服務啓動了兩臺:8011,8014,那麼,通過ribbon負載均衡後,會分發到兩臺服務上。如下:
當我們把8011掛掉後,此時,由於eureka更新服務列表默認時間爲30s,這之間,如果請求落在8011上,那麼,就會調用熔斷方法,返回指定的結果,如下:
下一篇:SpringCloud教程(Finchley版本)-05:負載均衡(Feign)
完整源碼參考:https://github.com/myJava4all/springcloudfinchley