spring cloud的 Netflix 中提供了两个组件实现软负载均衡调用:ribbon 和 feign
1、Ribbon
是一个基于 HTTP 和 TCP 客户端 的负载均衡的工具。
它可以 在客户端 配置 RibbonServerList(服务端列表),使用 HttpClient 或 RestTemplate 模拟http请求,步骤相当繁琐。
2、Feign
Feign 是在 Ribbon的基础上进行了一次改进,是一个使用起来更加方便的 HTTP 客户端。
采用接口的方式, 只需要创建一个接口,然后在上面添加注解即可 ,将需要调用的其他服务的方法定义成抽象方法即可, 不需要自己构建http请求。
然后就像是调用自身工程的方法调用,而感觉不到是调用远程方法,使得编写 客户端变得非常容易。
类似于 mybatis 的 @Mapper注解 。
Feign远程调用,核心就是通过一系列的封装和处理,将以JAVA注解的方式定义的远程调用API接口,最终转换成HTTP的请求形式,然后将HTTP的请求的响应结果,解码成JAVA Bean,放回给调用者。Feign远程调用的基本流程,大致如下图所示。
从上图可以看到,Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的 Request 请求。通过Feign以及JAVA的动态代理机制,使得Java 开发人员,可以不用通过HTTP框架去封装HTTP请求报文的方式,完成远程服务的HTTP调用。
1.2 Feign 远程调用的重要组件
在微服务启动时,Feign会进行包扫描,对加@FeignClient注解的接口,按照注解的规则,创建远程接口的本地JDK Proxy代理实例。然后,将这些本地Proxy代理实例,注入到Spring IOC容器中。当远程接口的方法被调用,由Proxy代理实例去完成真正的远程访问,并且返回结果。
为了清晰的介绍SpringCloud中Feign运行机制和原理,在这里,首先为大家梳理一下Feign中几个重要组件。
1.pom.xml中添加扩展(注意版本)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
package com.example.devguo.service.feign;
import com.example.devguo.service.fallback.BasicInfoServiceFallBack;
import org.springframework.cloud.client.loadbalancer.reactive.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
import java.util.Map;
/**
* @Author: dev_guo
* @Date: 2022/2/10 16:28
*/
@FeignClient(value = "public-server",fallback = BasicInfoServiceFallBack.class)
public interface BasicInfoService {
@PostMapping("/api/basicInfo/getProductDetails")
Response getProductDetails(Map<String,Object> feignParam);
}
package com.example.devguo.service.fallback;
import com.example.devguo.service.feign.BasicInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.loadbalancer.reactive.Response;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @Author: dev_guo
* @Date: 2022/2/10 16:37
*/
@Slf4j
@Component
public class BasicInfoServiceFallBack implements BasicInfoService {
@Override
public Response getProductDetails(Map<String, Object> feignParam) {
return null;
}
}