SpringCloud進擊 | 三淺出:服務消費者(Feign)【Finchley版本】
1.前言
上一節:SpringCloud進擊 | 二淺出:服務消費者(Ribbon+REST)【Finchley版本】
上一節講述瞭如何通過 Ribbon + RestTemplate 的方式去消費服務,而在實際工作中,我們基本上都是使用 Feign 來完成呼叫。這篇就來說說如何通過 Feign 實現服務消費者去消費服務。
Feign 預設集成了 Ribbon,並和 Eureka 結合,預設實現了負載均衡的效果。其特點有:
- 可插拔的註解支援
- 支援可插拔的 HTTP 編碼器和解碼器
- 支援 Hystrix 和它的 Fallback
- 支援 Ribbon 的負載均衡
- 支援 HTTP 請求和響應的壓縮
2.準備
三個角色,依舊使用上面章節已經建立好的工程:
- 服務註冊中心:wei-eureka-server,啟動一個
- 服務提供者:wei-service-provider,分別以 8010、8011 埠啟動一次,獲得兩個例項的叢集
- 服務消費者:Feign,建立一個 wei-consumer-feign 模組
3.實踐
3.1 建立服務消費者(Feign)
在專案上新建一個模組:wei-consumer-feign,建立方法與第一節建立模組過程類似。但在Dependencies選擇依賴時需要注意以下:
a)
b) 選擇左側的 Cloud Discovery 後,這裡需要鉤上 Eureka Discovery 項
c) 選擇左側的 Cloud Routing後,這裡需要鉤上 Feign 項
最後點Finish後,一個模組就自動生成了,其 pom.xml 全內容如下:
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.wei</groupId> <artifactId>wei-consumer-feign</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>wei-consumer-feign</name> <description>服務消費者(Feign)(Finchley版本)</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--Feign實現宣告式HTTP客戶端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.2 配置服務消費者
■ 編寫配置 application.yml
server:
port: 8030
spring:
application:
name: wei-cloud-feign # 指定進行服務註冊時該服務的名稱,服務與服務之間相互呼叫一般都是根據這個name
eureka:
client:
service-url:
defaultZone: http://localhost:8090/eureka/ # 指定進行服務註冊的地址
這裡,指定的服務註冊中心地址為 http://localhost:8090/eureka/,服務名稱為:wei-consumer-feign,程式埠為:8030,spring.application.name:指定進行服務註冊時該服務的名稱,服務與服務之間相互呼叫一般都是根據這個name。
■ 編寫配置Service
package com.wei.service.demo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 通過@FeignClient("Eureka服務名稱"),來指定呼叫消費哪個服務
*/
@FeignClient(value = "wei-service-provider")
public interface IDemoFeignService {
/**
* 註解@RequestMapping,對映服務提供者中的URL
* @param name 入參
* @return
*/
@RequestMapping(value = "/demo/info", method = RequestMethod.GET)
String getDemoFeignServiceName(@RequestParam(value = "name") String name);
// Feign客戶端和Ribbon類似,同樣實現了客戶端的負載均衡
// 與Ribbon不同的是,Feign的呼叫與本地介面的呼叫更加類似,並且更加便捷、更加優雅,傳入引數較多時得以體現
}
注意,這個 Service 是一個介面類。通過@FeignClient("Eureka服務提供者名稱"),來指定呼叫和消費哪個服務提供者。當前配置是消費服務提供者 wei-service-provider 的 “/demo/info” 介面。
■ 編寫配置Controller
package com.wei.controller.demo;
import com.wei.service.demo.IDemoFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoFeignController {
/**
* 編譯器報錯,無視。因為這個Bean是在程式啟動的時候注入的,編譯器感知不到,所以報錯
*/
@Autowired
private IDemoFeignService iDemoFeignService;
@RequestMapping(value = {"/feign/demo/info", "/demo/info"}, method = RequestMethod.GET)
public String getDemoFeignName(@RequestParam(value = "name") String name) {
String result = iDemoFeignService.getDemoFeignServiceName(name);
result += "[Feign]";
System.out.println(result);
return result;
}
}
具體使用時,通過 Service層,呼叫服務提供者的方法就像呼叫本地方法一樣進行呼叫即可。
■ 配置main啟動類
package com.wei;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* 註解@EnableFeignClients,開啟Feign客戶端功能
*/
@SpringBootApplication
@EnableFeignClients
public class WeiConsumerFeignApplication {
public static void main(String[] args) {
SpringApplication.run(WeiConsumerFeignApplication.class, args);
}
}
以前使用註解@EnableDiscoveryClient向服務中心註冊,因為Eureka2.0已經不需要,所以這裡可以不用該註解。
通過 Spring Cloud Feign 來實現服務呼叫的方式非常簡單,註解 @EnableFeignClients 即可開啟 Feign 客戶端功能。
最後,Run一下這個啟動類。我們再去 Spring Eureka 的服務註冊資訊面板,看一看這個服務消費者有沒有被Eureka所發現並註冊進去。
看來,一切正常。
3.3 驗證服務消費者
好了,一切準備就緒。我們就來驗證一下吧:
瀏覽器反覆請求URL:http://localhost:8030/demo/info?name=tester 或者 http://localhost:8030/feign/demo/info?name=tester
Hi,tester,我是服務,我被呼叫了,服務名為:wei-service-provider,埠為:8010[Feign]
Hi,tester,我是服務,我被呼叫了,服務名為:wei-service-provider,埠為:8011[Feign]
我們可以看到瀏覽器也在8010和8011埠之間,也就是這個小的Service服務提供者叢集之間交替列印輸出內容。
到此,Feign 的負載均衡功能驗證成功。論點2成立。
4.總結
Feign 客戶端和 Ribbon 類似,同樣實現了客戶端的負載均衡,但與 Ribbon 不同的是,Feign 的呼叫與本地介面的呼叫更加類似,並且更加便捷、更加優雅,傳入引數較多時得以體現。
4.1 案例中有三個角色:
服務註冊中心、服務提供者、服務消費者
4.2 它們的工作流:
- 啟動服務註冊中心
- 服務提供者 生產服務並註冊到服務中心
- 服務消費者 從服務中心中獲取服務並使用
4.3 此時的架構圖:
原始碼:https://github.com/itanping/wei-springcloud/tree/master/chapter03-feign
下一節,請關注:SpringCloud進擊 | 四淺出:斷路器(Hystrix)【Finchley版本】