目录大纲:

  1. 前言
  2. 处理耗时业务的第一种方式-------handler 种加入线程池
  3. 处理耗时业务的第二种方式-------Context 中添加线程池
  4. 总结:两种方式的对比和思考

前言

熟悉 Netty 的同学都知道,不能在 Netty 中做耗时的,不可预料的操作,比如数据库,网络请求,这将会严重影响 Netty 对 Socket 的处理速度。而解决方法就是将耗时任务添加到异步线程池中。但就添加线程池这步操作来讲,可以有2种方式,而且这2种方式的区别也蛮大的。今天就好好讲一讲。

1. 处理耗时业务的第一种方式-------handler 种加入线程池

以我们之前的 Netty 的 demo 源码例子,在 channelRead 方法种进行异步:

上图中的 channelRead 方法,我们模拟了一个耗时 10 秒的操作,于是,我们将这个任务提交到了一个自定义的业务线程池中,这样,就不会阻塞 Netty 的 IO 线程。

这样操作之后,整个程序的逻辑是这样的:

解释一下上图,当 IO 线程轮询到一个 socket 事件,然后,IO 线程开始处理,当走到耗时 handler 的时候,将耗时任务交给业务线程池。当耗时任务执行完毕再执行 pipeline write 方法的时候(代码中使用的是 context 的 write 方法,上图画的是执行 pipeline 方法),会将任务这个任务交给 IO 线程。

下面是 write 方法的源码:

当判定下个 outbound 的 executor 线程不是当前线程的时候,会将当前的工作封装成 task ,然后放入 mpsc 队列中,等待 IO 任务执行完毕后执行队列中的任务。很明显,下个任务的线程肯定是 IO 线程,因为我们没有设置。

2. 处理耗时业务的第二种方式-------Context 中添加线程池

第二种方式是 Netty 建议的方式,在添加 pipeline 中的 handler 时候,添加一个线程池:

而 handler 中的代码不用做任何修改:

当我们在调用 addLast 方法添加线程池后,handler 将优先使用这个线程池,如果不添加,将使用 IO 线程。

所以,当走到 AbstractChannelHandlerContext 的 invokeChannelRead 方法的时候,executor.inEventLoop() 是不会通过的,因为当前线程是 IO 线程,Context(也就是 Handler) 的 executor 是业务线程,所以会异步执行,如下:

这个时候,后面的整个流程就变成和第一个方式一样了。

总结: 两种方式的对比和思考

有什么区别呢?第一种方式在 handler 中添加异步,可能更加的自由,比如如果需要访问数据库,那我就异步,如果不需要,就不异步,异步会拖长接口响应时间。因为需要将任务放进 mpscTask 中。如果不凑巧,IO 时间很短,task 很多,可能一个循环下来,都没时间执行整个 task,导致响应时间达不到指标。

第二种方式是 Netty 建议的,但是,这么做会将整个 handler 都交给业务线程池。不论耗时不耗时,都加入到队列里,不够灵活。

再回顾一下我们刚开始的图吧:

个人建议还是使用第一种方式,比较灵活。

Netty 源码阅读的思考------耗时业务到底该如何处理的更多相关文章

  1. Netty源码阅读(一) ServerBootstrap启动

    Netty源码阅读(一) ServerBootstrap启动 转自我的Github Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速 ...

  2. Netty源码阅读之如何将TCP的读写操作和指定线程绑定

    原文链接:http://xueliang.org/article/detail/20200712234015993 前言 在Netty的线程模型中,对于一个TCP连接的读写操作,都是由一个单线程完成的 ...

  3. netty源码阅读之UnpooledByteBufAllocator

    使用IDEA阅读源码Navigate下面的工具是个好东西 .可以帮助分析类的结构等 ByteBufAllocator主要用来生成三种ByteBuf :HeadBuffer,DirectBuffer,C ...

  4. Netty源码剖析-业务处理

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线:worker thread 触发pipeline.fi ...

  5. netty(一)---服务端源码阅读

    NIO Select 知识 select 示例代码 : //创建 channel 并设置为非阻塞 ServerSocketChannel serverChannel = ServerSocketCha ...

  6. 【JDK1.8】JDK1.8集合源码阅读——ArrayList

    一.前言 在前面几篇,我们已经学习了常见了Map,下面开始阅读实现Collection接口的常见的实现类.在有了之前源码的铺垫之后,我们后面的阅读之路将会变得简单很多,因为很多Collection的结 ...

  7. netty源码分析之揭开reactor线程的面纱(二)

    如果你对netty的reactor线程不了解,建议先看下上一篇文章netty源码分析之揭开reactor线程的面纱(一),这里再把reactor中的三个步骤的图贴一下 reactor线程 我们已经了解 ...

  8. Netty源码分析(前言, 概述及目录)

    Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...

  9. Netty 源码(一)服务端启动

    Netty 源码(一)服务端启动 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) ServerBootstap 创建时序图如 ...

随机推荐

  1. 1.buntu 安装redis

    方式一 :apt安装 在 Ubuntu 系统安装 Redi 可以使用以下命令: $sudo apt-get update $sudo apt-get install redis-server 启动 R ...

  2. Change tab position of PageControl to bottom

    Hi, Try: UniPageControl1 -> ClientEvents -> UniEvents : function tabPanel.beforeInit(sender, c ...

  3. javascript变量浅析

    变量声明 javascript 使用var + 变量名 声明变量,因为javascript是弱类型语言, 所有我们可以随意更改已有变量的类型. var b=1; b='2', 另外不同于c#中的var ...

  4. 记Asp.Net Core Swagger 使用 并带域接口处理

    引用作者原话:Asp.Net的WebApi中使用Swagger作为说明和测试的页面是非常不错的,比起WebApiTestClient来至少在界面上的很大的提升.但是使用Swagger时如果只是一般的控 ...

  5. UWP Button添加圆角阴影(三)

    原文:UWP Button添加圆角阴影(三) Composition DropShadow是CompositionAPI中的东西,使用Storyboard设置某个属性,就是频繁的触发put_xxx() ...

  6. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  7. 【新手向】阿里云上ubuntu+flask+gunicorn+nginx服务器部署(二)项目部署

    本项目实现的是类似于ins的图片分享网站.继续(一),当nginx的配置已修改好后,要在远程服务器上部署网站,只需要几个步骤: 1 前期准备 2 将运行网站的代码从github上下载过来 3 下载依赖 ...

  8. delphi datetimepicker 修改时间无效问题

    今天用delphi写个程序,使用datetimepicker获得想要的时间.蛋疼的问题是无论怎么调整明明看着控件里面的日期变了,但是show出来的datetimepicker.datetime日期都不 ...

  9. PICE(2):JDBCStreaming - gRPC-JDBC Service

    在一个akka-cluster环境里,从数据调用的角度上,JDBC数据库与集群中其它节点是脱离的.这是因为JDBC数据库不是分布式的,不具备节点位置透明化特性.所以,JDBC数据库服务器必须通过服务方 ...

  10. [ActionScript 3.0] as3处理xml的功能和遍历节点

    as3比as2处理xml的功能增强了N倍,获取或遍历节点非常之方便,类似于json对像的处理方式. XML 的一个强大功能是它能够通过文本字符的线性字符串提供复杂的嵌套数据.将数据加载到 XML 对象 ...