目录大纲:

  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. AngularJS 脏检查机制

    脏检查是AngularJS的核心机制之一,它是实现双向绑定.MVVM模式的重要基础. 一.digest循环 AngularJS将双向绑定转换为一个堆watch表达式,然后递归检查这些watch表达式的 ...

  2. java web开发遇到的常见问题解决办法(汇总贴)

    1. maven下载jar包失败,重复 maven --> update project 不管用 解决办法:  1.打开本地仓库所在目录, 通过win文件夹的搜索功能,查找 *.lastUpda ...

  3. poj 2155 区间更新 单点查询

    Matrix Time Limit: 3000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class ...

  4. cxgrid动态多表头

    function TForm15.CreateBand(View: TcxGridDBBandedTableView;  BandCaption, ParentBandCaption: String) ...

  5. ubuntu16.04 LTS把下载源改为阿里云的源

    为什么要切换下载源到国内的源上? Ubuntu的中国服务器下载速度很慢,我们可以尝试修改软件更新源,这样下载和更新软件的速度会加快很多. 一.linux系统版本: ubuntukylin-16.04- ...

  6. 输出的数据格式是如何决定的-------Asp.net WebAPI学习笔记(二)

    在上一篇文章<路由其实也可以很简单>,我们解决了路由问题,这篇文章,我们来研究剩下的另一个问题,为何我们的方法返回的是一个列表,输出到客户端的时候,变成json呢,大家应该还记得我们上一篇 ...

  7. .net core 与ELK(3)安装Kibana

    1.去产品官网下载https://www.elastic.co/downloads/kibana 对应的tar.gz的压缩包,放到/usr/local/src目录 2.解压 -linux-x86_64 ...

  8. Win10远程桌面出现 身份验证错误,要求的函数不受支持,这可能是由于CredSSP加密Oracle修正 解决方法

    升级至win10 最新版本10.0.17134,远程桌面连接Window Server时报错信息如下: 出现身份验证错误,要求的函数不正确,这可能是由于CredSSP加密Oracle修正. 解决方法: ...

  9. DEV通过FindFilterText自动检索gridview内容

    private void TreeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (names!=nul ...

  10. PS插件CameraRaw-初次尝试

    一.百度百科原话 RAW的原意就是“未经加工”.可以理解为:RAW图像就是CMOS或者CCD图像感应器将捕捉到的光源信号转化为数字信号的原始数据.RAW文件是一种记录了数码相机传感器的原始信息,同时记 ...