SpringCloudAlibaba随筆目錄
一、SpringCloudAlibaba項目之父工程搭建
二、SpringCloudAlibaba項目之Nacos搭建及服務注冊
三、SpringCloudAlibaba項目之生産者與消費者
四、SpringCloudAlibaba項目之Ribbon負載均衡
五、SpringCloudAlibaba項目之OpenFeign遠端調用
六、SpringCloudAlibaba項目之Nacos-config配置中心
七、SpringCloudAlibaba項目之Sentinel流量控制
八、SpringCloudAlibaba項目之Seata分布式事務
九、SpringCloudAlibaba項目之GateWay網關
十、SpringCloudAlibaba項目之SkyWalking鍊路追蹤
SpringCloudAlibaba項目之OpenFeign遠端調用
1、OpenFeign
OpenFeign是一種聲明式、模闆化的HTTP用戶端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP請求通路遠端服務,就像調用本地方法一樣的,開發者完全感覺不到這是在調用遠端方法,更感覺不到在通路HTTP請求。
2、Feign與OpenFeign的差別
Feign是Spring Cloud元件中一個輕量級RESTful的HTTP服務用戶端,Feign内置了Ribbon,用來做用戶端負載均衡,去調用服務注冊中心的服務。Feign的使用方式是:使用Feign的注解定義接口,調用接口,就可以調用服務注冊中心的服務。
OpenFeign是Spring Cloud在Feign的基礎上支援了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通過動态代理的方式産生實作類,實作類中做負載均衡并調用其他服務。
說明:springcloud F 及F版本以上 springboot 2.0 以上基本上使用openfeign,openfeign 如果從架構結構上看就是2019年feign停更後出現版本,也可以說大多數新項目都用openfeign ,2018年以前的項目在使用 feign。
3、快速使用 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 繼承父工程版本依賴 -->
<parent>
<artifactId>spring-cloud-alibaba</artifactId>
<groupId>com.qt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.qt</groupId>
<artifactId>service-openfeign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-openfeign</name>
<description>service-openfeign project</description>
<dependencies>
<!-- springweb 啟動依賴 -->
<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>
</dependency>
<!-- openfeign 遠端調用依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- springboot 測試類 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.qt.serviceopenfeign.ServiceOpenfeignApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
建立Openfeign服務接口
/**
* 庫存服務接口
* name:指定調用rest接口所對應的服務名
* path:指定調用rest接口所在的StockController指定的@RequestMapping
*/
@FeignClient(name = "service-stock",path = "stock")
public interface StockOpenFeignService {
//聲明需要調用的rest接口對應的方法
/**
* 庫存扣減
* @return
*/
@RequestMapping("/subStock")
String subStock();
/**
* 庫存新增
* @return
*/
@RequestMapping("/addStock")
String addStock();
}
OrderController調用:
/**
* 訂單服務
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Resource
private StockOpenFeignService stockOpenFeignService;
/**
* 新增訂單
* @return
*/
@RequestMapping("/addOrder")
public String addOrder(){
System.out.println("訂單新增成功");
//調用庫存扣減
String result = stockOpenFeignService.subStock();
return "訂單服務-訂單新增成功:" + result;
}
}
application.properties
# 應用名稱
spring.application.name=service-openfeign
# 應用服務 WEB 通路端口
server.port=8060
# Nacos幫助文檔: https://nacos.io/zh-cn/docs/concepts.html
# Nacos認證資訊
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
# Nacos 服務發現與注冊配置,其中子屬性 server-addr 指定 Nacos 伺服器主機和端口
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 注冊到 nacos 的指定 namespace,預設為 public
spring.cloud.nacos.discovery.namespace=public
通路位址:http://localhost:8060/order/addOrder
4、日志配置
有時候我們遇到bug,接口調用失敗、參數沒收到等問題,或者想看看調用性能,就需要配置OpenFeignde的日志了,以此讓openFeign把請求資訊輸出來。
OpenFeign提供了日志列印功能,我們可以通過配置來調整日恙級别,進而了解Feign 中 Http請求的細節。
日志級别
- NONE:預設的,不顯示任何日志;
- BASIC:僅記錄請求方法、URL、響應狀态碼及執行時間;
- HEADERS:除了BASIC中定義的資訊之外,還有請求和響應的頭資訊;
- FULL:除了HEADERS中定義的資訊之外,還有請求和響應的正文及中繼資料;
全局配置:
操作步驟:
- 在配置類中添加日志配置
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 全局配置:當使用@Configuration 會将配置作用所有的服務提供方
* 局部配置:如果隻想針對某一個服務進行配置,就不要加@Configuration
*/
@Configuration
public class OpenFeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
注:這裡的logger是feign包裡的
- application.properties添加配置
# openfeign配置包下(或指定哪些業務接口)以什麼日志級别監聽,springboot的預設日志級别是info,openFeign的日志級别debug就不會輸出,是以需要加上此配置
logging.level.com.qt.serviceopenfeign.openfeign=debug
#logging.level.com.qt.serviceopenfeign.openfeign.StockOpenFeignService=debug
日志輸出效果:
局部配置:
方式1,直接在接口上指定
/**
* 庫存服務接口
* name:指定調用rest接口所對應的服務名
* path:指定調用rest接口所在的StockController指定的@RequestMapping
*/
@FeignClient(name = "service-stock",path = "stock",configuration = OpenFeignConfig.class)
public interface StockOpenFeignService {
//聲明需要調用的rest接口對應的方法
/**
* 庫存扣減
* @return
*/
@RequestMapping("/subStock")
String subStock();
/**
* 庫存新增
* @return
*/
@RequestMapping("/addStock")
String addStock(@PathVariable("id") String id);
}
方式2,application.properties添加配置
# openfeign日志局部配置
feign.client.config.service-stock.loggerLevel=basic
5、契約配置
方式1,在OpenFeignConfig中添加配置類
/**
*全局配置:當使用@Configuration 會将配置作用所有的服務提供方
* 局部配置:1、如果隻想針對某一個服務進行配置,就不要加@Configuration
* 2、配置檔案
*/
@Configuration
public class OpenFeignConfig {
/**
* 日志配置
* @return
*/
/*@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}*/
/**
* 修改契約配置,支援Feign原生的注解
* @return
*/
@Bean
public Contract feignContract(){
return new Contract.Default();
}
}
方式2,在配置檔案中配置
# openfeign日志局部配置
feign.client.config.service-stock.loggerLevel=basic
#設定為預設的契約 (還原成原生注解)
feign.client.config.service-stock.contract=feign.Contract.Default
修改StockOpenFeignService服務接口注解方式
/**
* 庫存服務接口
* name:指定調用rest接口所對應的服務名
* path:指定調用rest接口所在的StockController指定的@RequestMapping
*/
@FeignClient(name = "service-stock",path = "stock",configuration = OpenFeignConfig.class)
public interface StockOpenFeignService {
//聲明需要調用的rest接口對應的方法
/**
* 庫存扣減
* @return
*/
//@RequestMapping("/subStock")
@RequestLine("GET /subStock") //feign的原生注解
String subStock();
/**
* 庫存新增
* @return
*/
//@RequestMapping("/addStock")
@RequestLine("GET /addStock") //feign的原生注解
//String addStock(@PathVariable("id") String id);
String addStock(@Param("id") String id); //@PathVariable換成@Param
}
通路位址:http://localhost:8060/order/subOrder
6、逾時時間配置
方式1,在OpenFeignConfig中添加配置類
/**
* 全局配置:當使用@Configuration 會将配置作用所有的服務提供方
* 局部配置:1、如果隻想針對某一個服務進行配置,就不要加@Configuration
* 2、配置檔案
*/
@Configuration
public class OpenFeignConfig {
/**
* 日志配置
* @return
*/
/*@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}*/
/**
* 修改契約配置,支援Feign原生的注解
* @return
*/
/*@Bean
public Contract feignContract(){
return new Contract.Default();
}*/
/**
* 逾時時間配置
* @return
*/
@Bean
public Request.Options options(){
return new Request.Options(5000,10000);
}
}
方式2,配置檔案修改
#修改某個服務的預設逾時時間
# 配置 類别調用商品服務openfeign預設逾時時間 預設連接配接逾時和等待逾時時間都是1s
# 配置指定服務連接配接逾時
#feign.client.config.service-stock.connectTimeout=5000
# 配置指定服務等待逾時
#feign.client.config.service-stock.readTimeout=5000
#修改OpenFeign預設調用所有服務的預設逾時時間
# 配置openfeign預設逾時時間 預設時間 機關毫秒
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=5000
7、自定義攔截器
自定義攔截器,CustomFeignInterceptor
/**
* 自定義feign攔截器
*/
public class CustomFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
//寫一些自己的業務邏輯 帶上token 什麼之類的
System.out.println("執行openFeign自定義攔截器");
String access_token = UUID.randomUUID().toString();
requestTemplate.header("Authorization",access_token);//設定認證
}
}
全局配置
如果寫在配置類中,注入的形式則就是全局的攔截器,因為并沒有指定是為具體服務進行配置。
@Configuration
public class OpenFeignConfig {
/**
* 自定義feign攔截器
* @return
*/
@Bean
public CustomFeignInterceptor customFeignInterceptor() {
return new CustomFeignInterceptor();
}
}
配置檔案,application.properties
如果寫在配置檔案中指明了服務,則為具體的服務指定一個或者多個攔截器
#在配置檔案中設定feign攔截器
feign.client.config.service-stock.requestInterceptors[0]=com.qt.serviceopenfeign.Interceptor.CustomFeignInterceptor