本文由黑壳博客原创
本文来源 SpringCloud Hystrix 定义服务降级
壳叔搞笑时间
正文
前言
在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会出现因等待出现故障的依赖方响应而形成任务积压,线程资源无法释放,最终导致自身服务的瘫痪,进一步甚至出现故障的蔓延最终导致整个系统的瘫痪。如果这样的架构存在如此严重的隐患,那么相较传统架构就更加的不稳定。为了解决这样的问题,因此产生了断路器等一系列的服务保护机制。
针对上述问题,在 Spring Cloud Hystrix 中实现了线程隔离、断路器等一系列的服务保护功能。它也是基于 Netflix 的开源框架 Hystrix 实现的,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix 具备了服务降级、服务熔断、线程隔离、请求缓存、请求合并以及服务监控等强大功能。
接下来,我们就从一个简单示例让你了解服务降级
对外提供了一个服务中心地址 http://api.blackdir.com:8000/eureka/ 可用于日常学习使用,请勿用于生产服务
参考项目 https://coding.net/u/ykz200/p/pace/git
懒人命令行专用 git clone https://git.coding.net/ykz200/pace.git
运行项目 运行项目主类 Application
eureka-server 服务注册中心 eureka-client 服务提供者
创建 maven 子项目模块 命名为~eureka-consumer-ribbon-hystrix [这个随意就好,反正我是挺随意的,当时没想着展示]
- 传统第一步 pom 依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-cloud.version>Brixton.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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>
<!-- spring-cloud-starter-hystrix 依赖项 -->
<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>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- 第二步 创建或添加 application.properties 内容
#命名
spring.application.name=eureka-consumer-ribbon-hystrix
#运行端口
server.port=9000
#服务中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
*** 第三步 在应用主类中使用 @EnableCircuitBreaker 或 @EnableHystrix 注解开启 Hystrix 的使用
/**
* pom.xml的dependencies节点中引入spring-cloud-starter-hystrix依赖
* 在应用主类中使用@EnableCircuitBreaker或@EnableHystrix注解开启Hystrix的使用
*/
@EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
/**
* 创建RestTemplate 的springbean实例
* 通过@LoadBalanced 注解开启客户端负载均衡
* @return
*/
@Bean
@LoadBalanced RestTemplate restTemplate() {
return new RestTemplate();
}
//这个就不解释了,这个要是不理解,那我只能说请你回炉重学吧
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 第四步 使用 @HystrixCommand 注解来指定服务降级方法
创建类 ConsumerController
在类里创建内部类 ConsumerService
接下来看代码~~~
@RestController
public class ConsumerController {
@Autowired
ConsumerService consumerService;
@GetMapping("/consumer")
public String consumer() {
return consumerService.consumer();
}
@Service
class ConsumerService {
@Autowired
RestTemplate restTemplate;
/**
* 具体执行逻辑的函数上增加@HystrixCommand 注解来指定服务降级方法,
* fallbackMethod定义回退方法的名称
* @return
*/
@HystrixCommand(fallbackMethod = "fallback")
public String consumer() {
// 如果报异常 则会调用fallbackMethod 指定方法 “fallback”
//int error = Integer.parseInt("error");
String result = restTemplate.getForEntity("http://EUREKA-CLIENT/hello", String.class).getBody();
System.out.println(result);
return result;
}
/**
* 此处可能是另一个网络请求来获取,所以也可能失败 \* @return
*/
@HystrixCommand(fallbackMethod = "fallbackSEC")
String fallback() {
return "Execute raw fallback";
}
String fallbackSEC() {
return "Execute raw fallback";
}
}
}
第四步则是用注解的方式来实现服务降级,如果将 consumer 的//int error = Integer.parseInt("error");如果将注释取消掉,则会立马进入 fallback
方法来实现服务降级逻辑。
对于 fallback 方法的访问修饰符没有特定要求,这个可以放心。
但是需要一点 fallback 方法 需要与 @HystrixCommand 在同一个类中。
这是我认为 SpringCloud 服务容错保护学习过程中,看代码更容易理解的一个阶段~。
关于我们
程序员是个辛苦的职业
请善待你们身边的每一位程序员~
欢迎在评论写下你的程序员趣事,程序员不是一个死板的职业~~
欢迎扫描二维码加入我们的小组织 ,大家都叫我壳叔,很期待你的到来。
黑壳网交流群 Q 群:200408242
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于