Spring - WebFlux

传统的Web框架,struts2,springmvc等都是基于Servlet API与Servlet容器基础之上运行的,在Servlet3.1之后才有了异步非阻塞的支持。而WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器上,因此它的运行环境的可选择行要比传统web框架多的多。

  • 同步servlet阻塞了什么?

它阻塞了tomcat容器的servlet线程。当网络请求发送到tomcat容器之后,tomcat容器会给每个请求启动一个线程,线程里会调用响应的servlet来处理。此时你的业务耗时多久,这个线程就要等多久,很多个请求就会阻塞。

  • 为什么要使用异步servlet?

如上,使用异步servlet可以提升更大的并发量,达到程序垂直扩展在水平扩展。垂直扩展就是指在我们代码能力范围内的瓶颈,水平扩展就比如加服务器,升配置等等。

webflux开发

创建一个springboot项目,勾选Reactive Web,不要勾选以前使用的Web Starter,我使用的软件idea,jdk是11,eclipse也是勾这两个。还是用了lombok,软件需要装一下这个插件。
在这里插入图片描述
创建完项目,pom自动加入依赖:
在这里插入图片描述

@RestController
public class OldController {
    /**
     * 常规写法
     *
     * @return
     */
    @GetMapping("/old")
    public Map<String, Object> old() {
        return new HashMap<String, Object>() {{
            put("username", "赵山河");
            put("age", "30");
            put("sex", "男");
        }};
    }

    /**
     * Mono 返回0-1个元素
     * @return
     */
    @GetMapping("/mono")
    public Mono<Map<String, Object>> mono() {
        return Mono.just(new HashMap<String, Object>() {{
            put("username", "赵山河");
            put("age", "30");
            put("sex", "男");
        }});
    }

    /**
     * Flux - 返回0-N个元素
     * @return
     */
    @GetMapping(value = "/flux" , produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> flux() {
        Flux<String> result = Flux.fromStream(IntStream.range(1,5).mapToObj(s -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "flux--" + s;
        }));
        return result;
    }
以上一个常规写法和webflux写法,区别在于阻塞和非阻塞,假设controller里有耗时操作,那么常规写法是耗时多久,这个线程就占用多久,而webflux写法会采用异步的响应式的方式来处理,则不会一直占用该线程。而Flux是返回多次数据。
  • SSE - Server sent Event

严格地说,HTTP协议无法做到服务器主动推送信息。但是,有一种变通方法,就是服务器向客户端声明,接下来要发送的是流信息(streaming)。
也就是说,发送的不是一次性的数据包,而是一个数据流,会连续不断地发送过来。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。本质上,这种通信就是以流信息的方式,完成一次用时很长的下载。
SSE就是利用这种机制,使用流信息向浏览器推送信息。它基于 HTTP 协议,目前除了 IE/Edge,其他浏览器都支持。Flux就是这个样子,getMapping里的produces属性指定了返回的是一个数据流,MediaType.TEXT_EVENT_STREAM_VALUE是它提供的枚举。

完整实例

操作MongoDB依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>

添加MongoDB相关注解

import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;

@EnableReactiveMongoRepositories

实体类相关注解

import org.springframework.data.mongodb.core.mapping.Document;

//指定在mongodb中的集合名
@Document(collection = "user")
@Data
public class User {
    @Id
    private String id;

    private String name;

    private int age;
}

定义仓库

import org.springframework.data.mongodb.repository.ReactiveMongoRepository;

//User实体类,String是Id主键的类型
@Repository
public interface UserRepository extends ReactiveMongoRepository<User,String> {
}

controller

@RestController
@RequestMapping("/user")
public class UserController {

    //使用构造函数注入
    private final UserRepository repository;

    public UserController(UserRepository repository){
        this.repository = repository;
    }

    //全部返回
    @GetMapping("/all")
    public Flux<User> getAll(){
        return repository.findAll();
    }

    //流方式返回
    @GetMapping(value = "/stream/all",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> streamGetAll(){
        return repository.findAll();
    }

}

开启MongoDB服务,配置application文件

spring.data.mongodb.uri=mongodb://localhost:27017/webflux

使用Restlet Client插件:

进去搜Restlet下载,进不去需要安装谷歌访问助手
http://chromecj.com

启动项目,进行测试。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值