ps:阅读此文章前,你必须具备实现一个基于Feign的可编程式接口的能力
Feign 的具体应用可以查看这篇文章
https://blog.csdn.net/weixin_43721000/article/details/124214887
Hystrix可以防止微服务链式调用时的雪崩
ps:
1.当C服务崩溃时,通过阻止B到C的通路来保护AB服务
2.熔断器定义在主动调用接口的微服务中【B调用C则B定义熔断器】
3.当B调用C时,如果在一定时间内B的请求失败次数超过了 Hystrix 的阈值,Hystrix 会熔断BC间的服务调用链
4.服务熔断后,经过一定时间 Hystrix 会放行B到C的一部分请求,如果此时请求结果返回正常,Hystrix 会关闭熔断器,恢复BC服务调用链。
实现两个微服务 A B,并且 A 可以通过 Feign 调用 B
我这里服务 A 的名称叫 order,服务 B 的名称叫 bookschina,是一个图书资源的调用
ps:以下全部修改操作都是针对服务 A 的,服务 B 不需要改动
引入 Feign ,由于 Feign 中已经引入了 Hystrix,所以只需要引入 Feign 的依赖即可
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
开启熔断功能
feign:
hystrix:
enabled: true # 开启 hystrix
<1>在服务调用接口的 @FeignClient 注解上增加 fallback 参数
package com.cxstar.client;
import com.alibaba.fastjson.JSONObject;
import com.cxstar.client.fallback.BookschinaClientFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Component
@FeignClient(value = "bookschina-service", fallback = BookschinaClientFallback.class)
public interface BookschinaClient {
@GetMapping("/bookschina/spiderBookList/{searchkey}/{pageno}")
JSONObject searchBookschina(
@PathVariable("searchkey") String searchKey,
@PathVariable("pageno") Integer pageNo
);
}
package com.cxstar.client.fallback;
import com.alibaba.fastjson.JSONObject;
import com.cxstar.client.BookschinaClient;
import org.springframework.stereotype.Component;
@Component
public class BookschinaClientFallback implements BookschinaClient {
@Override
public JSONObject searchBookschina(String searchKey, Integer pageNo) {
JSONObject jb = new JSONObject();
jb.put("msg", "熔断信息"); //直接返回固定的熔断信息即可
return jb;
}
}
测试类
package com.cxstar;
import com.alibaba.fastjson.JSONObject;
import com.cxstar.client.BookschinaClient;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
class OrderApplicationTests {
@Autowired
public BookschinaClient bookschinaClient;
@Test
void contextLoads() {
JSONObject jb = bookschinaClient.searchBookschina("东野圭吾", 1);
log.info(jb.toString());
}
}
我在使用熔断服务的时候,调用接口不能在接口名上添加 @RequestMapping 注解,比如下面这种情况
@Component
@FeignClient(value = "bookschina-service", fallback = BookschinaClientFallback.class)
@RequestMapping("/bookschina")
public interface BookschinaClient {
@GetMapping("/spiderBookList/{searchkey}/{pageno}")
JSONObject searchBookschina(
@PathVariable("searchkey") String searchKey,
@PathVariable("pageno") Integer pageNo
);
}
路由虽然是 /bookschina/spiderBookList/{searchkey}/{pageno},但是会报错,下面是报错信息,希望大佬指点原因
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'com.cxstar.client.BookschinaClient' method
com.sun.proxy.$Proxy105#searchBookschina(String, Integer)
to {GET /bookschina/spiderBookList/{searchkey}/{pageno}}: There is already 'bookschinaClientFallback' bean method
如果去掉 @RequestMapping ,改成下面这样,就可以正常使用熔断功能了
@Component
@FeignClient(value = "bookschina-service", fallback = BookschinaClientFallback.class)
public interface BookschinaClient {
@GetMapping("/bookschina/spiderBookList/{searchkey}/{pageno}")
JSONObject searchBookschina(
@PathVariable("searchkey") String searchKey,
@PathVariable("pageno") Integer pageNo
);
}
路由还是 /bookschina/spiderBookList/{searchkey}/{pageno},这样就不报错了,不知为啥【狗头】