天行健,君子以自强不息;地势坤,君子以厚德载物。
每个人都有惰性,但不断学习是好好生活的根本,共勉!
文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。
spring cloud 相关组件搭建(建议顺序):
注:本篇基于前三篇编写
Hystrix是一种实现服务熔断的机制,当某个服务不可用时可以阻断故障传播。
说到hystrix需要先了解以下几个概念。
在微服务中各个服务互相调用时,某一个服务出现故障导致多个服务出现故障继而导致整个系统故障。
解决服务雪崩的方式有两种,服务熔断和服务降级。
服务出现不可用或响应超时时,为防止服务雪崩,暂停对该服务的调用,直接返回一个结果,释放资源。
检测到服务恢复后再继续对服务调用。
防止核心业务负荷过载或响应过慢,对非核心服务进行降级,暂时关闭或延迟使用非核心服务,保证核心服务正常有效运行。
Hystrix监控服务之间的调用情况,连续调用多次失败时进行熔断保护,此时会开启熔断机制,返回一个开发者设置的退路信息。
Hystrix会定期检查故障服务,若故障恢复则可继续使用服务。
JDK版本:1.8
maven版本:3.9.0
开发工具:IDEA社区版ideaIC-2018.3
项目框架:spring boot 版本为 2.7.3 springboot搭建传送门spring cloud 版本为 2021.0.5
使用前请参考前三篇整合eureka、服务提供者service1、服务调用者service2
这里以service1服务为例使用熔断器,熔断器的使用分两步,引入熔断器依赖,配置文件开启参数(这一步这里不需要配置,在远程调用时的服务调用者service2中配置),请求控制类的方法上使用注解配置熔断参数,服务启动类添加注解开启。
service1服务的pom.xml中引入依赖
<?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">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>com.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring_cloud_service1</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--hystrix熔断器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
</dependencies>
</project>
在请求方法上添加注解,配置参数,这里将方法睡眠3秒,熔断配置的参数为2秒
然后编写fallbackMethod对应的返回函数,返回自己设置的结果
package com.service1.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.service1.service.Impl.Service1ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.TimeUnit;
/**
* @ClassDescription: crud请求控制类
* @Author:李白
* @Date:2023/5/31 17:07
*/
@RestController
@RequestMapping("/crud")
public class Service1Controller {
@Autowired
Service1ServiceImpl service1ServiceImpl;
@PostMapping
@HystrixCommand(fallbackMethod = "TimeOutCondition", commandProperties = {
//超过2秒,服务熔断,返回指定方法中的值
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
})
public String addInfo() {
try {
//睡眠3秒
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return service1ServiceImpl.addInfo();
}
@DeleteMapping
public String remove(){
return service1ServiceImpl.removeInfo();
}
@PutMapping
public String change(){
return service1ServiceImpl.changeInfo();
}
@GetMapping
public String search(){
return service1ServiceImpl.searchInfo();
}
/**
* 熔断调用函数
* @return
*/
public String TimeOutCondition(){
return "远程调用失败-超时2秒";
}
}
在service1服务的启动类上添加@EnableHystrix注解开启熔断功能
package com.service1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
/**
* @ClassDescription: 服务1启动项
* @Author:李白
* @Date:2023/5/31 14:46
*/
@EnableEurekaClient
@SpringBootApplication
@EnableHystrix
public class Service1Application {
public static void main(String[] args) {
SpringApplication.run(Service1Application.class, args);
}
}
启动service1服务,postman请求接口调用
由于请求响应时间3秒超出了熔断的时间2秒,在请求执行2秒时即返回熔断结果
这里以service2服务为例使用熔断器,分两步,引入熔断器依赖,配置文件开启参数,请求控制类的方法上使用注解配置熔断参数,服务启动类添加注解开启。
service2服务的pom.xml中引入依赖
<?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">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>com.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring_cloud_service2</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
<version>2.2.10.RELEASE</version>
</dependency>
</dependencies>
</project>
service2服务中的配置文件中添加hystrix参数,开启hystrix
(不在yml中配置hystrix参数功能也可正常使用,这一步可以忽略
)
这里是和服务提供者service1不同的地方,service1服务提供者不需要配置
service1是服务的提供者 service2是服务的调用者
application.yml
server:
port: 8003
spring:
application:
name: Service2-app
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka/
#Feign,这里应该是默认开启,因为这里不写,功能也正常用
#feign:
# hystrix:
# #开启熔断器
# enabled: true
在想要熔断的请求方法上添加@HystrixCommand注解,配置参数
fallbackMethod
参数值为熔断返回结果的方法名字符串commandProperties
参数为花括号抱起来的注解@HystrixProperty
@HystrixProperty
注解的参数以键值对存在键为name
值为value
"TimeOutCondition"
是熔断结果返回的函数,自己创建设置返回值"execution.isolation.thread.timeoutInMilliseconds"
是指请求超时多少秒进行熔断"2000"
是指2秒Service2Controller.java
package com.service2.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.service2.service.Service2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @ClassDescription: 请求控制类(service2)
* @Author:李白
* @Date:2023/5/31 18:42
*/
@RestController
@RequestMapping("/caller")
public class Service2Controller {
@Autowired
Service2Service service2Service;
@PostMapping
@HystrixCommand(fallbackMethod = "TimeOutCondition", commandProperties = {
//超过1秒,服务熔断,返回指定方法中的值
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000")
})
public String addInfo(){
return service2Service.addInfo();
}
@DeleteMapping
public String remove(){
return service2Service.removeInfo();
}
@PutMapping
public String change(){
return service2Service.changeInfo();
}
@GetMapping
public String search(){
return service2Service.searchInfo();
}
/**
* 熔断调用函数
* @return
*/
public String TimeOutCondition(){
return "远程调用失败-超时1秒";
}
}
在service2的启动类上添加注解开启熔断器
package com.service2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @ClassDescription: 服务2启动项
* 注解@EnableFeignClients开启feign功能,也可以添加参数,basePackages的值可指定使用该功能的接口所在包
* 注解@EnableHystrix开启熔断器 也可用@EnableCircuitBreaker开启熔断器,不过后者现在已被弃用
* @Author:李白
* @Date:2023/5/31 14:51
*/
@EnableEurekaClient
@SpringBootApplication
//@EnableFeignClients(basePackages = "com.service2.service")
@EnableFeignClients
@EnableHystrix
public class Service2Application {
public static void main(String[] args) {
SpringApplication.run(Service2Application.class, args);
}
}
启动eureka服务,service1服务,service2服务,postman请求接口调用
由于service1中的请求响应时间3秒,service1的熔断时间为2秒,service2设置的熔断时间为1秒,所以在超出1秒时,返回的是service2设置的熔断结果
这里可以将service2的熔断时间设置为2.5秒,可以发现结果返回的时service1设置的熔断结果,因为2.5秒大于2秒,service2的熔断机制未触发,在请求2秒时就直接返回了service1熔断返回的结果
以上就是熔断器hystrix的使用