channelRead对于耗时业务逻辑处理的优化

channelRead对于耗时业务逻辑处理的优化

背景:之前在channelRead中,接收到远端消息进行解码后直接使用了操作数据库这种耗时较久的业务逻辑处理。导致本地netty的工作线程阻塞,会降低可用线程数。另一个对于当前channel的心跳机制也有影响,会导致远端机器长时间接受不到心跳信号,认为这台机器挂掉了。。。

原始代码

       public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if(msg instanceof MessageEntity)
        {
            MessageEntity messageEntity = (MessageEntity) msg;
            if (2==messageEntity.getMsgType())
            {
                LOGGER.info("收到服务端发来的方法请求了--------------------------------------------");
                // 转换为MethodInvokeMeta
                MethodInvokeMeta invokeMeta = (MethodInvokeMeta) ((MessageEntity) msg).getData();
                LOGGER.info("{} -> [客户端信息] \n 方法名  - > {} \n 参数列表  -> {} \n " +
                                "返回值  ->  {} ", this.getClass().getName(), invokeMeta.getMethodName(), invokeMeta.getArgs()
                        , invokeMeta.getReturnType());
                // 具体的处理类
                RequestDispatcher requestDispatcher = new RequestDispatcher();
                requestDispatcher.dispatcher(ctx, invokeMeta);
            }
            else
            {
                LOGGER.error("接受到的服务端请求无法识别");
            }
        }else
        {
            LOGGER.error("接受到的服务端请求无法识别");
        }
    }

在channelRead中,dispatch是一个接受到远程调用请求的分发器,会根据调用参数执行本地具体的方法。其中大多数都包括耗时较久的数据库操作,因此这块代码亟需优化。

    requestDispatcher.dispatcher(ctx, invokeMeta); 

解决方案

啥都不说,先上代码,如下:

    ExecutorService executor = Executors.newFixedThreadPool(2);

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //引入异步业务线程池的方式,避免长时间业务耗时业务阻塞netty本身的worker工作线程
        executor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                if(msg instanceof MessageEntity)
                {
                    MessageEntity messageEntity = (MessageEntity) msg;
                    if (2==messageEntity.getMsgType())
                    {
                        LOGGER.info("收到服务端发来的方法请求了--------------------------------------------");
                        // 转换为MethodInvokeMeta
                        MethodInvokeMeta invokeMeta = (MethodInvokeMeta) ((MessageEntity) msg).getData();
                        LOGGER.info("{} -> [客户端信息] \n 方法名  - > {} \n 参数列表  -> {} \n " +
                                        "返回值  ->  {} ", this.getClass().getName(), invokeMeta.getMethodName(), invokeMeta.getArgs()
                                , invokeMeta.getReturnType());
                        // 具体的处理类
                        RequestDispatcher requestDispatcher = new RequestDispatcher();
                        requestDispatcher.dispatcher(ctx, invokeMeta);
                    }
                    else
                    {
                        LOGGER.error("接受到的服务端请求无法识别");
                    }
                }else
                {
                    LOGGER.error("接受到的服务端请求无法识别");
                }
                return null;
            }
        });
    }

通过自己添加业务线程池的方式,避免阻塞worker工作线程(因为读完数据后,ChannelPipeline会触发 ChannelHandler链来处理业务逻辑,而ChannelHandler链的整个过程是是同步的)

原文地址:https://www.cnblogs.com/falcon-fei/p/11422376.html

时间: 2024-08-07 00:32:52

channelRead对于耗时业务逻辑处理的优化的相关文章

提示框的优化之自定义Toast组件之(二)Toast组件的业务逻辑实现

在java下org.socrates.mydiary.activity下LoginActivity下自定义一个方法showCustomerToast() ? 1 public class LoginActivity extends AppCompatActivity { 2 private void showCustomerToast(final int icon, final String message){ 3 LayoutInflater inflater=getLayoutInflate

微软-创建业务逻辑层

https://msdn.microsoft.com/zh-cn/dd255899 简介 在教程一中创建的数据访问层 (DAL) 将数据访问逻辑与表示逻辑清晰地分离开来.然而,尽管 DAL 从表示层中清晰地分离出数据访问层细节,它却并没有实施任何可能采用的业务规则.例如,我们想让我们的应用程序在 Discontinued 字段设为 1 时禁止对 Products 表的 CategoryID 或 SupplierID 字段的修改,还有,我们可能想实施一些资历规则以便禁止发生这样的情况:雇员被其后入

系统架构师-基础到企业应用架构-业务逻辑层

一.上章回顾 上章我们主要讲述了系统设计规范与原则中的具体原则与规范及如何实现满足规范的设计,我们也讲述了通过分离功能点的方式来实现,而在软件开发过程中的具 体实现方式简单的分为面向过程与面向对象的开发方式,而目前更多的是面向对象的开发设计方式.并且我们也讲述了该如何通过设计手段去分析功能点及设计分离 点,应该如何在设计的过程中分析的角度及如何去满足设计规范与原则.首先我们通过下图来回顾下上章要点: 二.摘要 本文将已架构的方式去分析分层结构中的业务层的设计,如何写出来内聚度,高耦合的业务逻辑层

视频直播编码,如何驾驭超复杂业务逻辑而不失漂亮的代码

折腾了一下午再加上晚上1小时,终于完成了总共6个视频,时长3小时48分的视频录制.这6个视频,完整演示了我们团队基于我们自己搭建的框架,进行编码的工作流程,即如何从原型图开始,一步一步分析需求,设计数据库,完成页面HTML,JS,CSS以至全部功能,现场直播,全程无删减. 我们的这个框架,就是为超复杂业务逻辑而生,同时不失漂亮的代码.通过这6个视频,你可以看到我们如何将复杂的业务逻辑,拆分成一个一个短小的业务单元,让每一个业务单元都那么简单.整个过程就像是庖丁解牛,每一行代码都那么理所当然,每一

数据库面对不同业务逻辑约束条件的选择

数据表的约束我觉得还是很有用的,至少在数据库优化方面还是用的比较多的,可以大大的提高检索效率,作用也是比较明显的,另外一点,表的约束可以在某种程度上简化程序代码端的业务逻辑量,这寄存于DBMS上面,其维护性我绝得韩式比较高的,这一般类型的数据库里面,我们常见的约束有:主键,外键,为空,唯一等,这四类是比较常见的约束,我绝对约束的实质应该是为真实的业务逻辑而服务的,否则则没有意义,所以,面对不同的业务逻辑逐一的进行分析: 1:什么情况下使用主键: 主键的含义是唯一且不为空,所以根据这个规范,能够满

从分享机制反观产品形态与业务逻辑

本文不是我写的,转载出处:http://www.woshipm.com/pd/273760.html “分享”是一个在App中特别常见的功能,从运营层面它满足了推广需求,从用户层面则满足了用户对外塑造自我形象.分享自我点滴.宣扬价值观等需求.这次我将分析五类常见应用(社交类.内容类.电商类.美化类.打车类)的分享机制,从中反推出不同产品的产品目标.业务逻辑对分享机制的影响:接着,从用户体验的角度分析几种分享机制下不同操作流程的优缺点. 一.每类产品分享的内容形式 不同种类的产品会因为不同的产品性

PHP业务逻辑层和数据访问层设计

以下还是觉得有点抽象 1.面向对象能给我们什么? 进行分析之前,我们先来复习一下面向对象.对象是要进行研究的任何事物.类是具有相同或相似性质的对象的抽象.面向对象的要素:封装.继承.多态.面向对象目的是:如何分配职责. 面向对象设计原则: 单一职责原则 (SRP) 一个类,只有一个引起它变化的原因. 开放-封闭原则 (OCP)(对外)可扩展,(对内)不可修改. 李氏替换原则 (LSP) 子类型必须能够完全替换其父类型. 依赖倒置原则 (DIP) 要依赖于抽象,不要依赖于具体. 接口隔离原则 (I

减少存储过程封装业务逻辑-web开发与传统软件开发的思维模式不同

本篇文章讨论并不是:不要使用存储过程,因为有些事情还是要存储过程来完成,不可能不用.而是关于:"业务逻辑是不是要封装在存储过程中实现,这样子php.java等就是调用存储过程". 业务逻辑,通俗说就是:比如要取数据的操作,取出会员编号为x的数据,原来我们一般是封装成函数,或者直接编写sql语句查询.现在是交给数据库的存储过程去完成. +------------------------------------------------------------ 写这篇文章的缘由 +-----

django--BBS项目,后端业务逻辑整理

经典的生活价值观 别让人生,输给了心情.心情不是人生的全部,却能左右人生的全部.心情好,什么都好,心情不好,一切都乱了.我们常常不是输给了别人,而是坏心情贬低了我们的形象,降低了我们的能力,扰乱了我们的思维,从而输给了自己. 控制好心情,生活才会处处祥和.好的心态塑造好心情,好心情塑造最出色的你. 静静的过自己的生活,心若不动,风又奈何.你若不伤,岁月无恙. BBS 项目开发逻辑梳理 第一步:先进行数据库设计 数据库设计规则是: 1.先创建基表:用户表.站点表.文章表.标签表.分类表.文章2标签