文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何分析springboot响应式编程整合webFlux的问题

2023-06-29 00:38

关注

这期内容当中小编将会给大家带来有关如何分析springboot响应式编程整合webFlux的问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

在servlet3.0标准之前,是每一个请求对应一个线程。如果此时一个线程出现了高延迟,就会产生阻塞问题,从而导致整个服务出现严重的性能情况,因为一旦要调用第三方接口,就有可能出现这样的操作了。早期的处理方式只能是手工控制线程。

在servlet3.0标准之后,为了解决此类问题,所以提供了异步响应的支持。在异步响应处理结构中,可以将耗时操作的部分交由一个专属的异步线程进行响应处理,同时请求的线程资源将被释放,并将该线程返回到线程池中,以供其他用户使用,这样的操作机制将极大的提升程序的并发性能。

对于以上给出的响应式编程支持,仅仅是一些原生的支持模式,而现在既然基于springboot程序开发,那么就需要考虑一些更简单的整合。

而在spring中实现响应式编程,那么则需要使用到spring webFlux,该组件是一个重新构建的且基于Reactive Streams标准实现的异步非阻塞Web开发框架,以Reactor开发框架为基础,可以更加容易实现高并发访问下的请求处理模型。在springboot2.x版本中提供了webFlux依赖模块,该模块有两种模型实现:一种是基于功能性端点的方式,另一种是基于SpringMVC注解方式。

 Maven引入

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

整合处理器:

package com.example.oldguy.myWebFlux.handler; import com.example.oldguy.myVo.Message;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import reactor.core.publisher.Mono;@Component@Slf4jpublic class MessageHandler {    public Mono<Message> echoHandler(Message message){        log.info("【{}】业务层接收处理数据:{}",Thread.currentThread().getName());        message.setTitle("【】"+Thread.currentThread().getName()+"】"+message.getTitle());        message.setContent("【】"+Thread.currentThread().getName()+"】"+message.getContent());        return Mono.create(item->item.success(message)); //实现数据响应    }}

整合控制器:

package com.example.oldguy.myController; import com.example.oldguy.myVo.Message;import com.example.oldguy.myWebFlux.handler.MessageHandler;import com.example.oldguy.mytask.MyThreadTask;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.InitBinder;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import org.springframework.web.context.request.async.DeferredResult;import javax.servlet.http.HttpServletRequest;import java.beans.PropertyEditorSupport;import java.time.Instant;import java.time.LocalDate;import java.time.ZoneId;import java.time.format.DateTimeFormatter;import java.util.Date;import java.util.concurrent.TimeUnit;@RestController@RequestMapping("/message    private static final DateTimeFormatter LOCAL_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");    @InitBinder    public void initBinder(WebDataBinder binder){        binder.registerCustomEditor(Date.class,new PropertyEditorSupport(){            @Override            public void setAsText(String text) throws IllegalArgumentException {                LocalDate localDate = LocalDate.parse(text,LOCAL_DATE_FORMAT);                Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();                super.setValue(Date.from(instant));            }        });    }    @GetMapping("runnable")    @ApiOperation("异常处理Runnable")    public Object message(String message) {        log.info("外部线程:{}", Thread.currentThread().getName());        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();        DeferredResult<String> result = new DeferredResult<>(6000L); //设置异步响应        this.threadPoolTaskExecutor.execute(new Runnable() { //线程核心任务            @SneakyThrows            public void run() {                log.info("内部线程:{}",Thread.currentThread().getName());                TimeUnit.SECONDS.sleep(7);                result.setResult("[echo]"+message); //执行最终的响应        result.onCompletion(new Runnable() { //完成处理线程                log.info("完成线程:{}",Thread.currentThread().getName()); //日志输出        result.onTimeout(new Runnable() {                log.info("超时线程:{}",Thread.currentThread().getName());                result.setResult("【请求超时】"+request.getRequestURI()); //超时路径        return  result;    @GetMapping("task")    @ApiOperation("task异步任务开启")    public Object messageTask(String message){        log.info("外部线程{}",Thread.currentThread().getName());        this.task.startTaskHander();        return "【echo】"+message;    @GetMapping("webflux")    @ApiOperation("整合webflux")    public Object echo(Message message){        log.info("接收用户信息,用户方发送的参数为message={}",message);        return this.messageHandler.echoHandler(message);}

页面响应:

如何分析springboot响应式编程整合webFlux的问题

控制台响应:

2021-11-30 15:04:06.946  INFO 22884 --- [nio-1999-exec-1] c.e.oldguy.myController.AsyncController  : 接收用户信息,用户方发送的参数为message=Message(title=pansd, pubdate=Tue Nov 30 00:00:00 CST 2021, content=come on baby)
2021-11-30 15:04:06.947  INFO 22884 --- [nio-1999-exec-1] c.e.o.myWebFlux.handler.MessageHandler   : 【http-nio-1999-exec-1】业务层接收处理数据:Message(title=pansd, pubdate=Tue Nov 30 00:00:00 CST 2021, content=come on baby)

 webFlux响应map和List

//webFlux响应集合    public Flux<Message> list(Message message){        List<Message> messageList = new ArrayList<>();        for(int i=0;i<10;i++){            Message m = new Message();            m.setTitle(i+"--"+message.getTitle());            m.setContent(i+"--"+message.getContent());            m.setPubdate(message.getPubdate());            messageList.add(m);        }        return Flux.fromIterable(messageList);    }    public Flux<Map.Entry<String,Message>> map(Message message){        Map<String,Message> map = new HashMap<>();        for(int i=0;i<10;i++){            Message m = new Message();            m.setTitle(i+"--"+message.getTitle());            m.setContent(i+"--"+message.getContent());            m.setPubdate(message.getPubdate());            map.put("pansd-"+i,m);        }//        Set<Map.Entry<String, Message>> entries = map.entrySet();        return Flux.fromIterable(map.entrySet());    }
@GetMapping("webfluxList")@ApiOperation("整合webfluxList")public Object echoList(Message message){    log.info("接收用户信息,用户方发送的参数为message={}",message);    return this.messageHandler.list(message);} @GetMapping("webfluxMap")@ApiOperation("整合webfluxMap")public Object echoMap(Message message){    log.info("接收用户信息,用户方发送的参数为message={}",message);    return this.messageHandler.map(message);}

上述就是小编为大家分享的如何分析springboot响应式编程整合webFlux的问题了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯