Netty入门之TimeServer
嗨,大家好!!!
从过完年后的一段时间,笔者一直在找工作,刚刚入职不到一个月好,一直忙公司的事情,久都没更新技术博客了,实在抱歉哈。幸运的是,笔者已经找到了一份还算满意的工作,这家公司的业务也在蓬勃发展,系统日活、用户量、qps也挺不错,很有技术挑战。
最近,上级给我安排了个任务,要把系统中与websocket的的模块独立出来,并用Netty重写,哈哈,从毕业到现在一直做的都是业务方面的开发,这方面的工作还没怎么做过,很高兴的接了这个任务。
下面就带大家初识JAVA界大名鼎鼎的Netty,从这篇文章中,大家可以学到的内容如下:
-
什么是Netty
-
JDK中的I/O的缺点
-
为什么选择Netty
-
Netty入门小Demo——TimeServer
No1、什么是Netty
Netty是业界最流行的NIO框架之一,它的性能、健壮性、应用范围等都在同类框架中首屈一指。例如RPC框架dubbo、Hadoop的RPC框架Avro就使用Netty作为底层的通信框架。
No2、JDK中的I/O的缺点
相信大家学过Socket编程的朋友们都看到过如下的代码:
处理逻辑图如下所示
这是一个最简单的Socket程序,服务端接收到request后立即创建一个线程来处理这个request。看起来没什么毛病,但是如果并发量稍稍大一点的话,server端创建线程、销毁线程会特别消耗性能。有朋友一定会说,既然系统的瓶颈在线程的创建和销毁上,用线程池不久可以了吗?将系统创建的线程数控制在一定范围内,不会因为并发量而耗尽系统线程。确实是这样,但由于底层的通信依然采用同步阻塞模型,无法从根本上解决问题。
No3、为什么选择Netty
不选择JAVA原生NIO的原因如下:
-
NIO库和API复杂
-
代码复杂
-
入门困难,需要大量JAVA知识储备
-
JDK NIO的Bug
-
。。。
选择Netty的原因如下:
-
API简单,开发门槛低
-
功能强大,预置了多种编码解码功能
-
性能高,成熟稳定
-
社区活跃度高
-
修复了NIO中已发现的所有Bug
- 。。。
No4、Netty入门小Demo——TimeServer
好,下面我们就来写一个最简单的基于Netty的网络小程序,程序功能是client链接到server,server给client返回当前的时间
Step1、工程搭建
创建一个maven工程,引入相关的依赖
Step2、编写服务端——TimeServer
-
创建两个NioEventLoopGroup实例,NioEventLiipGroup是一个线程组,它包含了一组NIO线程。创建两个的原因是一个用于服务端接收客户端的连接,另一个用于Sockerchannel的读写。
-
创建ServerBootstrap,它是Netty启动服务的启动类,将EventLoop Group传入ServerBootstrap中,最后绑定I/O事件的处理类ChildChannelHandler。
-
bind端口,调用同步阻塞方法sync等待绑定操作完成,并返回一个ChannelFuture对象,它的功能类似于java.util.concurrent.Future,主要用于异步回调。
-
等待服务器端链路关闭后main方法结束
I/O事件处理类ChildChannelHandler.java的实现
-
将msg转化为ByteBuf对象,此对象相当于byte[],不过比byte[]封装了更多操作。
-
ByteBuf的readableBytes()方法可以获取缓冲区中可读到的字节数,并将它写入byte[]中
-
创建响应,并写给客户端。
这就是server端的代码,很简单吧
Step3、编写客户端——TimeClient
-
创建EventLoopGroup实例
-
创建Bootstrap实例,与TimeServer不同的是,此处Channel需要设置为NioSockerChannel
-
调用connect发起异步连接,然后调用sync等待连接成功
-
关闭连接,释放资源
TimeClientHandler.java的实现
-
当client与server的TCP连接成功后,Netty的NIO线程调用channelActive方法,向服务器发送请求
-
将byte[]数据封装到ByteBuf中,并发送请求
-
将响应msg转化为ByteBuf对象,写入byte[]中
-
打印响应数据
好了,这就是一个基于Netty的TimeServer程序,很简单吧!笔者最近也在自学Netty,接下来的时间我会把新学到的知识与大家分享。大家可以关注笔者微信公众号或加笔者的微信,获得更多JAVA相关知识,谢谢大家