前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloud学习笔记(4):Hystrix容错机制

SpringCloud学习笔记(4):Hystrix容错机制

作者头像
布禾
修改2020-11-19 10:09:37
3980
修改2020-11-19 10:09:37
举报
文章被收录于专栏:好好学习,天天向上

简介

在微服务架构中,微服务之间的依赖关系错综复杂,难免的某些服务会出现故障,导致服务调用方出现远程调度的线程阻塞。在高负载的场景下,如果不做任何处理,可能会引起级联故障,导致服务调用方的资源耗尽甚至整个系统奔溃。Hystrix是一个由Netflix开源的一个延迟和容错库,它通过添加延迟容忍和容错逻辑来帮助控制这些微服务之间的交互。Hystrix通过隔离服务之间的访问点、停止跨服务的级联故障并提供回退选项来实现这一点,所有这些选项都提高了系统的总体弹性。

项目介绍

  1. sc-parent,父模块(请参照SpringCloud学习笔记(1):Eureka注册中心)
  2. sc-eureka,注册中心(请参照SpringCloud学习笔记(1):Eureka注册中心)
  3. sc-provider,提供者(请参照SpringCloud学习笔记(1):Eureka注册中心)
  4. sc-consumer-hystrix-ribbon,使用Hystrix+Ribbon的消费者
  5. sc-consumer-hystrix-feign,使用Hystrix+Feign的消费者

在Ribbon上使用Hystrix

1.在父模块下创建子模块项目sc-consumer-hystrix-ribbon,pom.xml:
代码语言:javascript
复制
<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>
  <parent>
    <groupId>com.cf</groupId>
    <artifactId>sc-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>sc-consumer-hystrix-ribbon</artifactId>
  
  <dependencies>
  	<dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
	</dependency>
	<dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
	</dependency>
  </dependencies>
</project>
2.创建启动类consumer.ConsumerApplication:
代码语言:javascript
复制
package consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableCircuitBreaker
public class ConsumerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConsumerApplication.class, args);
	}
	
	//为RestTemplate整合Ribbon,使其具备负载均衡的能力
	@LoadBalanced
	@Bean
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}
}
3.创建调用提供者服务的Controller:consumer.controller.ConsumerController
代码语言:javascript
复制
package consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@RestController
public class ConsumerController {
	@Autowired
	private RestTemplate restTemplate;
	
	@HystrixCommand(fallbackMethod="getBookListFallBack")
	@GetMapping("/getBookList")
	public String getBookList(){
		return restTemplate.getForObject("http://sc-provider/book/list", String.class);
	}
	
	public String getBookListFallBack(){
		return "[\"Java入门到放弃\"]";
	}
}

@HystrixCommand:表示将getBookList方法作为hystrix命令调用的方法。

fallbackMethod:指定处理回退逻辑的方法,这里是getBookListFallBack方法,当getBookList方法跑出异常时将会调用getBookListFallBack方法。

注意:回退方法应该与作为hystrix命令调用的方法具有相同的签名。

4.创建application.yml:
代码语言:javascript
复制
server:
  port: 8083

spring:
  application:
    name: sc-consumer-hystrix-ribbon
    
eureka:
  client:
    registerWithEureka: false
    serviceUrl:
      defaultZone: http://localhost:8080/eureka/    
5.测试

依次启动注册中心sc-eureka、提供者sc-provider、消费者sc-consumer-hystrix-ribbon,并访问http://localhost:8083/getBookList,结果显示如下:

这是提供者正常返回的值,接下来将提供者sc-provider关闭,再次访问http://localhost:8083/getBookList,结果显示如下:

因为将提供者sc-provider关闭后,消费者再访问提供者时会报错,Hystrix捕获异常后会直接调用回退方法也就是getBookListFallBack方法。

在Feign上使用Hystrix

1.在父模块下创建子模块项目sc-consumer-hystrix-feign,pom.xml:
代码语言:javascript
复制
<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>
  <parent>
    <groupId>com.cf</groupId>
    <artifactId>sc-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>sc-consumer-hystrix-feign</artifactId>
  
  <dependencies>
  	<dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
	</dependency>
	<dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>
	<dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
	</dependency>
  </dependencies>
</project>
2.创建启动类feign.FeignApplication:
代码语言:javascript
复制
package feign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
public class FeignApplication {
	public static void main(String[] args) {
		SpringApplication.run(FeignApplication.class, args);
	}
}
3.创建Feign声明式接口:feign.inter.BookService
代码语言:javascript
复制
package feign.inter;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;

import feign.fallback.BookFallBack;

@FeignClient(value="sc-provider", fallbackFactory=BookFallBack.class)
public interface BookService {
	
	@GetMapping("/book/list")
	public String getBookList();
}

@FeignClient注解中的fallbackFactory属性是指定的Feign客户端界面定义回退工厂。

4.创建调用提供者服务的Controller:
代码语言:javascript
复制
package feign.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import feign.inter.BookService;

@RequestMapping("/feign")
@RestController
public class FeignController {
	@Autowired
	private BookService bookService;
	
	@GetMapping("/getBookList")
	public String getBookList(){
		return bookService.getBookList();
	}
}
5.创建application.yml:
代码语言:javascript
复制
server:
  port: 8084

spring:
  application:
    name: sc-consumer-hystrix-feign

eureka:
  client:
    registerWithEureka: false
    serviceUrl:
      defaultZone: http://localhost:8080/eureka/   

feign:
  hystrix:
    enabled: true  #开启hystrix支持     
6.创建回退工厂类:
代码语言:javascript
复制
package feign.fallback;
import org.springframework.stereotype.Component;

import feign.hystrix.FallbackFactory;
import feign.inter.BookService;

@Component
public class BookFallBack implements FallbackFactory<BookService>{
	@Override
	public BookService create(Throwable cause) {
		return new BookService() {
			@Override
			public String getBookList() {
				return "[\"Java入门到放弃\"]";
			}
		};
	}
}

create方法返回一个回退实例,回退实例为Feign声明式接口BookService的实现类,提供了与BookService相对应的回退方法,BookService接口调用失败时将会调用该实现类中的回退方法。

7.测试:

依次启动注册中心sc-eureka、提供者sc-provider、消费者sc-consumer-hystrix-feign,并访问http://localhost:8084/feign/getBookList,结果显示如下:

这是提供者正常返回的值,接下来将提供者sc-provider关闭,再次访问http://localhost:8084/feign/getBookList,结果显示如下:

8.查看回退原因

修改回退工厂类BookFallBack:

代码语言:javascript
复制
@Component
public class BookFallBack implements FallbackFactory<BookService>{
	@Override
	public BookService create(Throwable cause) {
		return new BookService() {
			@Override
			public String getBookList() {
				//将回退原因输出到控制台
				cause.printStackTrace(System.out);
				return "[\"Java入门到放弃\"]";
			}
		};
	}
}

依次启动注册中心sc-eureka、消费者sc-consumer-hystrix-feign,并访问http://localhost:8084/feign/getBookList,控制台输出:

代码语言:javascript
复制
com.netflix.hystrix.exception.HystrixTimeoutException
	at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.run(AbstractCommand.java:1142)
	at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41)
	at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:37)
	at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57)
	at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.tick(AbstractCommand.java:1159)
        ......
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-09-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 项目介绍
  • 在Ribbon上使用Hystrix
    • 1.在父模块下创建子模块项目sc-consumer-hystrix-ribbon,pom.xml:
      • 2.创建启动类consumer.ConsumerApplication:
        • 3.创建调用提供者服务的Controller:consumer.controller.ConsumerController
          • 4.创建application.yml:
            • 5.测试
            • 在Feign上使用Hystrix
              • 1.在父模块下创建子模块项目sc-consumer-hystrix-feign,pom.xml:
                • 2.创建启动类feign.FeignApplication:
                  • 3.创建Feign声明式接口:feign.inter.BookService
                    • 4.创建调用提供者服务的Controller:
                      • 5.创建application.yml:
                        • 6.创建回退工厂类:
                          • 7.测试:
                            • 8.查看回退原因
                            相关产品与服务
                            微服务引擎 TSE
                            微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档