千家信息网

Netty分布式pipeline管道传播outBound事件的示例分析

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章将为大家详细讲解有关Netty分布式pipeline管道传播outBound事件的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。outbound事件
千家信息网最后更新 2026年11月02日Netty分布式pipeline管道传播outBound事件的示例分析

这篇文章将为大家详细讲解有关Netty分布式pipeline管道传播outBound事件的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

outbound事件传输流程

在我们业务代码中, 有可能使用wirte方法往写数据:

public void channelActive(ChannelHandlerContext ctx) throws Exception {    ctx.channel().write("test data");}

当然, 直接调用write方法是不能往对方channel中写入数据的, 因为这种方式只能写入到缓冲区, 还要调用flush方法才能将缓冲区数据刷到channel中, 或者直接调用writeAndFlush方法, 有关逻辑, 我们会在后面章节中详细讲解, 这里只是以wirte方法为例为了演示outbound事件的传播的流程

这里我们同样给出两种写法

public void channelActive(ChannelHandlerContext ctx) throws Exception {    //写法1    ctx.channel().write("test data");    //写法2    ctx.write("test data");}

这两种写法有什么区别, 我们首先跟到第一种写法中去:

ctx.channel().write("test data");

这里获取ctx所绑定的channel

我们跟到AbstractChannel的write方法中:

public ChannelFuture write(Object msg) {    return pipeline.write(msg);}

这里pipeline是DefaultChannelPipeline

跟到其write方法中:
public final ChannelFuture write(Object msg) {    //从tail节点开始(从最后的节点往前写)    return tail.write(msg);}

这里调用tail节点write方法, 这里我们应该能分析到, outbound事件, 是通过tail节点开始往上传播的, 带着这点猜想, 我们继往下看

其实tail节点并没有重写write方法, 最终会调用其父类AbstractChannelHandlerContext的write方法

AbstractChannelHandlerContext的write方法:

public ChannelFuture write(Object msg) {     return write(msg, newPromise());}

我们看到这里有个newPromise()这个方法, 这里是创建一个Promise对象, 有关Promise的相关知识我们会在以后的章节剖析

我们继续跟write:

public ChannelFuture write(final Object msg, final ChannelPromise promise) {    //代码省略    write(msg, false, promise);    return promise;}

继续跟write:

private void write(Object msg, boolean flush, ChannelPromise promise) {     AbstractChannelHandlerContext next = findContextOutbound();    final Object m = pipeline.touch(msg, next);    EventExecutor executor = next.executor();    if (executor.inEventLoop()) {        if (flush) {            next.invokeWriteAndFlush(m, promise);        } else {            //没有调flush            next.invokeWrite(m, promise);        }    } else {        AbstractWriteTask task;        if (flush) {            task = WriteAndFlushTask.newInstance(next, m, promise);        }  else {            task = WriteTask.newInstance(next, m, promise);        }        safeExecute(executor, task, promise, m);    }}

这里跟我们上一小节剖析过channelRead方法有点类似, 但是事件传输的方向有所不同, 这里findContextOutbound()是获取上一个标注outbound事件的HandlerContext

跟到findContextOutbound中
private AbstractChannelHandlerContext findContextOutbound() {    AbstractChannelHandlerContext ctx = this;    do {        ctx = ctx.prev;    } while (!ctx.outbound);    return ctx;}

这里的逻辑我们似曾相识, 跟我们上一小节的findContextInbound()方法有点像, 只是过程是反过来的

在这里, 会找到当前context的上一个节点, 如果标注的事件不是outbound事件, 则继续往上找, 意思就是找到上一个标注outbound事件的节点

回到write方法:
AbstractChannelHandlerContext next = findContextOutbound();

这里将找到节点赋值到next属性中

因为我们之前分析的write事件是从tail节点传播的, 所以上一个节点就有可能是用户自定的handler所属的context

然后判断是否为当前eventLoop线程, 如果是不是, 则封装成task异步执行, 如果不是, 则继续判断是否调用了flush方法, 因为我们这里没有调用, 所以会执行到next.invokeWrite(m, promise),

我们继续跟invokeWrite

private void invokeWrite(Object msg, ChannelPromise promise) {    if (invokeHandler()) {        invokeWrite0(msg, promise);    } else {        write(msg, promise);    }}

这里会判断当前handler的状态是否是添加状态, 这里返回的是true, 将会走到invokeWrite0(msg, promise)这一步

继续跟invokeWrite0
private void invokeWrite0(Object msg, ChannelPromise promise) {    try {        //调用当前handler的wirte()方法        ((ChannelOutboundHandler) handler()).write(this, msg, promise);    } catch (Throwable t) {        notifyOutboundHandlerException(t, promise);    }}

这里的逻辑也似曾相识, 调用了当前节点包装的handler的write方法, 如果用户没有重写write方法, 则会交给其父类处理

我们跟到ChannelOutboundHandlerAdapter的write方法中看:

public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {    ctx.write(msg, promise);}

这里调用了当前ctx的write方法, 这种写法和我们小节开始的写法是相同的, 我们回顾一下:

public void channelActive(ChannelHandlerContext ctx) throws Exception {    //写法1    ctx.channel().write("test data");    //写法2    ctx.write("test data");}

我们跟到其write方法中, 这里走到的是AbstractChannelHandlerContext类的write方法:

private void write(Object msg, boolean flush, ChannelPromise promise) {     AbstractChannelHandlerContext next = findContextOutbound();    final Object m = pipeline.touch(msg, next);    EventExecutor executor = next.executor();    if (executor.inEventLoop()) {        if (flush) {            next.invokeWriteAndFlush(m, promise);        } else {            //没有调flush            next.invokeWrite(m, promise);        }    } else {        AbstractWriteTask task;        if (flush) {            task = WriteAndFlushTask.newInstance(next, m, promise);        }  else {            task = WriteTask.newInstance(next, m, promise);        }        safeExecute(executor, task, promise, m);    }}

又是我们所熟悉逻辑, 找到当前节点的上一个标注事件为outbound事件的节点, 继续执行invokeWrite方法, 根据之前的剖析, 我们知道最终会执行到上一个handler的write方法中

走到这里已经不难理解, ctx.channel().write("test data")其实是从tail节点开始传播写事件, 而ctx.write("test data")是从自身开始传播写事件

所以, 在handler中如果重写了write方法要传递write事件, 一定采用ctx.write("test data")这种方式或者交给其父类处理处理, 而不能采用ctx.channel().write("test data")这种方式, 因为会造成每次事件传输到这里都会从tail节点重新传输, 导致不可预知的错误

如果用代码中没有重写handler的write方法, 则事件会一直往上传输, 当传输完所有的outbound节点之后, 最后会走到head节点的wirte方法中

我们跟到HeadContext的write方法中
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {    unsafe.write(msg, promise);}

我们看到write事件最终会流向这里, 通过unsafe对象进行最终的写操作

有关inbound事件和outbound事件的传输, 可通过下图进行说明:

关于"Netty分布式pipeline管道传播outBound事件的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

方法 事件 节点 写法 传播 传输 分析 逻辑 有关 代码 小节 数据 方式 篇文章 剖析 处理 分布式 示例 管道 似曾相识 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百单网互联网科技有限公司 美国互联网保险保险科技 美国互联网科技巨头监管 金诺互联网科技 平安科技 互联网 上海挚品互联网科技 唐信互联网科技 壹账通互联网科技 上海致骋互联网科技 北京禾田雨橡互联网科技 火传媒上海互联网科技 上海亿帐通互联网科技 广西拼得多互联网科技有限公司 字节跳动和互联网科技 佛山市翊博互联网络科技有限公司 特约风豹互联网科技为什么扣费 科技赋能视角下互联网保险发展 上海乐五互联网科技有限公司 互联网公司属于科技吗 东风日产互联网科技公司叫什么 互联网核心科技是什么 互联网科技与金融科技 互联网科技公司怎么样 老年人脱离互联网科技的作文 互联网大会黑科技排名 知域互联网科技有限公司大骗子 允成互联网科技有限公司融资 互联网科技数字货币 互联网金融运营模式中的金融科技 互联网企业和网络科技有限公司
0