Netty
文章平均质量分 80
书唐瑞
个人站点: www.infuq.com
个人公众号: Netty历险记
展开
-
Java通过JNI申请直接内存
Java通过JNI申请直接内存原创 2022-03-15 20:06:30 · 1964 阅读 · 3 评论 -
Selector.select()
Netty的底层依然是依赖于JDK的NIO . 开发NIO服务端的代码如下所示import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.*;import java.util.Iterator;import java.util.Set;public class Server { // 缓冲区的大小 priva原创 2021-12-07 12:01:02 · 2168 阅读 · 0 评论 -
使用自定义协议实现Python向Netty传输数据
本篇文章,自定义一个数据协议,通过Python语言,使用这个自定义的数据协议,将数据发送给Netty接收端.之所以使用两种不同的语言,也在说明,数据之间的传输与语言无关.只要发送端和接收端彼此遵守相同的协议即可.关于协议,无处不在,比如与网络相关的HTTP协议, 比如向Redis发送命令使用的RESP协议,比如Dubbo消费者和提供者之间的数据传输,比如RocketMQ消费者与服务端之间的消息传输,比如JVM中使用jstack命令获取堆栈信息时所使用的协议,等等. 它们之间必然会有一套相关的协议,用于数原创 2021-10-01 14:38:19 · 1247 阅读 · 0 评论 -
通过Netty/Socket/C语言三种方式向Redis服务器发送命令
本文通过使用Netty,Java的Socket和C语言Socket这三种方式,基于RESP协议,向Redis服务器发送一个set命令.向Redis服务器发送命令,即与Redis服务器通信,必须基于RESP协议. 就好像在B站看2021苹果秋季发布会的视频底层数据传输必须基于TCP协议一样.RESP协议是一个简单的协议.它的协议格式如下*<number of arguments> CR LF$<number of bytes of argument 1> CR LF <a原创 2021-09-15 22:49:05 · 574 阅读 · 0 评论 -
Netty接收数据时一次读取多少字节以及读多少次
本篇文章介绍一下,Netty在接收到数据时,一次性读取多少字节.本篇使用Netty构建一个简单的服务端,使用Python构建一个简单的客户端,然后客户端向服务端发送数据,然后观察Netty每次读取的字节数.客户端代码如下import socketif __name__ == '__main__': client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080))原创 2021-08-26 04:29:58 · 2665 阅读 · 1 评论 -
Netty写数据(动画)
以动画的形式,简单描述Netty写数据的流程.个人站点语雀公众号原创 2021-06-12 20:00:22 · 258 阅读 · 0 评论 -
Netty对象池
在平时工作中,听说和使用过连接池,线程池等.还有一种就是对象池,可以实现对象复用的功能.当然实现对象池的方式手段有多种,比如有一个公共的池子,所有需要对象的线程通过并发控制的方式从池子中获取对象,并发控制的同时伴随性能的损耗.那么Netty是如何实现对象池的呢? 先通过一段演示代码说起import io.netty.util.Recycler;public class Book { private String name; private final Recycler.Handle原创 2021-06-10 20:25:13 · 494 阅读 · 1 评论 -
本地编译Netty并打包成指定的版本
开发的小伙伴,是否有过想在自己的项目中引入其他第三方的源码,作为debug或者学习用呢?比如我在自己的项目模块中只是添加了Netty的maven依赖,自己写的测试用例每次跳进Netty里面,看不到源码.即便我点击下载了源码,可我们不可以编辑,比如在源码里面加个打印日志,这是不可以的.我们所谓下载的源码其实依然是个jar为了解决这个问题,或者类似的问题,我们还是需要下载所谓真正的源码.比如我从GitHub下载的Netty源码如下接下来修改IDEA中的配置不要告诉我,你不知道如何打开原创 2020-05-09 01:46:52 · 1129 阅读 · 2 评论 -
Netty之线程唤醒wakeup
首先回顾下, Netty中的IO线程主要完成三件事1.轮询IO事件2.处理IO事件3.执行任务在轮询IO事件的过程中,在Linux系统下, 使用epoll实现.涉及的Netty代码如下private void select() { // ... int selectedKeys = selector.select(timeoutMillis); // ...}具体源码位置:io.netty.channel.nio.NioEventLoop#select当I原创 2021-04-10 20:46:46 · 524 阅读 · 2 评论 -
Netty中真的没有使用锁吗?
Netty号称是一个事件驱动&异步串行无锁化的网络通信框架.在Netty的官方网站(https://netty.io/)中声称, 它是一个异步的, 事件驱动的网络框架.关于事件驱动, 在之前的文章中也简单提到过, Netty内部会一直轮询ACCEPT,READ,WRITE,CONNECT等事件, 根据轮询到的不同的事件, 调用不同的方法, 做出不同的响应. 正如我们平时说的, 操作系统是基于中断驱动的, 而Netty是基于事件驱动的.关于异步这块, 我给它的准确定义是异步串行无锁化. 然而在N原创 2021-04-01 22:27:19 · 367 阅读 · 0 评论 -
浅谈Netty和Python中的事件驱动
如果把Netty比作一台工厂车间, 那么IO线程就是车间里面的运作机器, IO线程一直在无限循环地做着三件事1.轮询IO事件2.处理IO事件3.执行task任务无限循环源码位置: io.netty.channel.nio.NioEventLoop#runselect()方法源码位置: io.netty.channel.nio.NioEventLoop#select在Netty中轮询IO事件是通过调用select()方法, 至于底层基于select,poll,epoll哪一种, 这个和平台有关原创 2021-03-28 18:02:05 · 291 阅读 · 0 评论 -
Netty客户端发起连接过程注意点
使用Netty创建客户端的时候, 和创建服务端类似, 也需要经过创建-初始化-注册这三步, 最后一步也最重要就是连接操作, io.netty.bootstrap.Bootstrap#connect(java.net.SocketAddress)创建就是创建NioSocketChannel, 同时也会创建unsafe,pipeline,config等. 还会设置一个感兴趣的SelectionKey.OP_READ 读事件属性, 此时也仅仅是把OP_READ保存到一个属性上.初始化就是给channel设置一原创 2021-03-27 21:55:37 · 567 阅读 · 0 评论 -
解码器LengthFieldBasedFrameDecoder
解码器LengthFieldBasedFrameDecoder, 从名字上可以猜测出来, 它是基于长度的解码器.Netty从TCP缓冲区中读取字节, 把这些字节交给LengthFieldBasedFrameDecoder进行解码, 解码的操作是根据设定的规则, 根据规则, 从字节中解码出来有意义的数据, 然后把数据再交给后续的Handler处理.接下来看下, 它是如何根据规则解码的.如上图, 从网络中读取到的数据是基于流的, 而且是有方向的. 然而数据是没有边界的, 不知道从哪儿到哪儿是一个完整的数据原创 2021-03-26 23:03:27 · 9552 阅读 · 1 评论 -
Netty服务端是如何一点一点被带动起来的
import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;原创 2021-03-21 23:52:04 · 223 阅读 · 0 评论 -
Netty源码下载与编译
在学习Netty源码的过程中,有时候需要针对某个版本的源码进行修改,测试一些功能点.这个时候我们就需要下载指定版本的源码,修改一些配置,让源码可以正常编译成功.1.下载指定版本的源码访问 https://github.com/netty/netty/tags选择需要的版本并下载zip解压并导入到IDEA2.修改前提: 电脑上安装了JDK1.8修改parent的pom.xml中的compiler<maven.compiler.source>1.8</maven.compile原创 2021-02-26 21:47:40 · 1707 阅读 · 0 评论 -
Netty中的LengthFieldBasedFrameDecoder解码器
假如客户端给服务端发送数据,那么服务端的Netty从网络中读取的数据都是连续的字节流数据,同时粘包和拆包也在’捣乱’,如何读取一个完整的数据包, 这个重担就落在了解码器的身上.本篇文章介绍下使用广泛的LengthFieldBasedFrameDecoder解码器.在介绍之前, 先看个总览图简单描述上面这张图, 假如客户端给服务端发送数据.第一次当数据(HEL)到达服务端之后,Netty中的NioByteUnsafe类会从TCP缓冲区将数据(HEL)读取出来并封装成一个ByteBuf传给帧解码器.原创 2021-02-26 14:10:44 · 2167 阅读 · 0 评论 -
Dubbo与Netty杂谈
在Dubbo的’人生’中, 无论它是在自己的’亲爸爸’阿里家族成长, 还是’寄养’在Apache家族里, Dubbo的底层通信一直使用高性能的Netty框架.Dubbo在阿里家族一直成长到v2.6.9版本之后,就被送到Apache家族了.通过Maven官网搜索Dubbo版本, 如下从上面两张图看出, Dubbo在阿里家族的Maven最高版本是v2.6.9, 在Apache家族的Maven最低版本是v2.7.0, 正好衔接.在之前的Netty在Dubbo中使用了哪些Handler文章中, 介绍了在原创 2021-02-24 22:23:23 · 1513 阅读 · 1 评论 -
Netty模拟OOM-Metaspace
在模拟OOM之前, 先简单说下Netty服务端向客户端发送数据的时候, 涉及两个存储数据的地方, 如下图所示业务线程在向客户端发送数据的时候, 是不能直接把数据发送到网络的, 只有IO线程才可以把数据发送到网络, 因此业务线程只能把数据封装成一个任务放到与IO线程关联的一个Queue中, 之后IO线程会从Queue中取出任务, 执行写操作, 将数据写到网络. 因此这个Queue就是存储数据的第一个地方.在之前的文章中,介绍过 使用Netty模拟发生OOM , 那里说的OOM是指java.lang.Ou原创 2021-02-22 21:47:51 · 532 阅读 · 0 评论 -
Netty中的永动机
永动机即’永远运动的机器’.作为服务端时, 需要接收客户端的连接, 需要接收客户端的数据, 或者向客户端发送数据.既然需要接收客户端的连接, 那么就需要一个IO线程永远的执行一个无限循环.只有一直循环着, 才能一直接收新的连接.NioEventLoop的底层绑定一个线程, 这个线程在启动之后, 就会一直无限循环着, 而且只做三件事1.轮询IO事件2.处理IO事件3.执行任务当有新的客户端连接到服务端的时候(TCP三次握手已经完成), 服务端的IO线程就会轮询到有客户端的连接事件. 接下来原创 2021-02-21 21:40:43 · 276 阅读 · 1 评论 -
Netty在Dubbo中使用了哪些Handler
本篇以Dubbo作为服务端为例.当配置如下信息时<dubbo:application name="infuq-dubbo-provider" /><dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" check="false" /><dubbo:protocol name="dubbo" port="20880" threads="200"/><dubbo:service ref="qu原创 2021-01-24 22:45:37 · 462 阅读 · 0 评论 -
Dubbo学习Netty中的FastThreadLocal
在之前的Netty的FastThreadLocal文章中介绍了FastThreadLocal在Netty中的实现和使用.今天在浏览Dubbo源码的时候,发现了一个com.alibaba.dubbo.common.threadlocal.InternalThreadLocal类,细看下它的实现,代码与io.netty.util.concurrent.FastThreadLocal很相似.This design is learning from io.netty.util.concurrent.FastTh原创 2021-01-18 22:34:57 · 275 阅读 · 0 评论 -
Netty中的任务队列(添加元素篇)
此篇文章讲解一下Netty中的任务队列.这里说的任务队列是Netty中的IO线程对应的任务队列.在Netty中NioEventLoopGroup这个类相当于线程池,而由它创建的每个NioEventLoop相当于池中的线程,因为每个NioEventLoop都是和唯一的一个线程绑定的,而这个线程只负责IO相关的工作,因此称作IO线程.在创建NioEventLoop的时候会创建一个与之关联的任务队列(Queue taskQueue).这个任务队列用于’装载’其他非IO线程向IO线程提交的任务,比如业务线程(即原创 2021-01-06 22:07:43 · 707 阅读 · 0 评论 -
Netty知识点(杂记)
import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;im原创 2021-01-02 02:24:07 · 306 阅读 · 0 评论 -
Netty在Dubbo服务暴露时何时被使用
Dubbo的底层通信使用的是Netty.关于Dubbo的服务暴露流程,网络上已经有很多优质的文章.此篇文章以Dubbo的服务暴露为主线(不会详细讲解),观察一下,Netty在服务暴露过程中何时被使用.// 服务暴露的起点com.alibaba.dubbo.config.spring.ServiceBean#onApplicationEvent@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) { if (i原创 2020-12-27 16:00:02 · 269 阅读 · 0 评论 -
Netty中客户端如何连接服务端
本篇文章讲解使用的Netty版本<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.43.Final</version></dependency>使用Netty构建一个客户端,那么它是如何连接服务端的呢?以下是客户端代码import io.netty.bootstr原创 2020-12-24 00:57:14 · 1151 阅读 · 0 评论 -
Netty中的时间轮(v3.10.7)
在上一篇Netty中的时间轮(v3.2.5)中,讲解的版本是v3.2.5,它在MAVEN仓库中是可以找到的.这篇文章讲解的是3.x系列中目前最高的版本v3.10.7,它在MAVEN仓库中不存在,这个版本只在Netty源码中可以找到.讲解这个v3.10.7版本的目的是要和v3.2.5版本做个对比,看它们各自在时间轮上的实现差异.在时间轮创建的底层,v3.10.7使用的是普通对象数组,而v3.2.5使用的是集合数组// v3.2.5版本中的时间轮底层存放任务的结构final Set<HashedWh原创 2020-12-12 15:09:42 · 372 阅读 · 0 评论 -
Netty中的时间轮(v3.2.5)
时间轮是一种可以执行定时任务的数据结构和算法.这篇文章,讲解一下它在Netty 3.x系列中如何实现的,它在4.x系列将在后面的文章中讲解.此次讲解的版本如下<dependency> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> <version>3.2.5.Final</version></depen原创 2020-12-10 01:54:28 · 557 阅读 · 0 评论 -
RocketMQ与Dubbo之间线程之间如何阻塞和唤醒
在上一篇RocketMQ与Dubbo相爱相杀引起的FullGC文章中,我们讲解了由于Dubbo接口调用耗时太久,而消息生产者发送的消息非常快,导致消息消费者不能及时消费消息,造成消息队列堆积,最终导致FullGC.本篇文章,我们看一下RocketMQ线程和Dubbo线程如何协作的.我们向MQ消费者发送一个消息,我们分析MQ线程是如何调用Dubbo的线程,以及接收到Dubbo的返回值之后,Dubbo线程又是如何和MQ线程交互的.Dubbo调用者的配置如下<dubbo:application na原创 2020-12-05 22:48:07 · 511 阅读 · 0 评论 -
RocketMQ与Dubbo相爱相杀引起的FullGC
RocketMQ与Dubbo相爱相杀引起的FullGC原创 2020-12-02 13:16:14 · 581 阅读 · 0 评论 -
Netty空闲检测之写空闲
在之前的文章,我们介绍了Netty空闲检测之读空闲,以及为了介绍此篇文章,我们也特意写了一篇关于写操作的概括文章.读者对于Netty如何进行写操作也有了一个大概的认识了,接下来我们说一下,对于如何检测写空闲,Netty是如何控制的?我们在向Pipeline中添加Handler的时候,绝大多数都会添加如下几个Handler.分别是编码器(把写入外部地数据进行编码),解码器(把从外部读取地数据进行解码),空闲检测(检测是否读/写空闲),连接管理(如果存在空闲连接,如何处理),业务处理器(处理业务)假如网原创 2020-11-24 23:16:49 · 642 阅读 · 1 评论 -
Netty如何向客户端写数据(视频)
Netty如何向客户端写数据 个人站点语雀公众号原创 2020-11-24 10:39:27 · 634 阅读 · 0 评论 -
Netty写操作的一点概括
相对于读操作而言,Netty在处理写操作上更复杂一些.在之前的文章我们介绍了Netty空闲检测之读空闲,为了介绍Netty空闲检测之写空闲,我们有必要对Netty的写操作做一个整体上的介绍.有助于我们接下来介绍写空闲.在之前的文章我们也说过,在Netty中有两类线程,一类是IO线程,负责读写操作,一类是业务线程,就是处理业务的线程.我们以RocketMQ为例,看下它的源码中,如何分配这两类线程的.// 源码位置: org.apache.rocketmq.remoting.netty.NettyRemot原创 2020-11-22 18:15:50 · 373 阅读 · 0 评论 -
Netty空闲检测之读空闲
Netty空闲检测之读空闲原创 2020-11-21 17:54:23 · 1231 阅读 · 1 评论 -
使用Netty模拟发生OOM
我们模拟这么一个场景,客户端和服务端都使用Netty进行通信,客户端无限循环地向服务端发送数据,过了一会客户端就会出现OOM,我们分析OOM产生的原因,给我们排查线上问题提供一个思路和角度.以下所有的分析都是基于以上描述的场景本文适合对Netty要有一定的基础代码放在了github上设置的客户端虚拟机参数-XX:MetaspaceSize=18M -XX:MaxMetaspaceSize=18M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDum原创 2020-11-21 00:24:08 · 759 阅读 · 0 评论 -
Netty在Dubbo中的线程名称
在项目中,我们会使用RocketMQ和Dubbo.前者用于发送或消费消息,后者用于两个模块之间的接口调用.RocketMQ和Dubbo在它们的底层都使用Netty作为网络通信的框架.那么今天我们就来看一下,在Dubbo中,使用的Netty线程名称叫什么?环境和流程如下:1.启动zookeeper2.一个简单的Dubbo提供者,并启动它3.通过telnet和invoke命令连接并调用接口关于zookeeper环境的简单搭建可以查看此篇文章.启动zookeeper之后,我们接下来主要看下Dubbo原创 2020-11-16 22:13:46 · 306 阅读 · 0 评论 -
Netty的高低水位
假如我们的底层使用Netty作为网络通信框架,业务流程在将业务数据发送到对端之前,实际先要将数据发送到Netty的缓冲区中,然后再从Netty的缓冲区发送到TCP的缓冲区,最后再到对端.业务数据不可能无限制向Netty缓冲区写入数据,TCP缓冲区也不可能无限制写入数据.Netty通过高低水位控制向Netty缓冲区写入数据的多少.它的大体流程就是向Netty缓冲区写入数据的时候,会判断写入的数据总量是否超过了设置的高水位值,如果超过了就设置通道(Channel)不可写状态.当Netty缓冲区中的数据写原创 2020-11-04 00:32:41 · 1621 阅读 · 0 评论 -
Netty的FastThreadLocal
在文章ThreadLocal与FastThreadLocal中我们介绍了JDK的ThreadLocal与Netty的FastThreadLocal之间的一点区别.这篇文章在单独介绍下FastThreadLocal.io.netty.util.concurrent.FastThreadLocal我们先看个对比表格JDKNettyThreadFastThreadLocalThreadThreadLocalFastThreadLocalThreadLocalMapI原创 2020-11-02 02:39:38 · 527 阅读 · 0 评论 -
JDK之ThreadLocal与Netty之FastThreadLocal对比
java.lang.ThreadLocalThreadLocal类通过线程封闭的方式解决线程安全,提到它,大家都会想到弱引用和内存泄漏等话题,它的get/set/remove等方法,网上有很多关于它的话题和详细介绍.这篇文章不会介绍这些内容.ThreadLocal作为key被存放到线程的ThreadLocal.ThreadLocalMap中.我们简单看下它的set方法.public void set(T value) { Thread t = Thread.currentThread();原创 2020-11-01 03:18:55 · 340 阅读 · 0 评论 -
redisson实现分布式锁底层通信与协议
在之前的Netty在Redis客户端中的应用文章中我们介绍了Netty在Redisson中的使用.在之前的jedis实现分布式锁底层通信与协议文章中我们介绍了关于Redis客户端与服务器通信的协议.那么,在本篇文章我们介绍下Redisson中如何实现客户端与服务器通信协议的.阅读本篇文章之前请先阅读上面的两篇文章在创建Redisson的过程中会创建一个org.redisson.client.RedisClient类,在这个类的内部会创建一个io.netty.bootstrap.Bootstrap原创 2020-09-20 02:09:35 · 828 阅读 · 0 评论 -
jedis实现分布式锁底层通信与协议
通过此篇文章可以了解Redis的底层通信,Redis的协议,以及自己手写与服务器通信.在分布式锁的实现上, 基于Redis的实现是其中一种.而具体的实现依赖包又有两个<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.0.1</version></dependency&g原创 2020-09-15 04:16:38 · 377 阅读 · 0 评论