从零开始学spring cloud(十) -------- hystrix简单代码示例
一、官网文档阅读

二、示例
添加hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
修改movie服务的controller
package com.zwjk.cloud.controller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.zwjk.cloud.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; /**
* @author : Jixiaohu
* @Date : 2019-04-11.
* @Time : 9:38.
* @Description :
*/
@RestController
public class MovieController { @Autowired
private RestTemplate restTemplate; @Value("${user.userServicePath}")
private String userServicePath; @GetMapping("/movie/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject(this.userServicePath + id, User.class);
} public User findByIdFallback(Long id) {
User user = new User();
user.setId(0L);
user.setName("失败");
return user;
}
}
这边需要注意的是,fallbackMethod方法的返回值和入参,必须和原方法一致,下面进行测试:

可以看到,这里返回了正常的结果,下面停掉user服务

可以看到,这里返回的结果,就是fallbackMethod里面返回的内容,hystrix就起了作用。
下面,继续看一下
Feign Hystrix Support
参考官网使用示例:
@FeignClient(name = "hello", fallback = HystrixClientFallback.class)
protected interface HystrixClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
Hello iFailSometimes();
} static class HystrixClientFallback implements HystrixClient {
@Override
public Hello iFailSometimes() {
return new Hello("fallback");
}
}
在配置文件中,增加开启feign使用断路器
feign:
hystrix:
enabled: true
按照示例,我们在movie服务中,新增UserFeignClientFallback类
package com.zwjk.cloud.fegin; import com.zwjk.cloud.entity.User;
import org.springframework.stereotype.Component; /**
* @author : Jixiaohu
* @Date : 2019-04-17.
* @Time : 18:20.
* @Description :
*/
@Component
public class UserFeignClientFallback implements UserFeignClient {
@Override
public User findById(Long id) {
User user = new User();
user.setId(0L);
return user;
}
}
在fegin上增加相应的注解:
package com.zwjk.cloud.fegin; import com.zwjk.cloud.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; /**
* @author : Jixiaohu
* @Date : 2019-04-12.
* @Time : 16:50.
* @Description :
*/
@FeignClient(name = "microservice-provider-user", fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
//@PathVariable得设置value
@GetMapping("/simple/{id}")
User findById(@PathVariable("id") Long id); //@PathVariable得设置value
}
启动项目,进行测试,

同样的,停掉user服务,再次访问这个地址:

就可以实现熔断服务
当一个项目中,有个feign时,如何禁用一些feign的hystrix?
查看一下官网文档

通过配置加上feignBuilder,就可以禁用指定fegin的hystrix
查看一下代码实现:
package com.zwjk.cloud.controller; import com.zwjk.cloud.entity.User;
import com.zwjk.cloud.fegin.UserFeignClient2;
import com.zwjk.cloud.fegin.UserFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; /**
* @author : Jixiaohu
* @Date : 2019-04-11.
* @Time : 9:38.
* @Description :
*/
@RestController
public class MovieController { @Autowired
private UserFeignClient userFeignClient; @Autowired
private UserFeignClient2 userFeignClient2; @GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {
return this.userFeignClient.findById(id);
} @GetMapping("/{serviceName}")
public String findServiceInfoFromEurekaByServiceName(@PathVariable String serviceName) {
return this.userFeignClient2.findServiceInfoFromEurekaByServiceName(serviceName);
} }
两个fegin:
package com.zwjk.cloud.fegin; import com.zwjk.cloud.entity.User;
import com.zwjk.config.UserConfiguration;
import feign.Param;
import feign.RequestLine;
import org.springframework.cloud.openfeign.FeignClient; /**
* @author : Jixiaohu
* @Date : 2019-04-12.
* @Time : 16:50.
* @Description :
*/
@FeignClient(name = "microservice-provider-user", configuration = UserConfiguration.class, fallback =
UserFeignClientFallback.class)
public interface UserFeignClient {
//@PathVariable得设置value
@RequestLine("GET /simple/{id}")
User findById(@Param("id") Long id); //@PathVariable得设置value }
package com.zwjk.cloud.fegin; import com.zwjk.config.UserConfiguration2;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; /**
* @author : Jixiaohu
* @Date : 2019-04-13.
* @Time : 11:23.
* @Description :
*/
@FeignClient(name = "xxxx", url = "http://192.168.1.114:8761/", configuration = UserConfiguration2.class)
public interface UserFeignClient2 {
@RequestMapping(value = "/eureka/apps/{serviceName}")
public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName);
}
两个fallback
package com.zwjk.cloud.fegin; import org.springframework.stereotype.Component; /**
* @author : Jixiaohu
* @Date : 2019-04-17.
* @Time : 18:20.
* @Description :
*/
@Component
public class UserFeignClient2Fallback implements UserFeignClient2 { @Override
public String findServiceInfoFromEurekaByServiceName(String serviceName) {
return "hahahha";
}
}
package com.zwjk.cloud.fegin; import com.zwjk.cloud.entity.User;
import org.springframework.stereotype.Component; /**
* @author : Jixiaohu
* @Date : 2019-04-17.
* @Time : 18:20.
* @Description :
*/
@Component
public class UserFeignClientFallback implements UserFeignClient {
@Override
public User findById(Long id) {
User user = new User();
user.setId(0L);
return user;
}
}
看一下两个配置文件
package com.zwjk.config; import feign.Contract;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* @author : Jixiaohu
* @Date : 2019-04-13.
* @Time : 10:20.
* @Description :
*/
@Configuration
public class UserConfiguration { @Bean
public Contract feignContract() {
return new feign.Contract.Default();
} @Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
package com.zwjk.config; import feign.Feign;
import feign.auth.BasicAuthRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope; /**
* @author : Jixiaohu
* @Date : 2019-04-13.
* @Time : 11:25.
* @Description :
*/
@Configuration
public class UserConfiguration2 {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("user", "password123");
} @Configuration
public class FooConfiguration {
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}
}
}
启动服务,进行测试


下面,我们停掉eureka,和user服务,在一次查看返回结果
启用hystrix的返回结果如下:

没有启用hystrix的返回结果,提示500错误

从中,可以看出,hytrix的熔断,可以有很细的粒度。
如果想要查看fallback回退的原因,可以使用可以使用@FeignClient中的fallbackFactory属性。
看一下如何实现?
参考一下官网文档:

先写一个hystrixFactory:
package com.zwjk.cloud.fegin; import com.zwjk.cloud.entity.User;
import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; /**
* @author : Jixiaohu
* @Date : 2019-04-17.
* @Time : 19:37.
* @Description :
*/
@Component
public class UserFeginClientFactory implements FallbackFactory<UserFeignClient> { private static final Logger Log = LoggerFactory.getLogger(UserFeginClientFactory.class); @Override
public UserFeignClient create(Throwable cause) {
UserFeginClientFactory.Log.info("fallback:reason was : {}", cause.getMessage());
return id -> {
User user = new User();
user.setId(-1L);
user.setName("haha");
return user;
};
}
}
修改一下原feignClient
package com.zwjk.cloud.fegin; import com.zwjk.cloud.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; /**
* @author : Jixiaohu
* @Date : 2019-04-12.
* @Time : 16:50.
* @Description :
*/
@FeignClient(name = "microservice-provider-user", fallbackFactory =
UserFeginClientFactory.class)
public interface UserFeignClient {
//@PathVariable得设置value
@GetMapping("/simple/{id}")
User findById(@PathVariable("id") Long id); //@PathVariable得设置value
}
启动user服务,movie服务,先正常访问:
然后关闭user服务,会发现控制台开始打印日志:

这是为什么呢?因为此时,断路器并没有打开,实际的原因是TimeoutException

当断路器打开时,就会答应异常的信息。
从零开始学spring cloud(十) -------- hystrix简单代码示例的更多相关文章
- 从零开始学spring cloud(十一) -------- hystrix监控
一.官方文档阅读 服务启动后,可以通过/health和hystrix.stream查看效果,实际上,访问上述两个地址,会出现404,这是因为spring boot版本的问题, 我在这里使用的sprin ...
- 从零开始学spring cloud(七) -------- Spring Cloud OpenFegin
一.OpenFegin 介绍 Feign是一个声明性的Web服务客户端. 它使编写Web服务客户端变得更容易. 要使用Feign,请创建一个界面并对其进行注释. 它具有可插入的注释支持,包括Feign ...
- 从零开始学spring cloud(六) -------- Ribbon
一.Ribbon介绍 Ribbon就是客户端侧负责均衡实现的一种方式,那么Ribbon是什么呢? Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端侧负载均衡算法.Ribb ...
- 从零开始学spring cloud(四) -------- 基础项目搭建
1.创建一个spring cloud项目 1.1.使用工具创建--idea 点击creat new project,选择spring initializr 点击next,选择下一步 填入自己的Grou ...
- 从零开始学spring cloud(五) -------- 将服务注册到Eureka上
一.开发前准备工作: 官方文档地址:https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.1.0.RELEASE/mul ...
- 从零开始学spring cloud(一) -------- spring cloud 简介
1.微服务简介 1.1.单体架构 一个归档包(例如war格式)包含了应用所有功能的应用程序,我们通常称之为单体应用.架构单体应用的方法论,我们称之为单体应用架构. 缺点:1. 复杂性高以笔者经手的一个 ...
- 从零开始学spring cloud(九) -------- 超时机制,断路器模式介绍
目前存在的问题: 现在我们假设一下,服务提供者响应非常缓慢,那么消费者对提供者的请求就会被强制等待,直到服务返回.在高负载场景下,如果不做任何处理,这种问题很可能造成所有处理用户请求的线程都被耗竭,而 ...
- 从零开始学spring cloud(八) -------- Eureka 高可用机制
一.Eureka高可用机制介绍 Eureka服务器没有后端存储,但注册表中的服务实例都必须发送心跳以使其注册保持最新(因此可以在内存中完成). 客户端还有一个Eureka注册的内存缓存(因此,他们不必 ...
- 从零开始学spring cloud(三) -------- Eureka简介
1.服务发现组件:Eureka Eureka的开源文档介绍地址:https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance What is Eu ...
随机推荐
- HP880G3 安装RHEL6.5
###关于读不到网卡驱动的问题 HP 880G3 在安装系统的时候会提示acpi错误 需要按F9 选择 lency开头走U盘安装系统 进入安装界面按tab 输入 acpi=off 这样就可以安装了 ...
- 关于anaconda中jupyter notebook错误
anaconda这个软件是真的坑,其中的jupyter notebook每次都会出错,不知道,为什么,可惜我的pycharm装tensorflow一直有错误,不然,真想卸了这个软件. 会莫名其妙闪退, ...
- 微信小程序+没有找到node_modules目录
第一步:设置-->项目设置-->使用npm模块 第二步:右键目录下miniprogram-->终端打开-->输入npm init-->在packagename下输入:sm ...
- Docker容器开机自动启动
部署项目服务器时,为了应对停电等情况影响正常web项目的访问,会把Docker容器设置为开机自动启动. 在使用docker run启动容器时,使用--restart参数来设置: # docker r ...
- Centos 7环境下安装配置MySQL 5.7
安装步骤为: 1.由于Centos 7版中已经移除MySQL rpm,因此需要到其官方网站上下载rpm,下载完成后,使用以下命令,来安装MySQL的rpm配置. rpm -ivh *****[注释:* ...
- Linux内核中的printf实现
1 #ifndef __PRINT_H_ 2 #define __PRINT_H_ 3 4 void print(char* fmt, ...); 5 void printch(char ch); 6 ...
- Python简单语音识别并响应
起因是一个工作中喜欢说口头禅的同事,昨天老说"你看看你看看 操不操心".说了几次之后我就在他说完"你看看"后面续上,"操不操心".往复多次后 ...
- @Override is not allowed when implementing interface method
使用idea导入maven项目时 会出现如下报错 @Override从jdk1.5开始出现的,是用来标注方法重写:通常方法重写发生在继承父类,重写父类方法,或者实现接口,实现接口方法: @Overri ...
- FPGA笔试必会知识点2—FPGA器件
FPGA 综合工具并不一定保证能够充分利用芯片结构特点以达到最优目的而且工具本身也不一定非常智能,因为设计本身是复杂多样的且一直在变化,问题总会越来越多,因此在这种情况下,我们必须了解我们的器件结构, ...
- c++堆和栈(转)
想要学好C++的C++堆栈,那么就要了解什么是C++堆栈,所为C++堆栈就是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除,分为堆和栈两部分. 在C++中,内存分 ...