如何分析springboot响应式编程整合webFlux的问题
导读:本文共4193.5字符,通常情况下阅读需要14分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 在servlet3.0标准之前,是每一个请求对应一个线程。如果此时一个线程出现了高延迟,就会产生阻塞问题,从而导致整个服务出现严重的性能情况,因为一旦要调用第三方接口,就有可能出现这样的操作了。早期的处理方式只能是手工控制线程。在servlet3.0标准之后,为了解决此类问题,所以提供了异步响应的支持。在异步响应处理结构中,可以将耗时操作的部分交由一个专属的异步... ...
目录
(为您整理了一些要点),点击可以直达。在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>
整合处理器:
packagecom.example.oldguy.myWebFlux.handler;importcom.example.oldguy.myVo.Message;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Component;importreactor.core.publisher.Mono;@Component@Slf4jpublicclassMessageHandler{publicMono<Message>echoHandler(Messagemessage){log.info("【{}】业务层接收处理数据:{}",Thread.currentThread().getName());message.setTitle("【】"+Thread.currentThread().getName()+"】"+message.getTitle());message.setContent("【】"+Thread.currentThread().getName()+"】"+message.getContent());returnMono.create(item->item.success(message));//实现数据响应}}
整合控制器:
packagecom.example.oldguy.myController;importcom.example.oldguy.myVo.Message;importcom.example.oldguy.myWebFlux.handler.MessageHandler;importcom.example.oldguy.mytask.MyThreadTask;importio.swagger.annotations.Api;importio.swagger.annotations.ApiOperation;importlombok.SneakyThrows;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;importorg.springframework.web.bind.WebDataBinder;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.InitBinder;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importorg.springframework.web.context.request.async.DeferredResult;importjavax.servlet.http.HttpServletRequest;importjava.beans.PropertyEditorSupport;importjava.time.Instant;importjava.time.LocalDate;importjava.time.ZoneId;importjava.time.format.DateTimeFormatter;importjava.util.Date;importjava.util.concurrent.TimeUnit;/***异步线程的处理机制*/@RestController@RequestMapping("/message/*")@Slf4j@Api(tags="异步处理")publicclassAsyncController{@AutowiredprivateThreadPoolTaskExecutorthreadPoolTaskExecutor;privateMyThreadTasktask;privateMessageHandlermessageHandler;/***日期转换*@param*@return*/privatestaticfinalDateTimeFormatterLOCAL_DATE_FORMAT=DateTimeFormatter.ofPattern("yyyy-MM-dd");@InitBinderpublicvoidinitBinder(WebDataBinderbinder){binder.registerCustomEditor(Date.class,newPropertyEditorSupport(){@OverridepublicvoidsetAsText(Stringtext)throwsIllegalArgumentException{LocalDatelocalDate=LocalDate.parse(text,LOCAL_DATE_FORMAT);Instantinstant=localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();super.setValue(Date.from(instant));}});}@GetMapping("runnable")@ApiOperation("异常处理Runnable")publicObjectmessage(Stringmessage){log.info("外部线程:{}",Thread.currentThread().getName());HttpServletRequestrequest=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();DeferredResult<String>result=newDeferredResult<>(6000L);//设置异步响应this.threadPoolTaskExecutor.execute(newRunnable(){//线程核心任务@SneakyThrowspublicvoidrun(){log.info("内部线程:{}",Thread.currentThread().getName());TimeUnit.SECONDS.sleep(7);result.setResult("[echo]"+message);//执行最终的响应result.onCompletion(newRunnable(){//完成处理线程log.info("完成线程:{}",Thread.currentThread().getName());//日志输出result.onTimeout(newRunnable(){log.info("超时线程:{}",Thread.currentThread().getName());result.setResult("【请求超时】"+request.getRequestURI());//超时路径returnresult;@GetMapping("task")@ApiOperation("task异步任务开启")publicObjectmessageTask(Stringmessage){log.info("外部线程{}",Thread.currentThread().getName());this.task.startTaskHander();return"【echo】"+message;@GetMapping("webflux")@ApiOperation("整合webflux")publicObjectecho(Messagemessage){log.info("接收用户信息,用户方发送的参数为message={}",message);returnthis.messageHandler.echoHandler(message);}
页面响应:
控制台响应:
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响应集合publicFlux<Message>list(Messagemessage){List<Message>messageList=newArrayList<>();for(inti=0;i<10;i++){Messagem=newMessage();m.setTitle(i+"--"+message.getTitle());m.setContent(i+"--"+message.getContent());m.setPubdate(message.getPubdate());messageList.add(m);}returnFlux.fromIterable(messageList);}publicFlux<Map.Entry<String,Message>>map(Messagemessage){Map<String,Message>map=newHashMap<>();for(inti=0;i<10;i++){Messagem=newMessage();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();returnFlux.fromIterable(map.entrySet());}
@GetMapping("webfluxList")@ApiOperation("整合webfluxList")publicObjectechoList(Messagemessage){log.info("接收用户信息,用户方发送的参数为message={}",message);returnthis.messageHandler.list(message);}@GetMapping("webfluxMap")@ApiOperation("整合webfluxMap")publicObjectechoMap(Messagemessage){log.info("接收用户信息,用户方发送的参数为message={}",message);returnthis.messageHandler.map(message);}
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
如何分析springboot响应式编程整合webFlux的问题的详细内容,希望对您有所帮助,信息来源于网络。