1. 程式人生 > 其它 >springcloud-Feign負載均衡(基於服務端)

springcloud-Feign負載均衡(基於服務端)

1 Feigin介紹

1.1 Feigin是什麼

Feign是宣告式Web Service客戶端,它讓微服務之間的呼叫變得更簡單,類似於controller呼叫service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供負載均衡的http客戶端

Feign,主要是社群版,大家都習慣面向介面程式設計。這個是很多開發人員的規範。呼叫微服務訪問兩種方法

  • 微服務名字 【ribbon】
  • 介面和註解 【feign】

1.2 Feigin能幹什麼

  • Feign旨在使編寫Java Http客戶端變得更容易
  • 前面在使用Ribbon + RestTemplate時,利用RestTemplate對Http請求的封裝處理,形成了一套模板化的呼叫方法。但是在實際開發中,由於對服務依賴的呼叫可能不止一處,往往一個介面會被多處呼叫,所以通常都會針對每個微服務自行封裝一個客戶端類來包裝這些依賴服務的呼叫。所以,Feign在此基礎上做了進一步的封裝,由他來幫助我們定義和實現依賴服務介面的定義,在Feign的實現下,我們只需要建立一個介面並使用註解的方式來配置它 (類似以前Dao介面上標註Mapper註解,現在是一個微服務介面上面標註一個Feign註解),即可完成對服務提供方的介面繫結,簡化了使用Spring Cloud Ribbon 時,自動封裝服務呼叫客戶端的開發量。
  • Feign預設集成了Ribbon,利用Ribbon維護了MicroServiceCloud-Dept的服務列表資訊,並且通過輪詢實現了客戶端的負載均衡,而與Ribbon不同的是,通過Feign只需要定義服務繫結介面且以宣告式的方法,優雅而簡單的實現了服務呼叫。

2 Feigin具體實現

基於:springcloud-Ribbon負載均衡(基於客戶端)

2.1 建立模組

在父工程下新建一個普通的maven專案 springcloud-consumer-dept-feign

springcloud-consumer-dept-feign模組中的所有內容與springcloud-consumer-dept-80模組完全一致,只需要複製過來即可,然後修改一下啟動類

springcloud-consumer-dept-feign : src/main/java/com/lv/springcloud/FeignDeptConsumer_80.java

package com.lv.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;

//Ribbon 和 Eureka 整合以後,客戶端可以直接呼叫,不用關心IP地址和埠號
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.lv.springcloud"})
public class FeignDeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(FeignDeptConsumer_80.class,args);
    }
}

2.2 匯入依賴

需要給springcloud-consumer-dept-feign和springcloud-api這兩個模組匯入feign依賴

springcloud-api : pom.xml

springcloud-consumer-dept-feign : pom.xml

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

2.3 建立service介面

在springcloud-api模組下新建一個service包,並在該包下建立一個DeptClientService 介面

springcloud-api : src/main/java/com/lv/springcloud/service/DeptClientService.java

package com.lv.springcloud.service;

import com.lv.springcloud.pojo.Dept;
import org.springframework.cloud.openfeign.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);
}

2.4 修改控制層

修改springcloud-consumer-dept-feign模組的DeptConsumerController.java,將原來的Ribbon方式改為feign的方式

springcloud-consumer-dept-feign : src/main/java/com/lv/springcloud/controller/DeptConsumerController.java

package com.lv.springcloud.controller;

import com.lv.springcloud.pojo.Dept;
import com.lv.springcloud.service.DeptClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class DeptConsumerController {

    @Qualifier("com.lv.springcloud.service.DeptClientService")
    @Autowired
    private DeptClientService service = null;

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

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

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

對比Feign和Ribbon這兩種方式,Feign顯現出面向介面程式設計特點,程式碼看起來更清爽,而且Feign呼叫方式更符合我們之前在做SSM或者SprngBoot專案時,Controller層呼叫Service層的程式設計習慣!

2.5 測試

依次啟動7001,8001,8002,和新建立的springcloud-consumer-dept-feign

啟動成功後訪問http://localhost/consumer/dept/list

成功查詢出資料庫中內容

3 Feign和Ribbon如何選擇

  • 根據個人習慣而定,如果喜歡REST風格使用Ribbon;如果喜歡社群版的面向介面風格使用Feign.
  • Feign 本質上也是實現了 Ribbon,只不過後者是在呼叫方式上,為了滿足一些開發者習慣的介面呼叫習慣!