Netty 入门 — 亘古不变的Hello World

这篇文章我们正式开始学习 Netty,在入门之前我们还是需要了解什么是 Netty。

什么是 Netty

为什么很多人都推崇 Java boy 去研究 Netty?Netty 这么高大上,它到底是何方神圣?

用官方的话说:Netty 是一款异步的、基于事件驱动的网络应用程序框架,用以快速开发高性能、高可靠性的网络 IO 程序

为什么要使用 Netty 呢?因为使用原生的 Java NIO 非常不爽,它存在一系列的问题,比如:

  1. 使用 Java NIO 需要了解很多概念,而且 API 非常繁琐。
  2. 使用 Java NIO 编程复杂,一不小心就会 Bug 横飞。
  3. 开发工作量和难度也很大,例如我们要处理断开重连、网络闪断、半包读写、网络拥塞、异常处理,等等异常情况,处理起来难度比较大。需要非常熟悉 Java 多线程和网络相关知识点,才能编写一个高质量的 Java NIO 程序。
  4. JDK NIO 的 Bug:例如臭名昭著的 Epoll Bug,它会导致 Selector 空轮询,最终导致 CPU 100%。

使用 Netty,都解决了上面的问题,它具备如下几个优点:

  1. 容易上手:Netty 是 Java NIO 进行了封装,API 使用简单,开发门槛相对较低。
  2. 功能强大:预置多种编解码功能,支持多种主流协议,底层 IO 模型随意切换等等。
  3. 高性能:精心设计的 Reactor 线程模型支持高并发,优秀的内存模型,减少了资源的消耗。
  4. 设计优雅:灵活且可扩展的事件模型,可以清晰地分离关注点;高度可定制化的线程模型;粘包/粘包、异常检测等机制将我们从繁重的细节中解脱,只需关注业务逻辑。
  5. 社区活跃:Netty 是目前最为活跃的开源项目之一,版本迭代周期短,bug 修复速度快。
  6. 安全:完整的 SSL/TLS 和 StartTLS 支持。
  7. 质量有保障:经过大规模的商业应用考验,质量得到了充分的验证,健壮性无比强大,放心使用吧。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/159311.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KMP 算法 + 详细笔记

给两个字符串&#xff0c;T"AAAAAAAAB"&#xff0c;P"AAAAB"; 可以暴力匹配&#xff0c;但是太费时和效率不太好。于是KMP问世&#xff0c;我们一起来探究一下吧&#xff01;&#xff01;&#xff01; &#xff08;一&#xff09;最长公共前后缀 D[i] p[…

Java架构师缓存性能优化

目录 1 缓存的负载策略2 缓存的序列化问题3 缓存命中率低4 缓存对数据库高并发访问5 缓存数据刷新的策略5.1. 实时策略5.2. 异步策略5.3. 定时策略6 何时写缓存7 批量数据来更新缓存8 缓存数据过期的策略9 缓存数据如何恢复10 缓存数据如何迁移11 缓存冷启动和缓存预热想学习架…

解决react样式组合时css module动态样式失效的问题

现象&#xff1a; <button disabled{invalid} className{ "btn btn-primary btn-lg" invalid ? styles.btnDisabled : "" } > 注册 </button> 上面采用字符串拼接的方式&#xff0c;组合class&#xff0c;但是css module的动态样式style…

【Java零基础入门到就业】第一天:java简介和cmd窗口的一些常见命令

1、java简介 Java是一种基于类的、面向对象的编程语言&#xff0c;它被设计成具有尽可能少的实现依赖。它旨在让应用程序开发人员编写一次&#xff0c;并在任何地方运行(WORA)&#xff0c;这意味着编译后的Java代码可以在所有支持Java的平台上运行&#xff0c;而无需重新编译。…

【具身智能模型1】PaLM-E: An Embodied Multimodal Language Model

论文标题&#xff1a;PaLM-E: An Embodied Multimodal Language Model 论文作者&#xff1a;Danny Driess, Fei Xia, Mehdi S. M. Sajjadi, Corey Lynch, Aakanksha Chowdhery, Brian Ichter, Ayzaan Wahid, Jonathan Tompson, Quan Vuong, Tianhe Yu, Wenlong Huang, Yevgen C…

Vue鼠标右键画矩形和Ctrl按键多选组件

效果图 说明 下面会贴出组件代码以及一个Demo&#xff0c;上面的效果图即为Demo的效果&#xff0c;建议直接将两份代码拷贝到自己的开发环境直接运行调试。 组件代码 <template><!-- 鼠标画矩形选择对象 --><div class"objects" ref"objectsR…

bash一行输入,多行回显demo脚本

效果图&#xff1a; 脚本&#xff1a; #!/bin/bash # 定义一个变量&#xff0c;用来存储输入的内容 input"" # 定义一个变量&#xff0c;用来存储输入的字符 char""# 为了让read能读到空格键 IFS_store$IFS IFS# 提示内容&#xff0c;在while循环中也有&a…

CSS 滚动驱动动画 animation-range

animation-range 语法 normallength-percentagetimeline-range-name 具名时间线范围 named timeline rangecovercontainentry 和 entry-crossingexit 和 exit-crossing 兼容性 animation-range 这个属性可同时对 scroll progress timeline 和 view progress timeline 这两种不…

数据结构与算法-(8)---队列(Queue)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

Python算法练习 10.15

leetcode 2130 链表的最大孪生和 在一个大小为 n 且 n 为 偶数 的链表中&#xff0c;对于 0 < i < (n / 2) - 1 的 i &#xff0c;第 i 个节点&#xff08;下标从 0 开始&#xff09;的孪生节点为第 (n-1-i) 个节点 。 比方说&#xff0c;n 4 那么节点 0 是节点 3 的孪…

LaunchView/启动页 的实现

1. 创建启动画板&#xff0c;LaunchScreen.storyboard 添加组件如图: 2. 项目中设置只支持竖屏&#xff0c;添加启动画板&#xff0c;如图: 3. 创建启动画面动画视图&#xff0c;LaunchView.swift import SwiftUI/// 启动视图 struct LaunchView: View {/// 字符串转换为字符串…

ES知识点全面整理

● 我们从很多年前就知道 ES6, 也就是官方发布的 ES2015 ● 从 2015 年开始, 官方觉得大家命名太乱了, 所以决定以年份命名 ● 但是大家还是习惯了叫做 ES6, 不过这不重要 ● 重要的是, ES6 关注的人非常多, 大家也会主动去关注 ● 但是从 2016 年以后, 每年官方都会出现新…

【TensorFlow2 之013】TensorFlow-Lite

一、说明 在这篇文章中&#xff0c;我们将展示如何构建计算机视觉模型并准备将其部署在移动和嵌入式设备上。有了这些知识&#xff0c;您就可以真正将脚本部署到日常使用或移动应用程序中。 教程概述&#xff1a; 介绍在 TensorFlow 中构建模型将模型转换为 TensorFlow Lite训练…

Mac 远程 Ubuntu

1. Iterm2 添加ssh 参考&#xff1a;https://www.javatang.com/archives/2021/11/29/13063392.html 2. Finder 添加远程文件管理 2.1 ubuntu 配置 安装samba sudo apt-get install samba配置 [share]path /home/USER_NAME/shared_directoryavailable yesbrowseable ye…

NewStarCTF2023week2-ez_sql

闭合之后尝试判断字段数&#xff0c;存在WAF&#xff0c;使用大小写绕过&#xff08;后面的sql语句也需要进行大小写绕过&#xff09; ?id1 Order by 5-- 测出有5列 ?id1 Order by 6-- 查一下数据库名、版本、用户等信息 ?id1Union Select database(),version(),user(),4,…

elementUI el-table+树形结构子节点选中后没有打勾?(element版本问题 已解决)

问题 1.不勾选父级CB111&#xff0c;直接去勾选子级&#xff08;ST2001…&#xff09;&#xff0c;子级选中后没有打勾显示 排查 一直以为是这个树形结构和表格不兼容产生的问题&#xff0c;到后来看官方demo都是可以勾选的&#xff0c;最后排查到了版本问题&#xff0c; 项…

数学建模——人工神经网络模型

一、人工神经网络简介 1、神经网络起源与应用 1943年心理学家McCulloch和数学家Pitts提出神经元生物数学模型&#xff08;M-P模型&#xff09;&#xff0c;后来人工神经网络(Artifical Neural Network,ANN)是在生物神经网络(Biological Neural Network,BNN)基础上发展起来的&a…

SystemC入门学习-第8章 测试平台的编写

之前的章节&#xff0c;一直把重点放在用SystemC来描述硬件电路上&#xff0c;即如何编写SystemC 的RTL。本章的注意力集中在验证和编写测试平台上。 重点包括&#xff1a; 如何生成时钟信号和激励波形如何编写有响应能力的测试平台如何记录仿真结果 8.1 编写测试平台 测试平…

IO流:java中解码和编码出现乱码说明及代码实现

IO流&#xff1a;java中解码和编码的代码实现 一、UTF-8和GBK编码方式二、idea和eclipse的默认编码方式三、解码和编码方法四、代码实现编码解码 五、额外知识扩展 一、UTF-8和GBK编码方式 如果采用的是UTF-8的编码方式&#xff0c;那么1个英文字母 占 1个字节&#xff0c;1个…

使用Swift开发Framework遇到的问题及解决方法

文章目录 一、Swift 旧版本Xcode 打出来的framework 新版本不兼容问题 一、Swift 旧版本Xcode 打出来的framework 新版本不兼容问题 Cannot load module xxx built with SDK ihphoneos16.4 when using SDK iphoneos17.0:XXX/xxx.framework/Modules/xxx.swiftmodule/arm64-appl…