SpringCloud版本:2021.0.1 SpringBoot版本:2.6.3
系列文章
SpringCloud学习(一)----- Eureka搭建
SpringCloud学习(二)----- SpringBoot Admin搭建(与Eureka整合)
SpringCloud学习(三)----- Gatewayw网关搭建
SpringCloud学习(四)----- Gatewayw网关完善(限流)
SpringCloud学习(五)----- Gatewayw网关完善(Resilience4j断路器)
SpringCloud学习(六)----- Gatewayw网关完善(防止SQL注入)
SpringCloud学习(七)----- 使用Feign调用别的微服务的方法
SpringCloud学习(八)----- Gateway网关及其他微服务接入Swagger接口文档
参考文章:
今日教学:RestTemplate 结合 Ribbon 使用
FEIGN调用出现权限问题 FEIGN.FEIGNEXCEPTION$UNAUTHORIZED: [401] DURING [GET] TO[....]
因为在微服务的框架中,已经把所有的服务的功能区分的很细了,所以有可能会出现一种问题,就是比如某个微服务需要用到某个功能,但这个功能已经划分在别的服务并已经开发完成了,那么这个时候就可以用到Feign这个来调用别的服务的方法了。
一般常用的有两种方法,即Ribbon + RestTemplate进行微服务调用或者使用Feign进行微服务调用。当然,也有一个最原始的方法,那就是http接口,这个也可以实现微服务之间的方法的调用的功能,但就是比较麻烦,头铁的可以试试。那么,Ribbon + RestTemplate和Feign这两种方法有什么区别吗?那当然是有的,但也没有那么大的区别。
1、它们的启动类注解不同,Ribbon是@RibbonClient,Feign的是@EnableFeignClients。
2、服务指定的位置不同,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明。
3、调用方式不同,Ribbon需要自己构建http请求,先模拟http请求然后再使用RestTemplate发送给其他服务,步骤比较繁琐。但Feign只需要将调用的方法定义成抽象方法即可,当然,前提是得已经把服务注册到注册中心。
那么,它们之间对比下来,那个更好呢?
1、Ribbon弊端:代码里会充斥着大量的url,在小型项目中还好,但在大型项目里,维护成本就会很高了。
2、Feign弊端:如果微服务调用的方法入参发生了变化,那么对应的Feign方法也得进行相应的更改,但这个我觉得还是可以接受的。
不过呢,一般开发人员都会选用Feign来进行微服务之间的调用,因为如果真的使用Ribbon + RestTemplate的话,那么维护成本就太高了,相比较下,Feign还是比较好的。
那么,回归主题,首先简单介绍一下Ribbon + RestTemplate的使用。
首先,是Ribbon的pom依赖导入,不过如果用的是Eurker作为注册中心的话,也不用导入,因为Eureka 中已经引用了Ribbon。
-
org.springframework.cloud -
spring-cloud-starter-ribbon
然后我们需要在启动类里面的方法创建一个负载均衡的RestTemplate Bean
- @SpringBootApplication
- @EnableDiscoveryClient
- public class TestApplicaton {
- //创建一个负载均衡的RestTemplate Bean
- @LoadBalanced
- @Bean
- public RestTemplate restTemplate(){
- return new RestTemplate();
- }
- public static void main(String[] args) {
- SpringApplication.run(TestApplicaton.class, args);
- }
- }
再然后,在要使用的方法里进行引入就可以了。
-
- @Autowired
- private RestTemplate restTemp;
-
-
- public String test(){
- //与Eurka集成,将服务注册到Eurka,url中使用注册到Eurka中服务名来进行调用
- ResponseEntity
rest = restTemp.getForEntity("http://test-service/test/hello" , String.class); - if (rest != null){
- return rest.getBody();
- }
- return null;
-
- }
(1)引入pom依赖
-
org.springframework.cloud -
spring-cloud-starter-openfeign
(2)在启动类上加上 @EnableFeignClients注解
- @EnableDiscoveryClient
- @SpringBootApplication
- @EnableFeignClients
- public class TestApplicaton {
- public static void main(String[] args) {
- SpringApplication.run(TestApplicaton.class, args);
- }
- }
(3)新建访问其他微服务的接口
- @FeignClient("test-service")
- public interface ServiceApi {
- @PostMapping("/test/hello")
- String hello();
- }
在使用Feign中,我还出现过401的问题,这种情况为没有认证就请求了资源服务器的资源,解决办法为使用Feign的时候把请求的认证信息传递过去,或者资源服务那边开放一些接口。不过开放接口的话情况有点多,所以就选择把token携带过去了。feign提供了一个名为RequestInterceptor得拦截器,可以在请求的时候指定请求头。
解决方法就是加一个配置文件, 在请求的时候指定请求头,就可以了。
- @Configuration
- public class FeignConfig implements RequestInterceptor {
- @Override
- public void apply(RequestTemplate requestTemplate) {
- ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- HttpServletRequest request = attributes.getRequest();
- requestTemplate.header("Authorization", request.getHeader("Authorization"));
- }
- }