Feign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务一样简单, 只需要创建一个接口并添加一个注解即可。

​ Nacos很好的兼容了Feign, Feign默认集成了 Ribbon, 所以在Nacos下使用Fegin默认就实现了负载均衡的效果。

主要模块:producer(生产者)、consumer(消费者)。消费者调用生产者。Feign主要作用于服务层。

1.引入openfeign实现发送请求

我们在消费者的pom文件中引入openfeign。

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

再加入loadbalance后变成:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>s-cloud-alibaba</artifactId>
        <groupId>site.longkui</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consumer-1</artifactId>

    <dependencies>
        <!--spring boot web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--nacos服务发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--openfeign  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- loadbalancer负载均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

</project>

如果引入依赖失败,可以尝试重启IDEA,或者清除缓存重启,刷新maven等操作来解决。

然后在消费者的启动类上加入@EnableFeignClients注解。

然后,我们在消费者模块,创建server层。

package site.longkui.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient("service-producer")
public interface ConsumerFeignService {

    @GetMapping("/user/getUser")
    String feignGetUser();
}


然后我们在消费者的controller层增加访问service层的代码

package site.longkui.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import site.longkui.service.ConsumerFeignService;


@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ConsumerFeignService consumerFeignService;
    //消费者接口
    @GetMapping("/getUser")
    public  String getUser(){
        //指出服务地址
        String url="http://localhost:8010/user/getUser";
        //返回值类型和我们的业务返回值一致
        return restTemplate.getForObject(url, String.class);
    }

    //使用feign的消费者接口
    @GetMapping("/testFeign")
    public String testFeign(){
       return consumerFeignService.feignGetUser();
    }

}

我们访问消费者的新的接口地址:localhost:9010/consumer/testFeign

可以看到我们使用feign的方式访问到了生产者的接口。

2.feign实现负载均衡

为了测试负载均衡,我们新创建一个生产者,端口为8020。

我们复制一份生产者代码,把端口改成8020。然后启动这个服务。

我们也要修改生产者2的代码来区分一下内容:

注意:这只是为了显示是否负载均衡,实际生产中不会这样复制很多份代码。

然后我们访问消费者的代码。

可以看到,我们实现了负载均衡。

3.后记

实践中,发现如果不引入spring-cloud-starter-loadbalancer 会直接报错

Caused by: java.lang.IllegalStateException: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer?