前言
前面做了一個簡單的服務 注冊。服務發現,服務提供者和消費者的項目,現在我們還是準備之前的項目代碼
1、 服務容錯保護,準備的項目工程
1、服務注冊中心 ,端口為1111
2、服務提供者,端口為8080,8081
3、服務消費者 端口為9000
2、在服務消費者中引入依賴包
hystrix 對應的中文名字是“豪豬”,豪豬周身長滿了刺,能保護自己不受天敵的傷害,代表了一種防禦機制,這與hystrix本身的功能不謀而合,是以Netflix團隊将該架構命名為Hystrix,并使用了對應的卡通形象做作為logo。
在一個分布式系統裡,許多依賴不可避免的會調用失敗,比如逾時、異常等,如何能夠保證在一個依賴出問題的情況下,不會導緻整體服務失敗,這個就是Hystrix需要做的事情。Hystrix提供了熔斷、隔離、Fallback、cache、監控等功能,能夠在一個、或多個依賴同時出現問題時保證系統依然可用。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.didispace</groupId>
<artifactId>ribbon-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ribbon-consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<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.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、注解開啟斷路器功能@EnableCircuitBreaker
解釋:這裡還可以使用 @ SpringCloudApplication 注解代替上面三個注解,由此也可以得到spring Cloud标準應用包含服務發下和斷路器
@EnableCircuitBreaker //開啟斷路器功能
@EnableDiscoveryClient //開啟服務發現用戶端,
@SpringBootApplication
@SpringCloudApplication //可以取代上面三個
public class ConsumerApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
//或者下面這個
@ SpringCloudApplication
public class ConsumerApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
4、@HystrixCommand(方法内部報錯之後,自動去找復原的方法)
4.1、建立service類,用來添加指定回調方法
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "helloFallBack")
public String hello(){
return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();
}
public String helloFallBack(){
return "error";
}
}
5、修改之前服務消費者的Controller方法
@RestController
public class ConsumerController {
@Autowired
HelloService helloService;
@ResponseBody
@RequestMapping(value = "/ribbon-consumer", method = RequestMethod.GET)
public String helloConsumer() {
return helloService.hello();
}
}
6、開始驗證斷路器的實作的回調邏輯,
6.1、啟動所有的服務
通路http://localhost:9000/ribbon-consumer
6.2、在8080 8081 這兩個服務提供者工作的時候,傳回的結果都是一樣的
6.3、直接斷開8081服務提供者
這個時候我們将8081的服務提供者挂掉,繼續通路,發現一會正常,一會顯示error,但是時間長了,就還是隻會顯示hello ,出現這種情況,應該是注冊中心沒有及時檢測到挂掉了8081,還繼續提供給消費者服務。但是時間長了,就肯定原型畢露
7、模拟服務阻塞,添加延遲
解釋:(hystrix預設逾時2000毫秒) (啟動所有的服務)
7.1、服務提供者中添加延遲時間設定為3000毫秒
/**
* 2、斷路器,模拟服務阻塞
*/
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() throws InterruptedException {
ServiceInstance instance = client.getLocalServiceInstance();
int sleepTime = new Random().nextInt(3000);
logger.info("處理線程等待 "+sleepTime+" 秒");
Thread.sleep(sleepTime);
logger.info("/hello, host:" + instance.getHost() + ", service_id:" + instance.getServiceId());
return "Hello World";
}