当前位置:网站首页>OpenFeign 简单使用
OpenFeign 简单使用
2022-07-02 06:29:00 【不懂一休】
文章目录
官方文档参考: https://docs.spring.io/spring-cloud-openfeign/docs/2.2.9.RELEASE/reference/html/,在 url 中选择自己对应的版本
github 文档参考:https://github.com/OpenFeign/feign
一、源码简单分析
1、导入依赖
导入依赖 OpenFeign 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、自动导入类
spring-cloud-starter-openfeign 引入了 spring-cloud-openfeign-core 依赖,查看 spring-cloud-openfeign-core/META-INF/spring.factories 自动加载 FeignRibbonClientAutoConfiguration 类
查看 FeignRibbonClientAutoConfiguration 类默认加载 DefaultFeignLoadBalancedConfiguration
3、OkHttpFeignLoadBalancedConfiguration 类
OkHttpFeignLoadBalancedConfiguration 类中可以看到 @ConditionalOnClass(OkHttpClient.class) 注解,如果没有 OkHttpClient 类则不加载 OkHttpFeignLoadBalancedConfiguration 类
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty("feign.okhttp.enabled")
@Import(OkHttpFeignConfiguration.class)
class OkHttpFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {
OkHttpClient delegate = new OkHttpClient(okHttpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}
4、DefaultFeignLoadBalancedConfiguration 类
从源码可以看到没有注入 Client 相关的 bean ,则注入该 client
@Configuration
class DefaultFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {
return new LoadBalancerFeignClient(new Client.Default(null, null),
cachingFactory, clientFactory);
}
}
查看 Client.Default 源码
public static class Default implements Client {
public Response execute(Request request, Options options) throws IOException {
HttpURLConnection connection = this.convertAndSend(request, options);
return this.convertResponse(connection, request);
}
HttpURLConnection convertAndSend(Request request, Options options) throws IOException{
URL url = new URL(request.url());
HttpURLConnection connection = this.getConnection(url);
}
public HttpURLConnection getConnection(URL url) throws IOException {
return (HttpURLConnection)url.openConnection();
}
}
从 Client.Default 源码可以看到每次请求都建立一个新的 HttpURLConnection 连接
其他 HttpClientFeignLoadBalancedConfiguration.class, OkHttpFeignLoadBalancedConfiguration.class, HttpClient5FeignLoadBalancedConfiguration.class
类似
5、小结
综上,默认情况下,spring cloud 没有引入 ApacheHttpClient 类(feign-httpclient jar包)和 okhhtp 类(okhttp jar包)和 ApacheHttp5Client ( ApacheHttp5Client jar 包) 类,所以默认使用 HttpURLConnection。
二 、OpenFeign 配置 Http 连接池
默认情况下,服务间调用使用 HttpURLConnection,效率比较低,可以通过连接池提高效率。
1、配置 Apache httpclient 连接池
pom.xml 中引入 feign-httpclient 依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
bootstrap.yml 中添加配置
feign:
httpclient:
enabled: true
hc5:
enabled: false
okhttp:
enabled: false
简单配置如上即可,其他相关配置可使用默认值,详细配置可参考 FeignHttpClientProperties、FeignAutoConfiguration 类
HttpClient 默认配置如下,详细配置可参考 https://docs.spring.io/spring-cloud-openfeign/docs/2.2.9.RELEASE/reference/html/appendix.html
feign:
httpclient:
enabled: true
hc5:
enabled: false
disable-ssl-validation: false # 禁用 SSL 验证
max-connections: 200 # 最大连接
max-connections-per-route: 50 # 路由最大连接数
time-to-live: 900 # 连接存活时间
time-to-live-unit: seconds # 连接存活时间单位
follow-redirects: true # 重定向
connection-timeout: 2000 # 连接超时
connection-timer-repeat: 3000 # 连接重复间隔
okhttp:
enabled: false
2、配置 OkHttpClient 连接池
pom.xml 中引入 feign-okhttp 依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
bootstrap.yml 中添加配置,其他详细配置参考上面的 Apache httpclient 连接池配置
feign:
httpclient:
enabled: false
hc5:
enabled: false
okhttp:
enabled: true
三、OpenFeign 简单测试
1、SPRING-CLOUD-SERVICE-OPENFEIGN 服务 bootstrap.yaml 配置
server:
port: 20004
spring:
application:
name: SPRING-CLOUD-SERVICE-OPENFEIGN
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
service: ${
spring.application.name:DEFAULT-SERVICE-NAME}
username: ${
spring.cloud.nacos.username:nacos}
password: ${
spring.cloud.nacos.password:nacos}
namespace: 2022-4-1-prod
cluster-name: DEFAULT
feign:
httpclient:
enabled: true
2、调用测试
①、SPRING-CLOUD-SERVICE-CONFIG-PROVIDER 服务
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Autowired
private Student student;
@GetMapping("/student")
public String getStudent(HttpServletRequest request) {
int port = request.getServerPort();
String servletPath = request.getServletPath();
String serverName = request.getServerName();
String api = serverName + ":" + port + servletPath;
JSONObject jsonObject = new JSONObject();
jsonObject.put("API", api);
jsonObject.put("student", student);
return JSONObject.toJSONString(jsonObject);
}
}
接口 http://192.168.159.1:20002/config/student
②、SPRING-CLOUD-SERVICE-OPENFEIGN 服务
启动类开启注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class SpringCloudStarterOpenfeignExamplesApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudStarterOpenfeignExamplesApplication.class, args);
}
}
新建 ProviderClient 服务接口
@Service
@FeignClient("SPRING-CLOUD-SERVICE-CONFIG-PROVIDER")
public interface ProviderClient {
@GetMapping("/config/student")
String selectService();
}
调用 SPRING-CLOUD-SERVICE-CONFIG-PROVIDER 服务
@RestController
@RequestMapping("/openfeign")
public class OpenFeignController {
@Autowired
private ProviderClient providerClient;
@GetMapping("/select")
public String selectService() {
return providerClient.selectService();
}
}
访问接口:http://127.0.0.1:20004/openfeign/select
3、使用 OpenFeign 接口注解
OpenFeign 默认支持 springmvc 默认注解(@GetMapping、@PostMapping、@Param、@RequestMapping)
如果要使用 OpenFeign 自带的如下接口注解
需要配置 feign 的合约模式,如果不配置就是用如上注解会报错 not annotated with HTTP method type (ex. GET, POST)
,注入如下 bean 即可
@Configuration
public class FeignConfiguration {
//Contract feign的默认合约
@Bean
public Contract feignContract() {
return new Contract.Default();
}
}
SpringMVC 注解和 OpenFeign 不能共存
4、OpenFeign 配置优先级
如果我们同时创建 @Configuration @bean 和 yaml 配置文件配置,配置文件将覆盖 @Configuration值。
你可以将 feign.client.default-to-properties 改成 false,则 @Configuration 覆盖配置文件
5、OpenFeign GET 将 POJO 用作 GET 参数映射
①、服务提供者
控制层接口
@RestController
@RequestMapping("/discovery")
public class DiscoveryController {
@GetMapping(value = "/pojo")
public String selectPojo(HttpServletRequest request) {
Map<String, String[]> parameterMap = request.getParameterMap();
JSONObject jsonObject = new JSONObject();
for (String s : parameterMap.keySet()) {
if (parameterMap.get(s).length == 1) {
jsonObject.put(s, parameterMap.get(s)[0]);
} else {
jsonObject.put(s, parameterMap.get(s));
}
}
return jsonObject.toJSONString();
}
}
接口:http://127.0.0.1:20001/discovery/pojo?birthday=2022-02-22&username=admin&password=123456&address=西安
②、服务消费者
有的时候 GET 请求拼接 url 比较麻烦,则使用 @SpringQueryMap 注解将 POJO 对象用作 GET 参数映射
- OpenFeign @QueryMap 注解支持将 POJO 用作 GET 参数映射。不幸的是,默认的 OpenFeign QueryMap 注解与 Spring 不兼容,因为它缺少value属性。
- Spring Cloud OpenFeign 提供了等效的 @SpringQueryMap 注解,用于将 POJO 或 Map 参数注解为查询参数映射。
Feign 接口
@FeignClient(name = "SPRING-BOOT-SERVICE-DISCOVERY-CONSUMER")
@Service
public interface BootDiscoveryClient {
@GetMapping(value = "/discovery/pojo")
String selectPojo(@SpringQueryMap Map map);
}
控制层接口
@RestController
@RequestMapping("/openfeign")
public class OpenFeignController {
@Autowired
private BootDiscoveryClient bootDiscoveryClient;
@GetMapping(value = "/pojo")
public String selectPojo(@RequestBody Map map) {
return bootDiscoveryClient.selectPojo(map);
}
}
测试接口:http://127.0.0.1:20004/openfeign/pojo
@SpringQueryMap 注解将 pojo 参数拼接在 url 后面http://SERVICE-NAME/discovery/pojo?birthday=2022-02-22&username=admin&password=123456&address=西安
之后根据负载均衡查找服务,将服务名替换成真实的地址去访问
6、OpenFeign GET 请求带 body
关于 get 请求传递 body 详细说明 https://zhuanlan.zhihu.com/p/456921996,简单说 get 请求不建议传递 body ,某些浏览器可能不支持
- 支持 GET 请求 body: curl 、postman 、node.js 内置模块 http 、axios 、 Apache HttpClient 等
- 不支持 GET 请求 body: HttpUrlConnection 、OkHttpClient
OpenFeign 有 Apache HttpClient 、OkHttp 、HttpUrlConnection 三种实现方式
HttpClient 支持 Get 请求传递 body,OkHttp 和 HttpUrlConnection 不支持,下面讲解 HttpClient 实现方式
①、Apache HttpClient 支持 Get 请求传递 body
服务提供者
@RestController
@RequestMapping("/discovery")
public class DiscoveryController {
@GetMapping(value = "/json", consumes = MediaType.APPLICATION_JSON_VALUE)
public String selectStudent(@RequestBody Student student) {
return JSONObject.toJSONString(student);
}
}
服务提供者接口:http://127.0.0.1:20001/discovery/json
服务消费者
控制层接口
@RestController
@RequestMapping("/openfeign")
public class OpenFeignController {
@Autowired
private BootDiscoveryClient bootDiscoveryClient;
@GetMapping(value = "/json")
public String selectStudent(@RequestBody Map map) {
return bootDiscoveryClient.selectStudent(map);
}
}
feign 接口
@FeignClient(name = "SPRING-BOOT-SERVICE-DISCOVERY-CONSUMER")
@Service
public interface BootDiscoveryClient {
@GetMapping(value = "/discovery/json")
String selectStudent(@RequestBody Map map);
}
服务消费者接口:http://127.0.0.1:20004/openfeign/json
②、OkHttpClient 不支持 Get 请求传递 body
查看 OkHttpClient 源码可以看到,如果 body 不为空,请求方式为 GET 或 HEAD 则抛出异常
public static boolean permitsRequestBody(String method) {
return !method.equals("GET") && !method.equals("HEAD");
}
public Request.Builder method(String method, @Nullable RequestBody body) {
if (method == null) {
throw new NullPointerException("method == null");
} else if (method.length() == 0) {
throw new IllegalArgumentException("method.length() == 0");
} else if (body != null && !HttpMethod.permitsRequestBody(method)) {
throw new IllegalArgumentException("method " + method + " must not have a request body.");
} else if (body == null && HttpMethod.requiresRequestBody(method)) {
throw new IllegalArgumentException("method " + method + " must have a request body.");
} else {
this.method = method;
this.body = body;
return this;
}
}
四、OpenFeign 负载均衡
1、OpenFeign 和 Feign 的区别
- Feign 是 Spring Cloud 组件中一个轻量级 RESTful 的 HTTP 服务客户端
- Feign 基于 ribbon 实现,可以理解为对 ribbon 的进一步封装
- Feign 不是做负载均衡的,feign 只是集成了 ribbon,负载均衡还是 feign 内置的 ribbon 做。
- Feign 的作用的替代 RestTemplate,性能比较低,但是可以使代码可读性很强。
- OpenFeign 在 Feign 的基础上支持了 SpringMVC 的注解
2、默认负载均衡
从 BaseLoadBalancer 类可以看到, OpenFeign 负载均衡默认 RoundRobinRule 轮询方式
protected IRule rule = DEFAULT_RULE;
private final static IRule DEFAULT_RULE = new RoundRobinRule();
public Server chooseServer(Object key) {
if (counter == null) {
counter = createCounter();
}
counter.increment();
if (rule == null) {
return null;
} else {
try {
return rule.choose(key);
} catch (Exception e) {
logger.warn("LoadBalancer [{}]: Error choosing server for key {}", name, key, e);
return null;
}
}
}
3、简单测试
将 SPRING-CLOUD-SERVICE-CONFIG-PROVIDER
服务打成 jar,启动三个服务(如果是集群模式,要将服务放在云服务器,默认使用 内网 IP,不使用公网 IP,可以在启动时指定公网IP nohup java -Dfile.encoding=utf-8 -jar nacos-springcloud-config-examples-0.0.1-SNAPSHOT.jar --server.port=10002 --spring.cloud.nacos.discovery.ip=99.99.99.99 >> cloud.txt &)
下面的适用于局域网服务注册
java -Dfile.encoding=utf-8 -jar nacos-springcloud-config-examples-0.0.1-SNAPSHOT.jar --server.port=10002
java -Dfile.encoding=utf-8 -jar nacos-springcloud-config-examples-0.0.1-SNAPSHOT.jar --server.port=20002
java -Dfile.encoding=utf-8 -jar nacos-springcloud-config-examples-0.0.1-SNAPSHOT.jar --server.port=30002
启动之后查看 nacos 服务控制台,可以看到 SPRING-CLOUD-SERVICE-CONFIG-PROVIDER
服务有三个实例
接口访问:http://127.0.0.1:20004/openfeign/select
如下可以看到默认负载均衡轮询 92.168.159.1:10001 92.168.159.1:10002 92.168.159.1:10003
4、解决错误
将项目打成 jar 包,读取 nacos 配置可能报错org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
报错原因: nacos 读取配置文件默认使用 UTF-8,通过 cmd 启动项目,项目默认编码格式为 GBK
解决方式 :添加启动参数-Dfile.encoding=utf-8
命令:java -Dfile.encoding=utf-8 -jar nacos-springcloud-config-examples-0.0.1-SNAPSHOT.jar --server.port=10002
五、自定义负载均衡
spring-cloud-ribbon 文档:https://docs.spring.io/spring-cloud-netflix/docs/2.2.9.RELEASE/reference/html/#spring-cloud-ribbon
1、IRule 负载均衡规则接口
IRule 负载均衡规则接口
负载均衡类说明
负载均衡实现 | 策略 |
---|---|
RandomRule | 随机 |
RoundRobinRule | 轮询 |
AvailabilityFilteringRule | 先过滤掉由于多次访问故障的服务,以及并 发连接数超过阈值的服务,然后对剩下的服 务按照轮询策略进行访问; |
WeightedResponseTimeRule | 根据平均响应时间计算所有服务的权重,响应时间越快服务权重就越大被选中的概率即越高,如果服务刚启动时统计信息不足,则 使用RoundRobinRule策略,待统计信息足够会切换到该 |
RetryRule | 先按照RoundRobinRule策略分发如果分发 到的服务不能访问,则在指定时间内进行重试,然后分发其他可用的服务; |
BestAvailableRule | 先过滤掉由于多次访问故障的服务,然后选 择一个并发量最小的服务; |
ZoneAvoidanceRule (默认) | 综合判断服务节点所在区域的性能和服务节 点的可用性,来决定选择哪个服务; |
2、Feign 代码配置负载均衡随机策略
①、@RibbonClient 不同服务配置不同的负载均衡
@RibbonClient 目的
- @RibbonClient如果不添加,则当前项目调用的所有服务都是用该负载均衡策略
- 如果当前项目有多个服务,可以指定每个服务的负载均衡策略
- 自定义负载均衡配置类不能放在启动类包及其子包下,否则所有的服务共用一个策略,@RibbonClient 中的 name 将不起作用
- @RibbonClient 注解可以把其他的配置类作为另外一个IOC容器导入到应用中,相当于加载了两个完全不相干的Spring的beans配置文件,此时应用中会有两个IOC容器。
项目结构,添加的两个负载均衡不在启动类同包以及扫描包下
负载均衡随机策略 MyRandomRule,自定义负载均衡算法 MyDiyRule 下面步骤 3
@Configuration
public class MyRandomRule {
@Bean
public IRule ribbonRule() {
return new RandomRule(); // 采用随机策略
}
}
@RibbonClient 不同服务配置不同策略,下面两个类随便添加进启动类或者子包下的类即可
@Configuration
@RibbonClient(name = "SPRING-BOOT-SERVICE-DISCOVERY-CONSUMER", configuration = MyDiyRule.class)
class MyDiyRuleConfigRibbonClient {
}
@Configuration
@RibbonClient(name = "SPRING-CLOUD-SERVICE-CONFIG-PROVIDER", configuration = MyRandomRule.class)
class ConfigRibbonClient {
}
②、配置文件服务配置不同的负载均衡
bootstrap.yaml 添加负载均衡配置(MyDiyRule、MyRandomRule 和上面同一个类)
SPRING-BOOT-SERVICE-DISCOVERY-CONSUMER:
ribbon:
NFLoadBalancerRuleClassName: com.ribbon.MyDiyRule
SPRING-CLOUD-SERVICE-CONFIG-PROVIDER:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
# 上面的是 netflix 自带的随机算法,或者使用下面的是自定义的随机策略
# NFLoadBalancerRuleClassName: com.ribbon.MyRandomRule
③、测试
SPRING-CLOUD-SERVICE-CONFIG-PROVIDER 服务随机策略:http://127.0.0.1:20004/openfeign/select
SPRING-BOOT-SERVICE-DISCOVERY-CONSUMER 自定义负载均衡策略:http://127.0.0.1:20004/openfeign/rule
3、自定义算法实现负载均衡
仿照 IRule 的接口实现类轮询策略 RoundRobinRule,实现自定义算法负载均衡,保证每个服务访问 3 次,切换其他服务
public class MyRule extends AbstractLoadBalancerRule {
private int total;
private int currentIndex;
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
// 获取运行中的服务
List<Server> upList = lb.getReachableServers();
// 获取所有服务
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
// 简单的判断,保证每个服务执行 5 次
if (total % 3 == 0) {
if (currentIndex < upList.size()-1) {
currentIndex++;
} else {
currentIndex = 0;
this.total = 0;
}
}
total++;
// 从活着的服务中获取
server = upList.get(currentIndex);
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
server = null;
Thread.yield();
}
return server;
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
测试自定义负载均衡策略
六、熔断降级控制组件
OpenFeign 默认引入了 Hystrix 服务控制组件
Hystrix 和 Sentinel 都是分布式服务架构中服务熔断降级控制组件,Sentinel 和 Hystrix 对比选型可参考
Hystrix 概念简单实用参考:https://blog.csdn.net/qq_38149225/article/details/109454418
Sentinel 使用参考:https://github.com/alibaba/Sentinel/wiki/如何使用
1、服务雪崩
分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。
如果由于流量激增,线程数有限,会导致访问超时,最终导致 C 服务失请求败,则 B 服务也会失败,最终导致 A 服务失败。
简单说:一个服务失败,导致整条链路的服务都失败的,我们称之为服务雪崩。
2、引起雪崩的原因和服务雪崩的三个阶段
原因大致有四:
- 1、硬件故障;
- 2、程序Bug;
- 3、缓存击穿(用户大量访问缓存中没有的键值,导致大量请求查询数据库,使数据库压力过大);
- 4、用户大量请求;
服务雪崩三个阶段:
- 第一阶段: 服务不可用;
- 第二阶段:调用端重试加大流量(用户重试/代码逻辑重试);
- 第三阶段:服务调用者不可用(同步等待造成的资源耗尽);
3、雪崩解决方法
服务熔断:在一定时间内一定请求某个服务响应超时,则停止访问
服务降级:当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回响应一个缺省值。 例如:(备用接口/缓存/MySQL/mock数据) 。这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。
七、hystrix 服务降级简单测试
openfeign hystrix 参考:https://docs.spring.io/spring-cloud-openfeign/docs/2.2.9.RELEASE/reference/html/#creating-feign-clients-manually
netflix hystrix 参考:https://docs.spring.io/spring-cloud-netflix/docs/2.2.9.RELEASE/reference/html/#circuit-breaker-hystrix-clients
1、服务消费者
pom.xml 核心依赖如下,openfeign 包含 hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
bootstrap.yaml 启用 hystrix 断路器,Feign 将使用断路器包装所有方法
- Feign 开启 hystrix 断路器
feign.hystrix.enabled=true
- Feign 关闭 spring cloud 断路器
feign.circuitbreaker.enabled=true
feign:
hystrix:
enabled: true
circuitbreaker:
enabled: false
注意:启动类不能添加 @EnableCircuitBreaker ,如果添加该注解需要导入 spring-cloud-starter-netflix-hystrix 依赖
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
//@EnableCircuitBreaker
public class SpringCloudStarterOpenfeignExamplesApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudStarterOpenfeignExamplesApplication.class, args);
}
}
BootDiscoveryClient.java
@FeignClient(name = "SPRING-BOOT-SERVICE-DISCOVERY-CONSUMER",fallback = BootFallbackService.class)
@Service
public interface BootDiscoveryClient {
@GetMapping(value = "/hystrix/calculate")
String serviceDown(@SpringQueryMap Map map);
}
BootFallbackService.java 当请求超时错误回退类,需要声明为 spring bean,注意不能使用 @Controller 相关注解
@Component
public class BootFallbackService implements BootDiscoveryClient {
@Override
public String serviceDown(Map map) {
return "serviceDown 方法请求获取数据超时或错误,进行了服务降级操作";
}
}
服务消费者接口
@RestController
@RequestMapping("/hystrix")
public class HystrixController {
@Autowired
private BootDiscoveryClient bootDiscoveryClient;
@GetMapping(value = "/calculate")
public String serviceDown(String a,String b,String type) {
Map<String,String> map = new HashMap<>();
map.put("a",a); map.put("b",b); map.put("type",type);
return bootDiscoveryClient.serviceDown(map);
}
}
访问回退原因
FeignClient 接口
@Service
@FeignClient(value = "SPRING-CLOUD-SERVICE-CONFIG-PROVIDER",fallbackFactory = HystrixClientFallbackFactory.class)
public interface CloudConfigClient {
@GetMapping("/config/student")
String selectService();
}
HystrixClientFallbackFactory 回退类
@Component
public class HystrixClientFallbackFactory implements FallbackFactory<CloudConfigClient> {
@Override
public CloudConfigClient create(Throwable throwable) {
return new CloudConfigClient() {
@Override
public String selectService() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", "selectPojo 方法请求获取数据超时或错误,进行了服务降级操作");
jsonObject.put("code", 444);
jsonObject.put("err", throwable.getMessage());
return jsonObject.toJSONString();
}
};
}
}
测试 :http://127.0.0.1:20004/openfeign/select
服务提供者 debug,会导致读取超时,测试服务降级获取接口访问失败回退原因
2、服务提供者
服务提供者接口, @ApiAnnotation 为自定义注解,目的返回结果封装 url
@GetMapping("/calculate")
@ApiAnnotation
public String calculate(String a, String b, String type) {
int result = 0;
int num1 = Integer.parseInt(a);
int num2 = Integer.parseInt(b);
switch (type) {
case "+": result = num1 + num2; break;
case "-": result = num1 - num2; break;
case "*": result = num1 * num2; break;
case "/": result = num1 / num2; break;
}
return String.valueOf(result);
}
3、测试
测试可以在服务提供者打断点模拟读取超时或者 10/0 抛一个算术异常
接口:http://127.0.0.1:20004/hystrix/calculate?a=10&b=0&type=/
4、Hystrix 断路器监控
Spring Cloud 断路器监控(Hystrix Dashboard)
八、Sentinel 简单测试
参考我的另一篇博客:https://blog.csdn.net/qq_41538097/article/details/124330640
边栏推荐
- W10 is upgraded to W11 system, but the screen is black, but the mouse and desktop shortcuts can be used. How to solve it
- Carsim-路面3D形状文件参数介绍
- Introduction to anti interception technology of wechat domain name
- Rotating linked list (illustration)
- HCIA—應用層
- DWORD ptr[]
- Use the numbers 5, 5, 5, 1 to perform four operations. Each number should be used only once, and the operation result value is required to be 24
- HCIA—应用层
- Global and Chinese markets for Salmonella typhi nucleic acid detection kits 2022-2028: Research Report on technology, participants, trends, market size and share
- sqli-labs第2关
猜你喜欢
[dynamic planning] p4170: coloring (interval DP)
Web security -- core defense mechanism
Smart agriculture solutions smart agriculture system development
Matlab数学建模工具
cve_ 2019_ 0708_ bluekeep_ Rce vulnerability recurrence
Use Wireshark to grab TCP three handshakes
Jumping | Blue Bridge Cup
2022 Heilongjiang latest food safety administrator simulation exam questions and answers
文件上传-upload-labs
ICMP协议
随机推荐
Force deduction method summary: find classes
Carla-ue4editor import Roadrunner map file (nanny level tutorial)
Introduction to anti interception technology of wechat domain name
File upload and download performance test based on the locust framework
Web安全--核心防御机制
C language replaces spaces in strings with%20
Principes fondamentaux de la théorie musicale (brève introduction)
TCP/IP—传输层
类和对象(类和类的实例化,this,static关键字,封装)
idea中注释代码取消代码的快捷键
Use Wireshark to grab TCP three handshakes
Carsim-路面3D形状文件参数介绍
方法递归(斐波那契数列,青蛙跳台阶,汉诺塔问题)
Matlab-其它
Web security -- core defense mechanism
Static library and dynamic library
IP协议与IP地址
链表经典面试题(反转链表,中间节点,倒数第k个节点,合并分割链表,删除重复节点)
St-link connection error invalid ROM table of STM32 difficult and miscellaneous diseases
HCIA—应用层