Skip to content

新一代负载均衡组件-Feign

什么是Feign

SpringCloud提供的伪http客户端(本质还是用http),封装了Http调用流程,更适合面向接口化。让用Java接口注解的方式调用Http请求,不用像Ribbon中通过封装HTTP请求报文的方式调用。Feign默认集成了Ribbon,Nacos支持Feign,可以直接集成实现负载均衡的效果。

ribbon存在的问题

  • 不规范,风格不统一,维护性比较差
  • 比如在订单服务调用视频服务,url都是拼接的,很麻烦

集成Feign实现远程方法调用

在订单服务的POM中添加依赖

java
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

在订单服务的启动类增加注解@EnableFeignClients

java
//开启Feign支持
@EnableFeignClients
//开启服务发现
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
	//此处若不需要可以删掉
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

添加订单服务的service接口

java
import com.study.pojo.Video;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

//将视频服务名称添加
@FeignClient(name="class-video-service")
public interface OrderService {
    //写上路径,自动会携带参数
    @GetMapping("/api/v1/video/find_by_id")
    Video findById(@RequestParam("videoId") int videoId);
}

改造订单服务Controller

java
@RestController
@RequestMapping("/api/v1/video_order")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @GetMapping("/save")
    public Object save(int videoId){
        //访问视频服务
        Video video = orderService.findById(videoId);
        //构造返回对象
        VideoOrder videoOrder = new VideoOrder();
        videoOrder.setVideoId(videoId);
        videoOrder.setVideoTitle(video.getTitle());
        videoOrder.setCreateTime(video.getCreateTime());
        return videoOrder;
    }
}

post方式对象传输 Open-Feign 实现远程方法调用

视频服务中添加一个POST接口

java
//插入 - 此处参数为了方便,只传了一个id
@PostMapping("/insert")
public void insert(@RequestBody Video video){
    //为了方便,只是打印了一下参数
    System.out.println("视频标题:" + video.getTitle());
}

订单服务中的service接口增加方法

java
//插入 - 传递对象到视频服务
@PostMapping("/api/v1/video/insert")
void insert(@RequestBody Video video);

订单服务Controller中增加方法

java
//此处为了方便测试,是get请求
@GetMapping("/insert")
public void insert(){
    //此处为了测试方便,直接查询了一个视频
    Video video = orderService.findById(40);
    //远程调用
    orderService.insert(video);
}

启动订单服务和视频服务,进行测试

java
http://localhost:8000/api/v1/video_order/insert