Spring Cloud系列之Eureka
Spring Cloud系列之配置中心Config
Spring Cloud系列之gateway
Spring Cloud系列之Feign
Spring Cloud系列之Hystrix
Spring Cloud系列之鏈路追蹤
簡介
feign是netfix開發(fā)的一個輕量級的restful的http服務(wù)客戶端维咸,用來發(fā)起請求萍歉、遠(yuǎn)程調(diào)用凰棉。是以java接口注解的方式調(diào)用http請求讳侨,而不用像java中通過封裝http請求報文的方式直接調(diào)用。消費者拿到服務(wù)提供者的接口溺蕉,然后像調(diào)用本地方法一樣去調(diào)用遠(yuǎn)程的接口伶丐,本質(zhì)上就是feign幫我們?nèi)プ隽朔庋b并且發(fā)起請求。更符合面向接口化的編程邏輯疯特。
可以幫助我們更加便捷優(yōu)雅的調(diào)用http的API哗魂,不需要我們?nèi)テ唇觰rl通過restTmplate方式去調(diào)用遠(yuǎn)程接口
并且feign支持了springMVC注解
Feign入門
Feign服務(wù)提供者搭建
- 添加依賴
<dependencies>
<!-- eureka client依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- configClient依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- feign依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 健康監(jiān)測依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--鏈路追蹤-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
</dependencies>
- FeignClient的創(chuàng)建
/**
* @Description:
* @author: dy
* @Date: 2021/11/26
*/
//@FeignClient表明當(dāng)前類是一個feign客戶端,value指定該客戶端要請求的服務(wù)名稱(登記到注冊中心的服務(wù)提供者名稱)
@FeignClient(value = "user-service",path = UserClient.MAPPING)
public interface UserClient {
String MAPPING = "/user-service";
@RequestMapping(value = "/get_user_id", method = RequestMethod.GET)
public String getUserId();
}
/**
* @Description:
* @author: dy
*/
@Slf4j
@RestController
@RequestMapping(UserClient.MAPPING)
public class UserResource implements UserClient {
@Autowired
private AppInfo appinfo;
@Override
public String getUserId() {
log.info("==============請求來了===============");
return "======111111222>>"+appinfo.getAppId();
}
}
- 啟動類
/**
* @Description:
* @author: dy
*/
@EnableDiscoveryClient //開啟Eureka客戶端發(fā)現(xiàn)功能
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
Feign服務(wù)消費者搭建
- 引入依賴
<dependencies>
<!--引入user-service依賴-->
<dependency>
<groupId>com.dy</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--config-client依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--eureka-client依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--鏈路追蹤-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
</dependencies>
- 啟動類 (開啟feign客戶端功能)
/**
* @Description:
* @author: dy
*/
//開啟feign客戶端功能 basePackages指定要掃描的feignClient類所在包路徑
@EnableFeignClients(basePackages = {"com.dy.user.client"})
//開啟Eureka客戶端發(fā)現(xiàn)功能
@EnableDiscoveryClient
@SpringBootApplication
public class UserApiApplication {
public static void main(String[] args) {
SpringApplication.run(UserApiApplication.class, args);
}
}
- 使用
/**
* @Description:
* @author: dy
* @Date: 2021/11/29
*/
@Slf4j
@RestController
public class UserController implements UserApi {
@Autowired
private UserClient userClient;
@Override
public String getUserInfo() {
log.info("==========滴滴========");
return userClient.getUserId();
}
}
這樣完成了feign的基本使用漓雅,但是我們思考一個問題录别?如果我們同時啟動了幾個service服務(wù),那我們的api會調(diào)用哪個service呢故硅?
feign對負(fù)載均衡的支持
feign自身已經(jīng)集成了對ribbon依賴和自動配置庶灿,因此不需要我們引入額外對ribbon的依賴,可用通過在配置文件里面添加響應(yīng)的配置進(jìn)行全局的配置或者對某個服務(wù)單獨的負(fù)載均衡配置吃衅。
feign默認(rèn)的請求處理超時時長是1s,有時候肯定我們的業(yè)務(wù)處理邏輯是超過1s的腾誉,那么這些就需要我們根據(jù)自己的業(yè)務(wù)進(jìn)行相應(yīng)的配置徘层,以滿足我們對每個服務(wù)的調(diào)用需求
對單個服務(wù)的ribbon配置:
user-service:
ribbon:
#請求連接超時時間
ConnectTimeout: 3000
#請求處理超時時間
ReadTimeout: 15000
#對所有操作都進(jìn)行重試
OkToRetryOnAllOperations: true
#對當(dāng)前選中的實例重試次數(shù),不包含第一次調(diào)用
MaxAutoRetries: 0
#切換實例的重試次數(shù)
MaxAutoRetriesNextServer: 0
#負(fù)載均衡策略配置
NFLoadBalancerRuleClassName: com.netfix.loadbalancer.RoundRobinRule
負(fù)載均衡邏輯如下:
根據(jù)上面得配置利职,當(dāng)訪問超時時趣效,系統(tǒng)會再嘗試一次訪問當(dāng)前實例(次數(shù)由MaxAutoRetries配置)
如果不行,就換一個實例進(jìn)行訪問猪贪,如果還不行跷敬,再換一個實例訪問(更換次數(shù)由MaxAutoRetriesNextServer這個決定)
如果還不行,就返回失敗結(jié)果
Ribbon默認(rèn)的負(fù)載均衡策略是RoundRobinRule也就是輪詢热押,當(dāng)然在實際開發(fā)中我們可以根據(jù)我們服務(wù)的響應(yīng)配置進(jìn)行響應(yīng)的負(fù)載均衡策略的自定義
對全局的ribbon配置(就把我們服務(wù)的名字去掉就可以了):
ribbon:
#請求連接超時時間
ConnectTimeout: 3000
#請求處理超時時間
ReadTimeout: 15000
#對所有操作都進(jìn)行重試
OkToRetryOnAllOperations: true
#對當(dāng)前選中的實例重試次數(shù)西傀,不包含第一次調(diào)用
MaxAutoRetries: 0
#切換實例的重試次數(shù)
MaxAutoRetriesNextServer: 0
#負(fù)載均衡策略配置
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
Feign的日志級別配置
Feign是http請求的客戶端斤寇,類似于瀏覽器,在請求和接受響應(yīng)的時候拥褂,可以打印出比較詳細(xì)的一些信息娘锁,比如:響應(yīng)頭、狀態(tài)碼等等
如果我們想看到Feign請求時的日志饺鹃,我們可以進(jìn)行一些配置莫秆,默認(rèn)情況下Feign的日志是沒有開啟的。
- 在api module配置如下
/**
* @Description:
* @author: dy
*/
@Configuration
public class FeignConfig {
/**
*
* @return
*/
@Bean
Logger.Level feignLevel(){
return Logger.Level.FULL;
}
}
LEVEL說明:
NONE 不顯示任何日志
BASIC 僅記錄請求方法悔详、URL镊屎、響應(yīng)狀態(tài)碼、執(zhí)行時間 茄螃,適用于生產(chǎn)環(huán)境
HEADERS 在BASIC的基礎(chǔ)上記錄請求響應(yīng)的header
FULL 記錄請求響應(yīng)的header杯道、body、元數(shù)據(jù) 適用于開發(fā)及測試環(huán)境
注意配置log日志級別:
logging:
level:
com.dy.user: debug
運行結(jié)果如下:
Feign對熔斷器的支持
- 在feign客戶端配置文件添加配置開啟對熔斷的支持
#開啟對hystrix的支持
feign:
hystrix:
enabled: true
上面我們設(shè)置了feign的超時時長設(shè)置實際上是對Ribbon的超時時長設(shè)置责蝠,但是如果開啟了對hystrix的支持党巾,hystrix還有超時時長設(shè)置,如下
hystrix:
command:
default:
execution:
isolation:
thread:
#hystrix超時時長設(shè)置
timeoutInMilliseconds: 5000
開啟對hystrix支持后霜医,F(xiàn)eginclient中的方法就會被進(jìn)行一個管理了齿拂,一旦出現(xiàn)問題就會進(jìn)行默認(rèn)處理也就是fallback類的方法中的處理
注意:針對超時這塊,這里有兩個超時時間:一個是ribbon的超時時間肴敛,一個是hystrix的超時時間署海,熔斷的時間就是根據(jù)兩個時間中最小的超時時間來進(jìn)行的,及最短超時時間
- clent類
/**
* @Description:
* @author: dy
*/
//@FeignClient表明當(dāng)前類是一個feign客戶端医男,value指定該客戶端要請求的服務(wù)名稱(登記到注冊中心的服務(wù)提供者名稱) fallback指定回退類
@FeignClient(value = "user-service",path = UserClient.MAPPING ,fallback = UserFallback.class)
public interface UserClient {
String MAPPING = "/user-service";
@RequestMapping(value = "/get_user_id", method = RequestMethod.GET)
public String getUserId();
}
- 新建fallback方法
/**
* @Description: 降級回退邏輯定義一個類砸狞,實現(xiàn)Feign接口,實現(xiàn)其中的接口方法镀梭,返回默認(rèn)值
* @author: dy
*/
@Component
public class UserFallback implements UserClient {
@Override
public String getUserId() {
return "-1";
}
}
Feign對請求響應(yīng)壓縮的支持
feign支持對請求和響應(yīng)進(jìn)行GZIP壓縮刀森,以減少通信過程中的性能損耗,這里我們就不進(jìn)行過多介紹了报账。