Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

对netty的EventExecutor进行修饰 #372

Closed
heixiaoma opened this issue Apr 6, 2022 · 5 comments
Closed

对netty的EventExecutor进行修饰 #372

heixiaoma opened this issue Apr 6, 2022 · 5 comments
Assignees

Comments

@heixiaoma
Copy link

image
目前这段代码可以完美的使用,但是性能不是很高,有没有办法直接获取ctx.executor()的就是TTL修饰过的,我尝试多次,貌似没有办法处理这个问题,前来和各位大哥交流学习下

@heixiaoma
Copy link
Author

这代码每次的请求都会修饰,还有一种就是缓存修饰的对象,但是我认为这是对low的做法,应该可以直接在源头上处理

@oldratlee
Copy link
Member

oldratlee commented Apr 6, 2022

但是性能不是很高

我认为这是对low的做法,应该可以直接在源头上处理

赞成 +1 ! @heixiaoma


因为涉及执行器的库/框架会有很多,所以在TTL库中不能都集成实现好。

另外,尤其是对比较大的库/框架的TTL集成,需要

  • 了解对应的库/框架,并实现稳定
  • 在实际场景中线上环境才有验证机会

@heixiaoma 你可以实现整理一个: 😁

  1. 先解决自己的问题,也能有实际实践使用;
  2. 再整理成一个集成Netty使用的库,放出来方便大家使用。

提到Netty集成的 Issue 有好几个,相信大家挺希望能有更好的解决方案:

TTL集成相关说明的 Issue


  • 从库下层实现来看,这些上层的库使用方式(如TtlRunnableTtlExecutorService):
    • 只是些便利方法。
    • 没有对业务使用增加额外约束。
  • 下层核心是 CRR 操作。 @heixiaoma
    • CRR操作 不耦合/依赖 (最常见的、JDK自带的)RunnableExecutorService
    • 可以被用于其它的执行框架(如kotlin协程)来集成。
  • 当然,这些上层库使用方式是非常重要的,不是可有可无的存在:
    • 上层面向用户使用的友好程度甚至说库的生命力,非常依赖这些上层库使用方式的设计。
    • 绝大多数情况下,用户要的是开箱即用简单快速地解决问题,而不是理解相对复杂的下层操作。

@heixiaoma
Copy link
Author

感谢老哥的建议,我多尝试尝试这个问题,或许通过javassist来修改netty的代码来实现或许是一种方法

@heixiaoma
Copy link
Author

heixiaoma commented Apr 7, 2022

    /**
     * 修改Netty,让线程池被TTL包装
     * AbstractEventExecutor eventloop都继承了这个抽象类,我们只加入一点自己的逻辑,并在RouterHandler里使用
     */
    public static void modifyNetty() {
        ClassPool cp = ClassPool.getDefault();
        try {
            String strPath="io.netty.util.concurrent.AbstractEventExecutor";
            ClassPath classPath= new LoaderClassPath(Thread.currentThread().getContextClassLoader());
            cp.insertClassPath(classPath);
            Loader loader = new Loader(cp);
            Class<?> abstractEventExecutor = loader.loadClass(strPath);
            CtClass ctClass = cp.getCtClass(abstractEventExecutor.getName());
            ctClass.freeze();
            ctClass.defrost();
            CtClass executorType = cp.get(Executor.class.getCanonicalName());
            // final Executor executor=TtlExecutors.getTtlExecutor(this); 模拟这样一段代码
            CtField ctField = new CtField(executorType, "executor", ctClass);
            ctField.setModifiers(Modifier.FINAL);
            ctClass.addField(ctField, "com.alibaba.ttl.threadpool.TtlExecutors.getTtlExecutor(this);");
            //在添加一个get方法用于RouterHandler调用
            // public Executor getExecutor() {
            //        return this.executor;
            //    }
            CtMethod m = new CtMethod( cp.get(Executor.class.getCanonicalName()), "getTtlExecutor", new CtClass[]{}, ctClass);
            m.setModifiers(Modifier.PUBLIC);
            // 添加返回
            m.setBody("return this.executor;");
            ctClass.addMethod(m);
            ctClass.toClass();
            ctClass.detach();
        } catch (Throwable e) {
            log.error(ExceptionUtil.getMessage(e));
        }
    }
        if (getTtlExecutor == null) {
            getTtlExecutor = ctx.executor().getClass().getMethod("getTtlExecutor");
        }

        Executor executor = (Executor)getTtlExecutor.invoke(ctx.executor());

写了一个demo,看上去也很丑

@oldratlee
Copy link
Member

先 close 了;有进一步信息或问题可以继续讨论。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants