SpringCloud:使用feign实现负载均衡

郎家岭伯爵 2022年06月20日 376次浏览

背景

前面实现了微服务的集群化,以及使用Ribbon实现负载均衡。本文将使用feign来实现负载均衡。

那么Ribbonfeign的负载均衡实现的差异是怎样的呢?

Ribbon的负载均衡:通过微服务名称Ribbon+RestTemplate,利用RestTemplateHTTP请求进行封装处理,形成了一套模板化的调用方法。

feign的负载均衡:通过接口和注解。只需要创建一个接口并使用注解的方式进行配置(类似于在Dao接口上标注Mapper的注解,现在是在一个微服务接口上标注一个feign注解)。

feign集成了Ribbon

实现

springcloud-api

修改pom.xml

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

创建DeptClientService接口

package com.langjialing.springcloud.service;

import com.langjialing.springcloud.pojo.Dept;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

@Component
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptClientService {

    @GetMapping("/dept/get/{id}")
    public Dept queryById(@PathVariable("id") Long id);

    @GetMapping("/dept/list")
    public List<Dept> queryAll();

    @PostMapping("/dept/add")
    public boolean addDept(Dept dept);
}

模块的文件路径

springcloud-consumer-dept-80-feign

创建模块

编辑pom.xml

<dependencies>
        <dependency>
            <groupId>com.langjialing</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

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

编辑application.yaml

server:
  port: 80

eureka:
  client:
    register-with-eureka: false # 不向Eureka注册自己
    fetch-registry: true # 从Eureka获取注册信息
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
feign:
  circuitbreaker:
    enabled: true

创建DeptConsumerController

package com.langjialing.springcloud.controller;

import com.langjialing.springcloud.pojo.Dept;
import com.langjialing.springcloud.service.DeptClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class DeptConsumerController {

    @Qualifier("com.langjialing.springcloud.service.DeptClientService") // 指定调用哪个接口类
    @Autowired
    private DeptClientService service = null;

    @GetMapping("/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id){
        return this.service.queryById(id);
    }

    @PostMapping("/consumer/dept/add")
    public boolean add(Dept dept){
        return this.service.addDept(dept);
    }

    @GetMapping("/consumer/dept/list")
    public List<Dept> list(){
        return this.service.queryAll();
    }
}

创建启动类

package com.langjialing.springcloud;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;


@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.langjialing.springcloud.service"})
public class DeptConsumer_80_Feign {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80_Feign.class, args);
    }
}

模块的文件路径

测试功能

启动springcloud-consumer-dept-80-feign模块,注意要把springcloud-consumer-dept-80模块关掉,避免端口冲突(或者可以重新设置一个端口):

总结

本文我们使用feign实现了负载均衡,feign本质上仍为Ribbon,只是通过不同的调用逻辑来实现。

至此我们完成了负载均衡的部分,接下来我们将介绍服务熔断服务降级