2024年3月6日
相对于服务端,Netty 客户端 的创建更加复杂,除了要考虑线程模型、异步连接、客户端连接超时等因素外,还需要对连接过程中的各种异常进行考虑。本章将对 Netty 客户端 创建的关键流程和源码进行分析,以期读者能够了解客户端创建的细节。 基于 Netty 创建客户端的流程分析 Netty 为了向使用者屏蔽 NIO 通信 的底层细节,……
阅读全文
2024年3月6日
TCP 粘包/拆包 熟悉 TCP 编程的都知道,无论是服务端还是客户端,当我们读取或者发送消息的时候,都需要考虑 TCP 底层 的 粘包/拆包机制。TCP 粘包/拆包问题,在功能测试时往往不会怎么出现,而一旦并发压力上来,或者发送大报文之后,就很容易出现 粘包 / 拆包问题。如果代码没有考虑,往往就会出现解码错位或……
阅读全文
2024年3月6日
该文所涉及的 netty 源码版本为 4.1.16。 Netty 内存池申请内存流程 在通过 PooledByteBufAllocator 中向内存池中进行内存申请的时候,最先开始的步骤便是从 PooledByteBufAllocator 中一系列 PoolArena 数组中,选择其中一个 PoolArena 进行分配。 这时将会从 PoolArena 数组中选取当前使用量最小的 PoolArena 与当前线程通过 ThreadLocal 进行绑定,之后涉及到内存申请将会直接从这个 PoolArena 进行获取,这个做法……
阅读全文
2024年3月6日
该文所涉及的 netty 源码版本为 4.1.16。 在一开始需要明确的几个概念 在 Netty 的内存池的 PoolChunk 中,先要明确以下几个概念。 page: page 是 chunk 中所能申请到的最小内存单位。 chunk: 一个 chunk 是一组 page 的集合 在 PoolChunk 中,chunkSize 的大小是 2^maxOrder * pageSize,其中 2^maxOrder 是 PoolChunk 中的完全二叉树叶子结点的数量,pageSize 则是……
阅读全文
2024年3月6日
该文所涉及的 netty 源码版本为 4.1.6。 Netty 的对象池 Recycler 是什么 Recycler 是 Netty 中基于 ThreadLocal 的轻量化的对象池实现。既然是基于 ThreadLocal,那么就可以将其理解为当前线程在通过对象池 Recycler 得到一个对象之后,在回收对象的时候,不需要将其销毁,而是放回到该线程的对象池中即可,在该线程下一次用到该对象的时候……
阅读全文
2024年3月6日
该文所涉及的 netty 源码版本为 4.1.6。 MpscLinkedQueue 是什么 在 Netty 的核心中的核心成员 NioEventLoop 中,其中任务队列的实现 taskQueue 便是 MpscLinkedQueue。MpscLinkedQueue 是 Netty 所实现的一个基于多生产者单消费者的无锁队列,针对 NioEventLoop 中任务队列的特点,其单消费者的场景在一开始就避免了从队列中取数据时加……
阅读全文
2024年3月6日
该文所涉及的 Netty 源码版本为 4.1.6。 HashedWheelTimer 是什么 Netty 的时间轮 HashedWheelTimer 给出了一个粗略的定时器实现,之所以称之为粗略的实现是因为该时间轮并没有严格的准时执行定时任务,而是在每隔一个时间间隔之后的时间节点执行,并执行当前时间节点之前到期的定时任务。 当然具体的定时任务的时间执行精度可以通过调节 HashedWheelTimer 构造……
阅读全文
2024年3月6日
前言 前段时间在给自己的玩具项目设计的时候就遇到了一个场景需要定时任务,于是就趁机了解了目前主流的一些定时任务方案,比如下面这些: Timer(halo 博客源码中用到了) ScheduledExecutorService ThreadPoolTaskScheduler(基于 ScheduledExecutorService) Netty 的 sch……
阅读全文
2024年3月6日
Netty 的 FastThreadLocal 源码解析 该文中涉及到的 Netty 源码版本为 4.1.6。 Netty 的 FastThreadLocal 是什么 A special variant of ThreadLocal that yields higher access performance when accessed from a FastThreadLocalThread. Internally, a FastThreadLocal uses a constant index in an array, instead of using hash code and hash table, to look for a variable. Although seemingly very subtle, it yields slight performance advantage over using a hash table, and it is useful when accessed frequently. To take advantage of this thread-local variable, your thread must be a FastThreadLocalThread or its subtype. By default, all threads created by DefaultThreadFactory are FastThreadLocalThread due to this reason. Note that the fast path is only possible on threads that extend FastThreadLocalThread, because it requires a special field to……
阅读全文