Fallback多级降级,Request Cache减压。你知道是怎么实现的吗?
Hystrix介绍
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免地会调用失败,比如超时、异常等,Hystrix能保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
github地址: https://github.com/Netflix/Hystrix
服务降级
所谓降级,就是当某个服务出现异常之后,服务器将不再被调用,此时服务端可以自己准备一个本地的fallback回调,返回一个缺省值。 这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。
可能出现服务降级的情况:
- 程序运行异常
- 服务超时
- 服务熔断触发服务降级
- 线程池/信号量打满也会导致服务降级
版本说明
Java : 1.8 Spring Boot : 2.1.5.RELEASE Spring Cloud: Greenwich.SR1
项目说明
eureka-server:eureka服务中心 feign-client :feign生产者 feign-client-intf:feign接口提供者 hystrix-fallback:hystrix降级demo
eureka-server 前面文章已经提供不再粘贴出来了
feign-client-intf:feign接口提供者
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
1234567891011
server接口提供
@FeignClient("feign-client")
public interface IService {
@GetMapping("/sayHi")
public String sayHi();
@PostMapping("/sayHi")
public Friend sayHiPost(@RequestBody Friend friend);
@GetMapping("/retry")
public String retry(@RequestParam(name = "timeout") int timeout);
@GetMapping("/error")
public String error();
}
12345678910111213141516
Friend实体类
@Data
public class Friend {
private String name;
private String port;
}
12345678
feign-client :feign生产者
pom.xml
dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.imooc</groupId>
<artifactId>feign-client-intf</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
1234567891011121314151617181920212223
application.properties
spring.application.name=feign-client
server.port=40006
eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/
12345
Controller
@RestController
public class Controller implements IService {
Logger log = LoggerFactory.getLogger(Controller.class);
@Value("${server.port}")
private String port;
@GetMapping("/sayHi2")
public String sayHi2() {
return "This is " + port;
}
@Override
public String sayHi() {
return "This is " + port;
}
@Override
public Friend sayHiPost(@RequestBody Friend friend) {
log.info("You are " + friend.getName());
friend.setPort(port);
return friend;
}
@Override
public String retry(@RequestParam(name = "timeout") int timeout) {
System.out.println("timeout"+timeout);
while (--timeout >= 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
log.info("retry " + port);
return port;
}
@Override
public String error() {
throw new RuntimeException("black sheep");
}
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344
FeignClientApplication启动类
@EnableDiscoveryClient
@SpringBootApplication
public class FeignClientApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(FeignClientApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
1234567891011
hystrix-fallback:hystrix降级demo
pom.xml
dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.imooc</groupId>
<artifactId>feign-client-intf</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
12345678910111213141516171819202122232425262728
application.properties
spring.application.name=hystrix-consumer
server.port=50001
spring.main.allow-bean-definition-overriding=true
eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/
# 开启Feign下面的Hystrix功能
feign.hystrix.enabled=true
# 是否开启服务降级
hystrix.command.default.fallback.enabled=true
# 全局超时
hystrix.command.default.execution.timeout.enabled=true
# 超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
# 超时以后终止线程
hystrix.command.default.execution.isolation.thread.interruptOnTimeout=true
# 取消的时候终止线程
hystrix.command.default.execution.isolation.thread.interruptOnFutureCancel=true
# hystrix.command.MyService#retry(int).execution.isolation.thread.timeoutInMilliseconds=3000
# 每台机器最大重试次数
feign-client.ribbon.MaxAutoRetries=0
# 可以再重试几台机器
feign-client.ribbon.MaxAutoRetriesNextServer=0
# 连接超时
feign-client.ribbon.ConnectTimeout=1000
# 业务处理超时
feign-client.ribbon.ReadTimeout=8000
# 在所有HTTP Method进行重试
feign-client.ribbon.OkToRetryOnAllOperations=false
1234567891011121314151617181920212223242526272829303132
Controller
@RestController
public class Controller {
@Autowired
private MyService myService;
@Autowired
private RequestCacheService requestCacheService;
@GetMapping("/fallback")
public String fallback() {
return myService.error();
}
@GetMapping("/timeout")
public String timeout(Integer timeout) {
System.out.println(timeout);
return myService.retry(timeout);
}
@GetMapping("/timeout2")
@HystrixCommand(
fallbackMethod = "timeoutFallback",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value="3000")
}
)
public String timeout2(Integer timeout) {
return myService.retry(timeout);
}
public String timeoutFallback(Integer timeout) {
return "success";
}
@GetMapping("/cache")
public Friend cache(String name) {
@Cleanup HystrixRequestContext context =
HystrixRequestContext.initializeContext();
Friend friend = requestCacheService.requestCache(name);
friend = requestCacheService.requestCache(name);
return friend;
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
MyService
@FeignClient(name = "feign-client", fallback = Fallback.class)
public interface MyService extends IService {
}
1234
Fallback 降级处理类
@Slf4j
@Component
public class Fallback implements MyService {
@Override
//@HystrixCommand(fallbackMethod = "fallback2")
public String error() {
log.info("Fallback: I'm not a black sheep any more");
throw new RuntimeException("first fallback");
}
@HystrixCommand(fallbackMethod = "fallback3")
public String fallback2() {
log.info("fallback again");
throw new RuntimeException("fallback again");
}
public String fallback3() {
log.info("fallback again and again");
return "success";
}
@Override
public String sayHi() {
return null;
}
@Override
public Friend sayHiPost(@RequestBody Friend friend) {
return null;
}
@Override
public String retry(@RequestParam(name = "timeout") int timeout) {
return "You are late !";
}
}
123456789101112131415161718192021222324252627282930313233343536373839
RequestCacheService Request Cache减压
@Slf4j
@Service
public class RequestCacheService {
@Autowired
private MyService service;
@CacheResult
@HystrixCommand(commandKey = "cacheKey")
public Friend requestCache(@CacheKey String name) {
log.info("request cache " + name);
Friend friend = new Friend();
friend.setName(name);
friend = service.sayHiPost(friend);
log.info("after requesting cache " + name);
return friend;
}
}
1234567891011121314151617181920
HystrixFallbackApplication启动类
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
public class HystrixFallbackApplication {
public static void main(String[] args) throws NoSuchMethodException {
new SpringApplicationBuilder(HystrixFallbackApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
// System.out.println(Feign.configKey(MyService.class,
// MyService.class.getMethod("retry", int.class)));
}
}
12345678910111213141516
测试
依次启动: eureka-server:eureka服务中心 feign-client :feign生产者 hystrix-fallback:hystrix降级demo
Fallback多级降级测试
测试步骤: 1.通过postman来调用hystrix-fallback fallback接口
2.然后通过feign来调用feign-client的error接口来获取一个异常看看能不能降级。
3.多级降级处理
postman 放回的结果,然后分析一下结果。
在feign-client当中 抛出了一个RuntimeException的错误。然后会被hystrix进行降级处理。
我们再去hystrix-fallback的控制台看看有没有被降级。
这三条输出对应的就是之前多级处理的打印的结果说明 多级降级是成功的。
Timeout降级测试
1.设置全局的超时时间 超过时间就会Timeout降级 这里我是设置的3s
2通过postman来调用hystrix-fallback timeout接口
3.然后通过feign来调用feign-client的retry接口让线程sleep相应的时间
4.如果没有超时就会retrun 出feign-clien端口号 超时了的话就会进入timeout降级处理类
5.先测试2s 没有超时的结果
6.先然后测试3s 超时的结果
Request Cache减压测试
1.通过postman来调用hystrix-fallback cache接口,然后接口里面连续调用了 两次 requestCacheService.requestCache(name); 如果打印两遍相同的log说明没有被缓存到本地,解压失败。 如果只打印一遍og说明有被缓存到本地,解压成功。
requestCacheService.requestCache
调用接口
只打印了一遍Log说明解压成功
以上有问题请指出来!交流学习
相关文章
- 中文文案排版指北
- 什么是企业经营管理?【企业经营管理方案】
- Typecho 中英文之间自动加上空格
- PSCI接口规范
- LSM vs SECCOMP
- LSM一瞥
- Ubuntu 20.04.1 配置 LNMP 本地环境备忘
- 腾讯数据中心参展2022年中国国际节能低碳产业博览会
- 直播报名|资深云原生架构师分享服务网格在腾讯 IT 业务的落地实践
- @文旅人,扩大内需怎么干?中央发文定任务——
- 数字文旅周报89期 | 腾讯发布2023年十大数字科技前沿应用趋势
- 编程教会我的6个生活信条
- 代码智能补全+跨语言翻译,又一个效率工具来了
- Ubuntu ZFS 原生全盘加密
- 为什么编程都建议不要用拼音命名?
- Ubuntu ZFS 加密 Home 目录
- Harbor 2.6 支持 WebAssembly 镜像
- 关于 Ubuntu
- 工业焊接机器人需要用到哪些技术
- KMS Windows 激活服务器