Netty 入门 — 亘古不变的Hello World
这篇文章我们正式开始学习 Netty,在入门之前我们还是需要了解什么是 Netty。

什么是 Netty
为什么很多人都推崇 Java boy 去研究 Netty?Netty 这么高大上,它到底是何方神圣?
用官方的话说:Netty 是一款异步的、基于事件驱动的网络应用程序框架,用以快速开发高性能、高可靠性的网络 IO 程序。
为什么要使用 Netty 呢?因为使用原生的 Java NIO 非常不爽,它存在一系列的问题,比如:
- 使用 Java NIO 需要了解很多概念,而且 API 非常繁琐。
- 使用 Java NIO 编程复杂,一不小心就会 Bug 横飞。
- 开发工作量和难度也很大,例如我们要处理断开重连、网络闪断、半包读写、网络拥塞、异常处理,等等异常情况,处理起来难度比较大。需要非常熟悉 Java 多线程和网络相关知识点,才能编写一个高质量的 Java NIO 程序。
- JDK NIO 的 Bug:例如臭名昭著的 Epoll Bug,它会导致 Selector 空轮询,最终导致 CPU 100%。
使用 Netty,都解决了上面的问题,它具备如下几个优点:
- 容易上手:Netty 是 Java NIO 进行了封装,API 使用简单,开发门槛相对较低。
- 功能强大:预置多种编解码功能,支持多种主流协议,底层 IO 模型随意切换等等。
- 高性能:精心设计的 Reactor 线程模型支持高并发,优秀的内存模型,减少了资源的消耗。
- 设计优雅:灵活且可扩展的事件模型,可以清晰地分离关注点;高度可定制化的线程模型;粘包/粘包、异常检测等机制将我们从繁重的细节中解脱,只需关注业务逻辑。
- 社区活跃:Netty 是目前最为活跃的开源项目之一,版本迭代周期短,bug 修复速度快。
- 安全:完整的 SSL/TLS 和 StartTLS 支持。
- 质量有保障:经过大规模的商业应用考验,质量得到了充分的验证,健壮性无比强大,放心使用吧。
Hello World
接下来我们用 Netty 来实现我们的第一个应用程序:Hello World。该 Hello World 程序大明哥做到尽可能简单,理解不了没有关系,能跑起来就行,毕竟是第一个 demo。
注:大明哥写这篇文章时, Netty 最新版本为:4.1.77,所以后面所有文章 Netty 版本都是基于 4.1.77,包括源码解析。
引入 Netty
<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.77.Final</version>
</dependency>
服务端
服务端的逻辑非常简单,监听 8081 端口,当有客户端连接进来时打印:“**,已连接”,同时打印客户端发送过来的消息。
public class HelloWorldServer {public static void main(String[] args) {// 创建服务端启动引导器ServerBootstrap bootstrap = new ServerBootstrap();// 配置线程模型bootstrap.group(new NioEventLoopGroup());// 指定服务端的 IO 模型bootstrap.channel(NioServerSocketChannel.class);// 定义处理器 Handlerbootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {@Overrideprotected void initChannel(NioSocketChannel ch) throws Exception {// 解码ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println(ctx.channel() + ",hello world");}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println(new Date() + ":" + msg);}});}});// 绑定 8081 端口bootstrap.bind(8081);}
}
大明哥依次解释上面代码
ServerBootstrap bootstrap = new ServerBootstrap();:创建服务端启动引导器,ServerBootstrap将用于引导服务端的启动工作。bootstrap.group(new NioEventLoopGroup());:给引导器配置一个线程组,也就是 Netty 的线程模型,我们知道 Netty 是基于 Reactor 的线程模型,这里使用的单线程模型,即接受连接和业务处理都是使用同一个线程。bootstrap.channel(NioServerSocketChannel.class);:指定服务端的 IO 模型,这里我们定义的是 NIO,当然你也可以使用 BIO(OioServerSocketChannel.class),但是一般都不推荐,因为 Netty 的优势就在于 NIO。bootstrap.childHandler():这里是定义业务逻辑处理器,简单来说就是客户端向服务端做的操作(连接、读、写),服务端都是在这里进行处理的。bootstrap.bind(8081):绑定 8081 端口
一个最简单的 Netty 服务单程序就写完了。
客户端
客户端就做一件事,连接服务端,然后不停地往服务端发送 “hello world”。
public class HelloWorldClient {public static void main(String[] args) throws InterruptedException {// 客户端引导器Bootstrap bootstrap = new Bootstrap();// 配置线程组bootstrap.group(new NioEventLoopGroup());// 指定 IO 类型为 NIObootstrap.channel(NioSocketChannel.class);// 配置 IO 处理器bootstrap.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new StringEncoder());}});// 建立连接Channel channel = bootstrap.connect("127.0.0.1",8081).channel();// 发送消息while (true) {channel.writeAndFlush("hello world..");TimeUnit.SECONDS.sleep(5);}}
}
客户端与服务端的逻辑差不多,只不过它使用的是 Bootstrap,Bootstrap 为客户端启动的引导器,它负责启动客户端和连接服务端。创建引导器后,就和服务端一样了,需要配置线程模型,指定 IO 类型,配置 IO 处理器,最后与服务端建立连接。
bootstrap.connect("127.0.0.1",8081):connect()方法与服务端进行连接,这里需要注意connect()方法是一个异步方法,它返回的是 ChannelFuture,调用channel()方法可以获取到对应的 channel(代码里面这种方式处理不是很优雅,我们后续再来讲)。channel.writeAndFlush():向服务端发送消息。
到这里一个简单的 Netty 应用就完成了,是不是比使用 NIO 简便很多,也非常清晰。
运行结果

从服务端打印的日志可以看出,当客户端连接服务端后,打印日志:[id: 0xee05e542, L:/127.0.0.1:8081 - R:/127.0.0.1:53354],hello world,然后每隔 5 秒钟输出 hell world,这和我们开始的预期一样。
可能小伙伴们对上面的代码还不是很理解,对上面的 ServerBootstrap、group() 、channel() 等方法都不明白什么意思,没有关系,因为这篇文章仅仅只是让你对 Netty 有一个简单的认识,后面文章大明哥会将这些概念全部都讲的明明白白的。
【注】:上面两段代码有些瑕疵,但是为了小伙伴更加容易接受,大明哥就尽可能地简单演示,后面会基于它来优化
代码:http://m6z.cn/5zJPpt
相关文章:
Netty 入门 — 亘古不变的Hello World
这篇文章我们正式开始学习 Netty,在入门之前我们还是需要了解什么是 Netty。 什么是 Netty 为什么很多人都推崇 Java boy 去研究 Netty?Netty 这么高大上,它到底是何方神圣? 用官方的话说:Netty 是一款异步的、基于事…...
idea插件开发javax.net.ssl.SSLException: No PSK available. Unable to resume.
idea插件开发,编译出错 javax.net.ssl.SSLException: No PSK available. Unable to resume.at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:129)at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)at java.base/sun.security.ssl.…...
Selenium的WebDriver操作页面的超时或者元素重叠引起的ElementClickInterceptedException
超时 处理由页面加载引起的超时是在使用 Selenium 进行自动化测试中常见的任务。页面加载可能因网络速度慢、页面复杂性或异步操作而导致超时。以下是一些处理页面加载超时的方法: 1.设置隐式等待时间: 使用 implicitly_wait 方法可以设置隐式等待时间…...
oracle数据库的缓存设置
Oracle缓存由两个参数控制SGA_TARGET和PGA_AGGREGATE_TARGET,设置了这两个参数,其他的基本内存部分都由Oracle自动配置为最优值,这也是Oracle推荐的方式。 SGA_TARGET 和PGA_AGGREGATE_TARGET是动态参数,可以在不重启数据库的情况…...
算法通关村第一关-链表青铜挑战笔记
欢迎来到 : 第一关青铜关 java如何创建链表链表怎么增删改查 我们先了解链表 单链表的概念 我们从简单的创建和增删改查开始. 链表的概念 线性表分为顺序表(数组组成)和链表(节点组成) . 链表又分: 单向 双向有哨兵节点 无哨兵节点循环 不循环 链表是一种物理存储单…...
✔ ★【备战实习(面经+项目+算法)】 10.15学习时间表
✔ ★【备战实习(面经项目算法)】 坚持完成每天必做如何找到好工作1. 科学的学习方法(专注!效率!记忆!心流!)2. 每天认真完成必做项,踏实学习技术 认真完成每天必做&…...
pytorch 训练时raise EOFError EOFError
训练到一半时获取验证数据报错 报错代码 imgs next(iter(val_dataloader)) val_dataloader DataLoader(ImageDataset("data/%s" % opt.dataset_name, transforms_transforms_, unalignedTrue, mode"test"),batch_size5,shuffleTrue,num_workers2,)def …...
node.js+NPM包管理器+Webpack打包工具+前端项目搭建
javascript运行环境(无需依赖html文件) BFF,服务于前端的后端 官网下载安装,node -v查看是否安装成功 ①、创建一个01.js文件 //引入http模块 const httprequire(http)//创建服务器 http.createServer(function(request,respo…...
PCL点云处理之基于FPFH特征的全局配准流程具体实现(二百二十一)
PCL点云处理之基于FPFH特征的全局配准流程具体实现(二百二十一) 一、算法介绍二、算法实现1.代码2.效果一、算法介绍 PCL点云库提供的多种工具,可以组合为一套完整的点云配准流程,这里选择FPFH特征,进行具体的配准流程实现,主要内容包括点云读取、点云法线计算、点云特征…...
ai_drive67_基于不确定性的多视图决策融合
论文链接:https://openreview.net/forum?idOOsR8BzCnl5 https://arxiv.org/abs/2102.02051 代码链接:https://github.com/hanmenghan/TMC Zongbo Han, Changqing Zhang, Huazhu Fu, Joey Tianyi Zhou, Trusted Multi-View Classification, Internatio…...
Docker逃逸---procfs文件挂载
一、产生原因 将宿主机/proc目录挂载进了容器,而该目录内的/proc/sys/kernel/core_pattern文件是负责进程奔溃时内存数据转储的,当第一个字符是| 管道符时,后面的部分会以命令行的方式进行解析并运行,攻击者可以将恶意文件写入该…...
[Python小项目] 从桌面壁纸到AI绘画
从桌面壁纸到AI绘画 一、前言 1.1 确认问题 由于生活和工作需要,小编要长时间的使用电脑,小编又懒,一个主题用半年的那种,所以桌面壁纸也是处于常年不更换的状态。即时改变主题也是在微软自带的壁纸中选择,而这些自…...
【Docker 内核详解】namespace 资源隔离(五):User namespaces
【Docker 内核详解 - namespace 资源隔离】系列包含: namespace 资源隔离(一):进行 namespace API 操作的 4 种方式namespace 资源隔离(二):UTS namespace & IPC namespacenamespace 资源隔…...
网络原理必知会
衔接上文:网络原理必知会_念君思宁的博客-CSDN博客 流量控制: 流量控制也是保证可靠性的机制 对于滑动窗口,批量发送数据而言,窗口越大,相当于批量发送的数据越多,整体的速度也就越快了,但是&…...
ELK 日志分析系统介绍与部署
目录 一、ELK 简介: 1.开源工具介绍: 2.其它组件: 2.1 Filebeat: 2.2 Fluentd: 2.3 缓存/消息队列(redis、kafka、RabbitMQ等): 3. filebeat 结合 logstash 带来好处: 二、为什么要…...
Android 内存治理之线程
1、 前言 当我们在应用程序中启动一个线程的时候,也是有可能发生OOM错误的。当我们看到以下log的时候,就说明系统分配线程栈失败了。 java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory这种情况可能是两种原因导致的。…...
三、K8S之ReplicaSet
ReplicaSet 一、概述 Kubernetes最核心的功能是编排,编排操作都是依靠控制器对象来完成,高级控制器控制着基础的控制器,基础控制器再去控制Pod,Pod里面再包容器。K8S项目里API对象层级大概就是这样。 而ReplicaSet这个控制器是…...
【基础篇】四、本地部署Flink
文章目录 1、本地独立部署会话模式的Flink2、本地独立部署会话模式的Flink集群3、向Flink集群提交作业4、Standalone方式部署单作业模式5、Standalone方式部署应用模式的Flink Flink的常见三种部署方式: 独立部署(Standalone部署)基于K8S部署…...
简述什么是迭代器(Iterator)?
迭代器(Iterator)是一种设计模式,Java 中的迭代器是集合框架中的一个接口,它可以让程序员遍历集合中的元素而无需暴露集合的内部结构。使用迭代器可以遍历任何类型的集合,例如 List、Set 和 Map 等。 通过调用集合类的 iterator() 方法可以获取一个迭代器,并使用 hasNext…...
DarkGate恶意软件通过消息服务传播
导语 近日,一种名为DarkGate的恶意软件通过消息服务平台如Skype和Microsoft Teams进行传播。它冒充PDF文件,利用用户的好奇心诱使其打开,进而下载并执行恶意代码。这种攻击手段使用了Visual Basic for Applications(VBA࿰…...
MD源码#MDH5影视源码主题模版下载 苹果CMS V10版
内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 MD源码#MDH5影视源码主题模版下载 苹果CMS V10版 一键部署版本,完美运营版本带采集规则模块 system/include.html–公共引用文件 system/header.html–头部文件 system/foo…...
springboot智能垃圾识别分类管理系统-计算机毕业设计源码11555
摘要 随着环保意识的提升和垃圾分类政策的推进,垃圾分类管理变得愈加重要。现有的垃圾分类管理系统存在人工识别准确性低、操作繁琐、信息流转效率低等问题,缺乏高效、智能化的解决方案。为了解决这些问题,本文提出了一种智能垃圾识别分类管理…...
【Pixel专属Gemini Edge推理引擎】:本地运行LLM不联网、零延迟、功耗降低47%——实测数据首次公开
更多请点击: https://intelliparadigm.com 第一章:Gemini Edge推理引擎的Pixel专属定位与技术边界 Gemini Edge 是 Google 为 Pixel 系列设备深度定制的端侧推理引擎,其核心设计目标并非通用模型部署,而是围绕 Pixel 的硬件协同栈…...
【独家首发】DeepSeek-V2模型GPU利用率可视化方案:仅需3个自定义Metrics,告别盲调参数
更多请点击: https://intelliparadigm.com 第一章:DeepSeek Grafana可视化 DeepSeek 是一款高性能、低延迟的开源时序数据引擎,其原生支持 Prometheus 兼容指标暴露。将 DeepSeek 与 Grafana 集成,可实现对模型推理吞吐、GPU 显存…...
从零开始使用Taotoken为你的爬虫项目添加AI解析功能
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 从零开始使用Taotoken为你的爬虫项目添加AI解析功能 在数据采集项目中,我们常常会遇到非结构化或半结构化的网页内容。…...
使用python快速接入taotoken并调用多模型完成聊天任务
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用Python快速接入Taotoken并调用多模型完成聊天任务 基础教程类,面向刚接触Taotoken的Python开发者,手把…...
轻量级负载均衡器Codex-lb:云原生场景下的部署与调优实践
1. 项目概述:一个轻量级的负载均衡解决方案 最近在折腾一些个人项目和小型服务部署时,我遇到了一个挺实际的问题:如何在不引入复杂架构和运维负担的前提下,为多个后端服务实例提供一个统一的、可靠的入口。你可能也遇到过类似场景…...
基于梯度权值追踪的无监督域自适应优化研究
SummaryArticleObjectiveMethodComments基于梯度权值追踪的域自适应分类研究解决无监督领域自适应方法中存在的过拟合问题文章采用了基于梯度权值追踪的剪枝与优化算法来解决过拟合问题。该算法首先对样本进行训练,识别出重要的连接,并用权值的绝对值来量…...
FPGA加速的医疗影像深度学习分类系统实现14.5μs超低延迟
1. 项目背景与核心挑战在医疗影像分析领域,淋巴细胞亚群(如T4、T8和B细胞)的快速准确分类对疾病诊断和治疗监测至关重要。传统方法依赖荧光标记和人工镜检,存在操作复杂、成本高昂且主观性强的问题。我们团队开发的基于明场显微镜…...
告别RAM焦虑:手把手教你用MicroBlaze BootLoader把大程序塞进QSPI Flash和DDR3
突破FPGA内存瓶颈:MicroBlaze大型程序加载实战指南 当你的MicroBlaze项目从简单的控制逻辑升级到需要文件系统、网络协议栈甚至实时操作系统时,代码体积的膨胀速度往往超出预期。那些曾经足够用的BRAM资源突然变得捉襟见肘——这就像试图在智能手机上运行…...
