一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - spring webflux自定義netty 參數解析

spring webflux自定義netty 參數解析

2021-12-31 10:56IT_ZhiCunGaoYuan Java教程

這篇文章主要介紹了spring webflux自定義netty 參數解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

 

自定義 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;
    }
}

服務重啟時 報錯

SpringContextShutdownHook Socket couldn"t be stopped within 3000ms

 

解決方案

spring webflux自定義netty 參數解析

 

初識Spring WebFlux

在我的認識中,大部分人都在用SpringMVC(包括我自己)。在最近的學習中,發現spring5中有一個和SpringMVC平級的東西Spring WebFlux,接下來初步認識一下這是個什么東東?

 

Spring Web新的改變

眾所周知Spring MVC是同步阻塞的IO模型,當我們在處理一個耗時的任務時,如上傳文件,服務器的處理線程會一直處于等待狀態,等待文件的上傳,這期間什么也做不了,等到文件上傳完畢后可能需要寫入,寫入的過程線程又只能在那等待,非常浪費資源。為了避免這類資源的浪費,Spring WebFlux應運而生,在Spring WebFlux中若文件還沒上傳完畢,線程可以先去做其他事情,當文件上傳完畢后會通知線程,線程再來處理,后續寫入也是類似的,通過異步非阻塞機制節省了系統資源,極大的提高了系統的并發量。這兩種形式,是不是像極了BIO和NIO這兩種形式,實際上,SpringMVC和Spring WebFlux也就是這兩種IO特點的體現。

以下為官網的介紹:

spring webflux自定義netty 參數解析

 

Spring WebFlux的特性

 

1.異步非阻塞

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

 

2.響應式(reactive)編程

響應式編程是一種新的編程風格,其特點是異步和并發、事件驅動、推送PUSH機制一級觀察者模式的衍生。reactive引用允許開發者構建事件驅動,可擴展性,彈性的反應系統:提供高度敏感的實時用戶體驗感覺,可伸縮性和彈性的引用程序棧的支持,隨時可以部署在多核和云計算架構。

Reactive的主要接口:

  • Publisher:發布者,數據的生產端
  • Subscriber:消費者,此處可以定義獲取到數據后響應的操作
  • Processor:消費者與發布者之間的數據處理
  • back pressure:背壓,消費者告訴發布者自己能處理多少數據

消費者的回調方法:

  • onSubscribe:訂閱關系處理,用它來響應發布者
  • onNext:接收到數據后會響應的方法
  • onError:出現錯誤時處理的方法
  • onComplete:任務完成后響應的方法

 

3.適配多種web容器

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

 

Spring WebFlux簡單實踐

本文默認開發環境是JDK8,開發工具是IDEA。實踐分兩部分內容,第一部分與SpringMVC對比開發中的不一樣的地方;第二部分為Spring WebFlux獨有的響應式編程的簡單實踐。

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

 

1.工程創建

新建springboot工程。

選擇Web -> Spring Reactive Web 創建

spring webflux自定義netty 參數解析

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

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

 

2.Controller中與SpringMVC的對比

在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.異步非阻塞的體現

上面已經實現了初步的數據返回,不過webflux和springmvc目前來看沒有什么區別,已知springmvc線程執行時會阻塞的,webflux線程是異步非阻塞的。下面修改一下代碼,在獲取數據的時候加一些額外的耗時操作,看看webflux是否是真的異步非阻塞

@RestController
@Slf4j
@AllArgsConstructor
public class UserController {
    /**
     *  模擬耗時查詢操作
     */
    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;
    }
}

通過日志結果,可以很明顯的發現,雖然前端頁面展示的效果是一樣的,但springmvc是等待后返回結果;而webflux是先執行,等有結果后,再返回結果。由此體現了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.添加數據庫支持

對于數據庫的支持,webflux用到的是r2dbc這樣一個東西。

R2DBC(Reactive Relational Database Connectivity)是一個使用反應式驅動集成關系數據庫的孵化器。Spring Data R2DBC運用熟悉的Spring抽象和repository 支持R2DBC。基于此,在響應式程序棧上使用關系數據訪問技術,構建由Spring驅動的程序將變得非常簡單。

在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中加入數據源:

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

 

5.Dao的編寫

Dao的編寫和springmvc中類似,本文中繼承了ReactiveCrudRepository類,是Repository的一個實現類,其中實現了簡單的crud操作,model和dao的實現:

@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.響應式編程Handler的編寫

在使用上,webflux可以和springmvc類似,不過webflux也有自己的一套響應式編程的寫法,先定義handler,類似于controller,不過只有業務處理的代碼,其中就用到了reactive模擬的request(ServerRequest )和response(ServerResponse),同樣的實現簡單的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.響應式編程Route的編寫

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

學習過vue的老鐵們應該知道,vue是通過路由定義地址和頁面的對應關系的,vue也是響應式編程的一種體現。webflux中也是通過類似的方式來實現的,在Route中定義規則:

@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);
    }
}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/IT_liuzhiyuan/article/details/105871279

延伸 · 閱讀

精彩推薦
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
主站蜘蛛池模板: 国产综合视频在线 | 无码精品AV久久久奶水 | 日日摸日日添日日透 | 亚洲10p | 从后面撕开老师的丝袜动态图 | 午夜在线观看免费观看 视频 | 免费观看俄罗斯特黄特色 | x8x8在线观看免费 | 91精品国产高清久久久久久io | kayden·kross hd在线 | 欧美一区不卡二区不卡三区 | gogort人体的最新网站 | 五月天婷婷精品免费视频 | 欧美乱强 | 成人网18免费网 | h动态图男女啪啪27报 | 我的家教老师在线观看 | 欧美日韩一区二区中文字幕视频 | 日韩欧美中文字幕出 | 7777色鬼xxxx欧美色夫 | 狠狠搞视频 | 91大神亚洲影视在线 | 国产精品一在线观看 | 午夜一级毛片看看 | 亚洲国产精品ⅴa在线观看 亚洲国产高清一区二区三区 | 99热这里只有精品在线观看 | 欧美添下面视频免费观看 | 短篇艳妇系列 | 插鸡小说| 天堂在线国产 | 日韩高清在线高清免费 | 色婷婷影院在线视频免费播放 | 武侠艳妇屈辱的张开双腿 | 日本老熟老太hd | 希望影院高清免费观看视频 | 日韩精品视频在线观看免费 | 教室眠催白丝美女校花 | 热99re久久精品精品免费 | 2022天堂岛日产 | 明星ai智能人脸替换造梦在线播放 | 亚洲精品国产一区二区在线 |