最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring webflux自定義netty 參數(shù)解析

 更新時(shí)間:2021年09月14日 11:18:51   作者:IT_ZhiCunGaoYuan  
這篇文章主要介紹了spring webflux自定義netty 參數(shù)解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

自定義 webflux 容器配置

配置代碼

@Component
public class ContainerConfig extends ReactiveWebServerFactoryCustomizer {
    public ContainerConfig(ServerProperties serverProperties) {
        super(serverProperties);
    }
    @Override
    public void customize(ConfigurableReactiveWebServerFactory factory) {
        super.customize(factory);
        NettyReactiveWebServerFactory nettyFactory = (NettyReactiveWebServerFactory) factory;
        nettyFactory.setResourceFactory(null);
        nettyFactory.addServerCustomizers(server ->
                server.tcpConfiguration(tcpServer ->
                        tcpServer.runOn(LoopResources.create("mfilesvc", Runtime.getRuntime().availableProcessors() * 4, Runtime.getRuntime().availableProcessors() * 8, true))
                                .selectorOption(CONNECT_TIMEOUT_MILLIS, 200)
                ).channelGroup(new ChannelGroup())
        );     
    }
    @Override
    public int getOrder() {
        return -10;
    }
}

服務(wù)重啟時(shí) 報(bào)錯(cuò)

SpringContextShutdownHook Socket couldn't be stopped within 3000ms

解決方案

初識(shí)Spring WebFlux

在我的認(rèn)識(shí)中,大部分人都在用SpringMVC(包括我自己)。在最近的學(xué)習(xí)中,發(fā)現(xiàn)spring5中有一個(gè)和SpringMVC平級(jí)的東西Spring WebFlux,接下來初步認(rèn)識(shí)一下這是個(gè)什么東東?

Spring Web新的改變

眾所周知Spring MVC是同步阻塞的IO模型,當(dāng)我們?cè)谔幚硪粋€(gè)耗時(shí)的任務(wù)時(shí),如上傳文件,服務(wù)器的處理線程會(huì)一直處于等待狀態(tài),等待文件的上傳,這期間什么也做不了,等到文件上傳完畢后可能需要寫入,寫入的過程線程又只能在那等待,非常浪費(fèi)資源。為了避免這類資源的浪費(fèi),Spring WebFlux應(yīng)運(yùn)而生,在Spring WebFlux中若文件還沒上傳完畢,線程可以先去做其他事情,當(dāng)文件上傳完畢后會(huì)通知線程,線程再來處理,后續(xù)寫入也是類似的,通過異步非阻塞機(jī)制節(jié)省了系統(tǒng)資源,極大的提高了系統(tǒng)的并發(fā)量。這兩種形式,是不是像極了BIO和NIO這兩種形式,實(shí)際上,SpringMVC和Spring WebFlux也就是這兩種IO特點(diǎn)的體現(xiàn)。

以下為官網(wǎng)的介紹:

在這里插入圖片描述

Spring WebFlux的特性

1.異步非阻塞

如上文所說,線程不需要一直處于等待狀態(tài),Spring WebFlux很好的體現(xiàn)了NIO的異步非阻塞思想。

2.響應(yīng)式(reactive)編程

響應(yīng)式編程是一種新的編程風(fēng)格,其特點(diǎn)是異步和并發(fā)、事件驅(qū)動(dòng)、推送PUSH機(jī)制一級(jí)觀察者模式的衍生。reactive引用允許開發(fā)者構(gòu)建事件驅(qū)動(dòng),可擴(kuò)展性,彈性的反應(yīng)系統(tǒng):提供高度敏感的實(shí)時(shí)用戶體驗(yàn)感覺,可伸縮性和彈性的引用程序棧的支持,隨時(shí)可以部署在多核和云計(jì)算架構(gòu)。

Reactive的主要接口:

  • Publisher:發(fā)布者,數(shù)據(jù)的生產(chǎn)端
  • Subscriber:消費(fèi)者,此處可以定義獲取到數(shù)據(jù)后響應(yīng)的操作
  • Processor:消費(fèi)者與發(fā)布者之間的數(shù)據(jù)處理
  • back pressure:背壓,消費(fèi)者告訴發(fā)布者自己能處理多少數(shù)據(jù)

消費(fèi)者的回調(diào)方法:

  • onSubscribe:訂閱關(guān)系處理,用它來響應(yīng)發(fā)布者
  • onNext:接收到數(shù)據(jù)后會(huì)響應(yīng)的方法
  • onError:出現(xiàn)錯(cuò)誤時(shí)處理的方法
  • onComplete:任務(wù)完成后響應(yīng)的方法

3.適配多種web容器

既然Spring WebFlux很好的體現(xiàn)了NIO的異步非阻塞思想。作為首屈一指的NIO框架netty,便是Spring WebFlux默認(rèn)的運(yùn)行容器。此外,大家熟悉的Tomcat、Jetty等Servlet容器,也能運(yùn)行Spring WebFlux,前提是容器需要支持Servlet3.1,因?yàn)榉亲枞鸌O是使用了Servlet3.1的特性。

Spring WebFlux簡單實(shí)踐

本文默認(rèn)開發(fā)環(huán)境是JDK8,開發(fā)工具是IDEA。實(shí)踐分兩部分內(nèi)容,第一部分與SpringMVC對(duì)比開發(fā)中的不一樣的地方;第二部分為Spring WebFlux獨(dú)有的響應(yīng)式編程的簡單實(shí)踐。

在webflux中,Mono代表返回0或1個(gè)元素(相當(dāng)于一個(gè)對(duì)象)。Flux代表返回0-n個(gè)元素(相當(dāng)于集合)

1.工程創(chuàng)建

新建springboot工程。

選擇Web -> Spring Reactive Web 創(chuàng)建

在這里插入圖片描述

或者在springboot工程中pom文件添加依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

2.Controller中與SpringMVC的對(duì)比

在controller中,webflux的寫法可以和springMVC的寫法類似

@RestController
@Slf4j
public class UserController {
    @RequestMapping("/index")
    public String index(){
        log.info("springmvc index begin");
        String result="cc666";
        log.info("springmvc index end");
        return result;
    }
    @RequestMapping("/index2")
    public Mono<String> index2(){
        log.info("webflux index begin");
        Mono<String> result=Mono.just("666cc");
        log.info("webflux index end");
        return result;
    }
}

3.異步非阻塞的體現(xiàn)

上面已經(jīng)實(shí)現(xiàn)了初步的數(shù)據(jù)返回,不過webflux和springmvc目前來看沒有什么區(qū)別,已知springmvc線程執(zhí)行時(shí)會(huì)阻塞的,webflux線程是異步非阻塞的。下面修改一下代碼,在獲取數(shù)據(jù)的時(shí)候加一些額外的耗時(shí)操作,看看webflux是否是真的異步非阻塞

@RestController
@Slf4j
@AllArgsConstructor
public class UserController {
    /**
     *  模擬耗時(shí)查詢操作
     */
    public String createStr(){
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "cc666cc";
    }
    @RequestMapping("/index")
    public String index(){
        log.info("springmvc index begin");
        String result=this.createStr();
        log.info("springmvc index end");
        return result;
    }
    @RequestMapping("/index2")
    public Mono<String> index2(){
        log.info("webflux index begin");
        Mono<String> result=Mono.fromSupplier(()->this.createStr());
        log.info("webflux index end");
        return result;
    }
}

通過日志結(jié)果,可以很明顯的發(fā)現(xiàn),雖然前端頁面展示的效果是一樣的,但springmvc是等待后返回結(jié)果;而webflux是先執(zhí)行,等有結(jié)果后,再返回結(jié)果。由此體現(xiàn)了webflux異步非阻塞的特性

springmvc
2020-08-04 21:28:57.430  INFO 14156 --- [ctor-http-nio-2] c.w.webflux.controller.UserController    : springmvc index begin
2020-08-04 21:29:00.430  INFO 14156 --- [ctor-http-nio-2] c.w.webflux.controller.UserController    : springmvc index end
webflux
2020-08-04 21:29:09.640  INFO 14156 --- [ctor-http-nio-2] c.w.webflux.controller.UserController    : webflux index begin
2020-08-04 21:29:09.641  INFO 14156 --- [ctor-http-nio-2] c.w.webflux.controller.UserController    : webflux index end

4.添加數(shù)據(jù)庫支持

對(duì)于數(shù)據(jù)庫的支持,webflux用到的是r2dbc這樣一個(gè)東西。

R2DBC(Reactive Relational Database Connectivity)是一個(gè)使用反應(yīng)式驅(qū)動(dòng)集成關(guān)系數(shù)據(jù)庫的孵化器。Spring Data R2DBC運(yùn)用熟悉的Spring抽象和repository 支持R2DBC?;诖?,在響應(yīng)式程序棧上使用關(guān)系數(shù)據(jù)訪問技術(shù),構(gòu)建由Spring驅(qū)動(dòng)的程序?qū)⒆兊梅浅:唵巍?/p>

在pom中引入依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
    <groupId>com.github.jasync-sql</groupId>
    <artifactId>jasync-r2dbc-mysql</artifactId>
    <version>1.1.3</version>
</dependency>

在application.yml中加入數(shù)據(jù)源:

spring:
  r2dbc:
    url: r2dbc:mysql://127.0.0.1:3306/study
    username: xxx
    password: xxx

5.Dao的編寫

Dao的編寫和springmvc中類似,本文中繼承了ReactiveCrudRepository類,是Repository的一個(gè)實(shí)現(xiàn)類,其中實(shí)現(xiàn)了簡單的crud操作,model和dao的實(shí)現(xiàn):

@Table("user")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @Id
    private Long id;
    private String username;
    private String password;
}
public interface UserDao extends ReactiveCrudRepository<User,Long> {
}

6.Controller的編寫

controller的編寫還是和springmvc類似,這里采用RESTful的方式

@RestController
@AllArgsConstructor
public class UserController {
    private final UserDao userDao;
    @GetMapping("/findAll")
    public Flux<User> findAll(){
        return userDao.findAll();
    }
    @PostMapping("/save")
    public Mono save(@RequestBody User user){
        return this.userDao.save(user);
    }
    @DeleteMapping("/delete/{id}")
    public Mono delete(@PathVariable Long id){
        return this.userDao.deleteById(id);
    }
    @GetMapping("/get/{id}")
    public Mono get(@PathVariable Long id){
        return this.userDao.findById(id);
    }
}

7.響應(yīng)式編程Handler的編寫

在使用上,webflux可以和springmvc類似,不過webflux也有自己的一套響應(yīng)式編程的寫法,先定義handler,類似于controller,不過只有業(yè)務(wù)處理的代碼,其中就用到了reactive模擬的request(ServerRequest )和response(ServerResponse),同樣的實(shí)現(xiàn)簡單的crud功能:

@Component
@AllArgsConstructor
public class UserHandler {
    private final UserDao userDao;
    public Mono<ServerResponse> saveUser(ServerRequest request){
        Mono<User> mono=request.bodyToMono(User.class);
        User user = mono.block();
        return ServerResponse.ok().build(this.userDao.save(user).then());
    }
    public Mono<ServerResponse> deleteById(ServerRequest request){
        Long id=Long.parseLong(request.pathVariable("id"));
        return ServerResponse.ok().build(this.userDao.deleteById(id).then());
    }
    public Mono<ServerResponse> getByid(ServerRequest request){
        Long id=Long.parseLong(request.pathVariable("id"));
        Mono<User> mono = this.userDao.findById(id);
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(mono,User.class);
    }
    public Mono<ServerResponse> findAll(ServerRequest request){
        Flux<User> all = this.userDao.findAll();
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(all,User.class);
    }
}

8.響應(yīng)式編程Route的編寫

在handler中我們編寫了處理代碼,但是怎么通過請(qǐng)求地址訪問呢?

學(xué)習(xí)過vue的老鐵們應(yīng)該知道,vue是通過路由定義地址和頁面的對(duì)應(yīng)關(guān)系的,vue也是響應(yīng)式編程的一種體現(xiàn)。webflux中也是通過類似的方式來實(shí)現(xiàn)的,在Route中定義規(guī)則:

@Configuration
public class UserRoute {
    @Bean
    public RouterFunction<ServerResponse> routeUser(UserHandler userHandler){
        return RouterFunctions
                .route(RequestPredicates.GET("findAll2")
                        .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),userHandler::findAll)
                .andRoute(RequestPredicates.GET("/get2/{id}")
                        .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),userHandler::getByid)
                .andRoute(RequestPredicates.DELETE("/delete2/{id}")
                        .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),userHandler::deleteById)
                .andRoute(RequestPredicates.POST("/save2")
                        .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),userHandler::saveUser);
    }
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot整合xxl-job的示例代碼

    springboot整合xxl-job的示例代碼

    這篇文章主要介紹了springboot整合xxl-job的示例代碼,主要分為三大模塊,分別是調(diào)度中心、執(zhí)行器和配置定時(shí)任務(wù)的過程,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Spring 跨域配置請(qǐng)求詳解

    Spring 跨域配置請(qǐng)求詳解

    這篇文章主要介紹了Spring 跨域配置請(qǐng)求詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Springboot快速集成sse服務(wù)端推流(最新整理)

    Springboot快速集成sse服務(wù)端推流(最新整理)

    SSE?Server-Sent?Events是一種允許服務(wù)器向客戶端推送實(shí)時(shí)數(shù)據(jù)的技術(shù),它建立在?HTTP?和簡單文本格式之上,提供了一種輕量級(jí)的服務(wù)器推送方式,通常也被稱為“事件流”(Event?Stream),這篇文章主要介紹了Springboot快速集成sse服務(wù)端推流(最新整理),需要的朋友可以參考下
    2024-02-02
  • Java String的intern用法解析

    Java String的intern用法解析

    這篇文章主要介紹了Java String的intern用法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 詳解java JDK 動(dòng)態(tài)代理類分析(java.lang.reflect.Proxy)

    詳解java JDK 動(dòng)態(tài)代理類分析(java.lang.reflect.Proxy)

    這篇文章主要介紹了詳解java JDK 動(dòng)態(tài)代理類分析(java.lang.reflect.Proxy)的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • java反射機(jī)制最詳解

    java反射機(jī)制最詳解

    這篇文章主要介紹了Java 反射機(jī)制原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了Java反射機(jī)制的相關(guān)概念、原理、基本使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2021-08-08
  • 詳談Java中instanceof和isInstance的區(qū)別

    詳談Java中instanceof和isInstance的區(qū)別

    下面小編就為大家?guī)硪黄斦凧ava中instanceof和isInstance的區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • Java實(shí)現(xiàn)大文件的切割與合并操作示例

    Java實(shí)現(xiàn)大文件的切割與合并操作示例

    這篇文章主要介紹了Java實(shí)現(xiàn)大文件的切割與合并操作,結(jié)合實(shí)例形式分析了java基于io及util操作大文件按指定個(gè)數(shù)分割與合并相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • 解決java調(diào)用python代碼返回值中文亂碼問題

    解決java調(diào)用python代碼返回值中文亂碼問題

    這篇文章主要介紹了解決java調(diào)用python代碼返回值中文亂碼問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java 實(shí)戰(zhàn)練手項(xiàng)目之酒店管理系統(tǒng)的實(shí)現(xiàn)流程

    Java 實(shí)戰(zhàn)練手項(xiàng)目之酒店管理系統(tǒng)的實(shí)現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)一個(gè)酒店管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-11-11

最新評(píng)論

天门市| 阜康市| 沂源县| 昌宁县| 吴桥县| 武鸣县| 大庆市| 清苑县| 台前县| 来安县| 屏东市| 远安县| 苗栗市| 石门县| 积石山| 砀山县| 伊吾县| 增城市| 新建县| 汝南县| 衡东县| 宜兰县| 景洪市| 禹城市| 浦北县| 株洲县| 曲水县| 宜良县| 沁阳市| 乾安县| 涿州市| 乌鲁木齐市| 长子县| 海阳市| 尼勒克县| 大名县| 乌鲁木齐县| 胶州市| 开封市| 于田县| 河津市|