webfulx 內部使用的是響應式編程(Reactive Programming),以 Reactor 庫爲基礎, 基於異步和事件驅動,可以讓我們在不擴充硬件資源的前提下,提升系統的吞吐量和伸縮性。
我翻了無論官方的案例,文檔,已經網上資料
都是用的默認的http請求線程池作爲工作線程,我的默認是8個。
也就是當8個請求同時來的時候就堵塞了,下一個http請求就進不來了。我一直沒搞懂所謂的異步回調到底是怎麼用。
用我淺薄的認知,我理解的應該請求過來都是無堵塞的,然後工作線程異步執行完之後回調http響應。無論工作線程需要花多久時間,請求按理說都先被接受。
相信像我一樣新萌玩家都先用 官方的案例 https://github.com/spring-projects/spring-boot/tree/2.1.x/spring-boot-samples/spring-boot-sample-webflux/src/main/java/sample/webflux。
比如這樣:
@GetMapping("/")
public String welcome() {
return "Hello World";
}
@GetMapping("/")
public Mono<String> getUser() {
return Mono.just("開源中國-王念博客");
}
@GetMapping("/")
public Mono<String> getUser() {
return Mono.just(userService.getUser());
}
@Bean
public RouterFunction<ServerResponse> monoRouterFunction(EchoHandler echoHandler) {
return route(POST("/echo"), echoHandler::echo);
}
這些寫法不上生產,本地調試調試,以爲就已經響應式了。
剛開始發現線程池就8個時候,我就採用了一個卑鄙無恥的方式,配置100個,同學們你們覺得我做的對嗎?
public static void main(String[] args) {
System.setProperty("reactor.netty.ioWorkerCount", "100");
SpringApplication.run(CtmsDataProcessApplication.class, args);
}
我廢話真多,迴歸正題,我剛研究了一下發現貌似找到了一個對的方式。
@RequestMapping("/")
public Mono aaa(String abc) throws InterruptedException {
logger.info("請求線程,非堵塞,看線程名:調用/方法");
return Mono.create(new Consumer<MonoSink<Object>>() {
@Override
public void accept(MonoSink<Object> stringMonoSink) {
new Thread(new Runnable() {
@Override
public void run() {
logger.info("異步線程");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//關鍵就在這裏,只要在請求時的這個MonoSink裏,無論是哪個線程裏設置這個值就可以了
stringMonoSink.success(abc);
}
}).start();
}
});
}
上面我爲了測試 new Thread,這個線程就是工作線程,這樣就容易理解了,不過這裏推薦使用 jdk1.8新特性 CompletableFuture 來實現。
到現在也不知道用法對不對,如果有不對的老哥,看到了給小弟留個言。