高并發(fā)下就該使用非阻塞式方式接口調(diào)用提高系統(tǒng)整體性能
簡介
OpenFeign是Spring Cloud的一部分,它基于Feign實現(xiàn)了聲明式服務(wù)調(diào)用和負載均衡。以下是OpenFeign的一些主要特性:
- 支持SpringMVC的注解:OpenFeign整合了SpringMVC的注解,例如@RequestMapping,使得用戶可以直接在接口上使用這些注解,而無需編寫接口實現(xiàn)。
- 負載均衡:OpenFeign通過動態(tài)代理的方式生成實現(xiàn)類,這些實現(xiàn)類中包含了負載均衡的實現(xiàn),并可以調(diào)用其他服務(wù)。
- 聲明式服務(wù)調(diào)用:OpenFeign提供了一種聲明式的方式來訪問遠程服務(wù),這使得使用者可以像調(diào)用本地方法一樣來調(diào)用遠程服務(wù)。
- 可插拔的注解:OpenFeign提供了可插拔的注解支持,這意味著用戶可以根據(jù)自己的需要選擇不同的注解來使用。
- 異步通信:OpenFeign支持異步通信,這使得用戶可以更好地利用異步請求帶來的優(yōu)勢。
- 熔斷器:OpenFeign可以與resilience4j集成,支持熔斷器的功能,這可以在服務(wù)調(diào)用失敗時保護系統(tǒng),防止故障擴散。
- 服務(wù)發(fā)現(xiàn):OpenFeign可以與nacos, loadbalancer配合使用,支持服務(wù)發(fā)現(xiàn)的功能及負載均衡,這使得用戶可以更加方便地管理和調(diào)用遠程服務(wù)。
總的來說,OpenFeign是一個功能強大的聲明式服務(wù)調(diào)用和負載均衡工具,它可以提高服務(wù)調(diào)用的效率和靈活性,并可以幫助用戶更好地管理他們的分布式系統(tǒng)。
但是OpenFeign并不支持反應(yīng)式客戶端,如Spring WebClient,Spring Cloud OpenFeign也不支持。
feign-reactor是Spring Cloud的feign的擴展,它提供了對Reactor Netty的支持,可以更好地處理HTTP請求。具體來說,feign-reactor基于Reactor Netty實現(xiàn),它支持Reactive編程模型,可以更好地處理異步請求,并且可以更好地利用網(wǎng)絡(luò)資源。此外,feign-reactor還提供了一些其他的特性,例如:支持負載均衡、支持熔斷器、支持自定義請求和響應(yīng)等。
總的來說,feign-reactor可以提升feign在處理HTTP請求時的效率和靈活性。
使用上基本與openfeign一致,就是將相應(yīng)的注解換了相應(yīng)的名稱。
環(huán)境準備
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.playtika.reactivefeign</groupId>
<artifactId>feign-reactor-spring-configuration</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.playtika.reactivefeign</groupId>
<artifactId>feign-reactor-cloud</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.playtika.reactivefeign</groupId>
<artifactId>feign-reactor-webclient</artifactId>
<version>3.3.0</version>
</dependency>
feign-reactor-cloud依賴提供了CircuitBreaker + LoadBalancer的支持。
feign-reactor-webclient依賴提供了有關(guān)WebClient客戶端相關(guān)的實現(xiàn)及配置。
feign-reactor-spring-configuration依賴提供了Spring自動配置。
開啟反應(yīng)式客戶端
@SpringBootApplication
// 這里與openfeign就是名稱不一樣
@EnableReactiveFeignClients
public class SpringcloudFeignReactorApplication {
}
reactor feign接口定義
@ReactiveFeignClient(
// 目標地址
url = "http://localhost:8088/demos",
// 這里沒有走服務(wù)發(fā)現(xiàn)機制,隨意
name = "demoReactorFeign",
// 回退;當發(fā)生異?;虺瑫r調(diào)用,這里與openfeign一樣都需要實現(xiàn)當前feign接口
fallback = DemoReactorFeignFallback.class,
// 配置
configuration = {DemoReactorFeignConfig.class}
)
public interface DemoReactorFeign {
// 下面這個注解是feign的注解
// @RequestLine("GET /info/{id}")
// feign中@PathVariable => @Param
// 基于SpringMVC的注解
@GetMapping("/info/{id}")
public Mono<Object> info(@PathVariable("id") Integer id) ;
}
回退類定義
public class DemoReactorFeignFallback implements DemoReactorFeign {
@Override
public Mono<Object> info(Integer id) {
return Mono.just("請求失敗") ;
}
}
配置類
// 這里沒有添加@Configuration注解,不需要,不過添加了也可以,只是可能會出現(xiàn)問題
public class DemoReactorFeignConfig {
// 配置上面的回退類
@Bean
public DemoReactorFeignFallback demoReactorFeignFallback() {
return new DemoReactorFeignFallback() ;
}
}
以上對feign reactor的使用除了類不一樣外,其它都與openfeign是保持一致的。
測試接口
@RestController
@RequestMapping("/reactor")
public class DemoController {
@Resource
private DemoReactorFeign demoReactorFeign ;
@GetMapping("/{id}")
public Object info(@PathVariable("id") Integer id) {
return this.demoReactorFeign.info(id) ;
}
}
圖片
成功調(diào)用目標接口
超時支持
超時配置,我們只需要提供配置即可
reactive:
feign:
client:
config:
default:
options:
connectTimeoutMillis: 1000
readTimeoutMillis: 1000
以上是默認配置,對所有的接口都是一樣的超時時間。
由于目標接口模擬了耗時操作,所以調(diào)用了回退接口
為具體接口配置超時
reactive:
feign:
client:
config:
demoReactorFeign:
options:
connectTimeoutMillis: 2000
readTimeoutMillis: 2000
編程方式
也可以直接通過編程的方式
public class ProgramReactorFeignMain {
@Headers({ "Accept: application/json" })
static interface DemoReactorFeign {
@RequestLine("GET /info/{id}")
public Mono<Object> info(@Param("id") Integer id) ;
}
public static void main(String[] args) throws Exception {
DemoReactorFeign target =
WebReactiveFeign // WebClient based reactive feign
//JettyReactiveFeign // Jetty http client based
//Java11ReactiveFeign // Java 11 http client based
.<DemoReactorFeign>builder() // 指定方法返回值參數(shù)化類型
.target(DemoReactorFeign.class, "http://localhost:8088/demos") ;
target.info(6666).doOnNext(System.out::println).block() ;
}
}
完畢!??!