概要
feign:springcloud提供的微服務聲明式調用組件。
文章 SpringBoot學習8.4-ribbon負載均衡調用微服務 簡要說明了負載均衡訪問微服務的實現方式。但是每次請求都要進行RestTemplate調用代碼的開發,比較繁瑣。
feign就可以解決上述問題。feign在請求客戶端先聲明請求微服務的接口,其他方法只要調用改接口就可以。
開發要點:
- 添加ribbon、feign依賴包
- ribbon的spring配置
- @EnableFeignClients,啓動feign微服務負載均衡
- 註解@FeignClient標註接口
- 接口的方法,註解指定訪問路徑
1.maven依賴
主要是ribbon、feign依賴包。ribbon負責負載均衡,feign負責聲明接口(測試發現,如果不添加ribbon依賴,是無法實現負載均衡的)。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.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.RELEASE</spring-cloud.version>
</properties>
<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>
<!-- 實現負載均衡的ribbon依賴包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!-- 實現負載均衡的feign依賴包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependency>
<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>
2.spring配置文件
關注ribbon的配置。
server:
port: 8001 # 服務器端口
spring:
application:
name: app-server # 微服務名稱
mvc: #定義視圖解析器的規則
view:
prefix: classpath:/templates/ #文件前綴,templates是thymeleafd的默認路徑
suffix: .html #文件後綴
eureka:
client:
serviceUrl:
defaultZone: http://localhost:7001/eureka/ # 治理客戶端服務域
ribbon:
OkToRetryOnAllOperations: false #對所有操作請求都進行重試,默認false
ReadTimeout: 2000 #負載均衡超時時間,默認值5000 # 超過則會斷路
ConnectTimeout: 1000 #ribbon請求連接的超時時間,默認值2000
MaxAutoRetries: 0 #對當前實例的重試次數,默認0
MaxAutoRetriesNextServer: 1 #對切換實例的重試次數,默認1
3.開發feign聲明的接口
註解@FeignClient標註接口,聲明調用的微服務id。接口的方法,註解指定訪問路徑。
@FeignClient("service-product") ,service-product是微服務id
package com.zyf.appserver.product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* feign聲明式調用微服務(實現了負載均衡)
*/
@FeignClient("service-product") // 指定微服務id
public interface ProductService {
// 指定微服務的請求方法。使用feign時,參數名要在@PathVariable中用value指明。
@GetMapping("/productRestController/product/{id}")
public Product getById(@PathVariable(value="id") String id);
@PostMapping("/productRestController/product")
public Product insert(@RequestBody Product product);
}
@EnableFeignClients,啓動feign微服務負載均衡。
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableFeignClients(basePackages = "com.zyf.appserver.product") // 啓動feign微服務負載均衡
public class FeignConfig {
}
4.feign接口的調用
feign接口的調用與我們平時的接口調用沒有任何區別。
@Controller
@RequestMapping("/product")
@ResponseBody
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping("/getById/{id}")
public Product getById(@PathVariable String id) {
// 調用微服務
return productService.getById(id);
}
@RequestMapping("/insert")
public Product insert(@RequestBody Product product) {
// 調用微服務,測試負載均衡
for (int i = 1; i <= 10; i++) {
product.setId(i + "");
productService.insert(product);
}
return product;
}
}
5.測試
先用10001啓動service-product,然後修改端口爲10002,再次啓動service-product。
微服務搭建參考:SpringBoot學習8.3-搭建eureka微服務。
如下圖,ID爲service-product的微服務有兩個。
前臺調用ProductController.insert方法(代碼省略,可在文章末位github查找)。
service-product端口10001日誌:
產品id=1
產品id=3
產品id=5
產品id=7
產品id=9
service-product端口10002日誌:
產品id=2
產品id=4
產品id=6
產品id=8
產品id=10
可見請求平均分配帶10001和10002兩個微服務上了。
github:https://github.com/zhangyangfei/spring-cloud-learn.git 中的cloud-parent工程。