[TOC]
在前面的章节中,我们学会了使用Java NIO进行长连接Server的开发。尽管NIO在通讯过程中有内存占用低等优点,但其在配置使用方面,没有框架提供的功能便捷。接下来,我们将学习使用流行的Socket通信框架,来实现长连接服务端的开发。
Server端建议使用框架:
- Netty
- Mina
- QuickServer
## Netty简介
Netty作为一个高性能的NIO通信框架,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的,已经得到了成百上千的商用项目验证。
> 面对新事物的时候,人们往往把它想得太难,拿起来看看,才知道它是咋般模样。
相比同步I/O简单直接的编程模型,异步I/O在编程模型上有较大的差异,对开发人员也有更高的要求,同时问题的定位也更为复杂。Netty是当前业界应用最广泛的Java开源异步框架。Netty 框架能显著降低异步开发的门槛,使开发人员聚焦业务逻辑,免于处理复杂的底层通信机制和线程模型,从而能够简单和快速地开发异步应用。时至今日,越来越多的国内公司开始使用Netty来构建应用,使用Netty的开发者也日益增加。
### Netty的体系结构
![](https://img.kancloud.cn/ce/71/ce71c68905b1528b3a49b6290b3b5264_558x267.png)
看下一下上面的这张图,概述了Netty的一些核心能力:
- 传输服务支持NIO、BIO;
- 协议支持HTTP、Google Protobuf、文本行、二进制、视频图像等;
- 提供了OOM-Proof Thread Pool、SSL安全支持
- 支持Spring等容器的集成
- 其核心特征:可扩展的事件模型、统一的对接API、零拷贝能力的Byte Buffer。
## 核心类
在使用 Netty 进行服务端程序开发时,主要涉及端口监听、EventLoop 线程池创建、NioServerSocketChannel 和 ChannelPipeline 初始化等。
### channel
channel的主要作用:
- close(),关闭channel
- closeFuture()用来处理channel的关闭
- sync(),同步等待channel关闭
- addListener(),异步等待channel关闭
- pipeline(),添加处理器
- write(),将数据写入channel,需要配合flush()才能将数据刷出
- writeAndFlush(),将数据写入并刷出
### pipeline&handler
> 顾名思义,pipeline是一条处理消息的流水线,每一条工序,都在pipeline中进行了定义。
ChannelHandler用来处理Channel上的业务事件,pipeline则把各种ChannelHandler连成一串。
![](https://img.kancloud.cn/0a/c8/0ac8b8c051423ee8d317dab9e5c24c18_849x292.png)
在Reactor经典模型中,Reactor查询到NIO就绪的事件后,分发到Handler,由Handler完成NIO操作和计算的操作。Handler主要的操作为Channel缓存读、数据解码、业务处理、写Channel缓存,然后由Channel(代表client)发送到最终的连接终端。ChannelHandler分为两类:
- 入站处理器(ChannelInboundHandlerAdapter):主要用来读取客户端数据
- 出战处理器(ChannelInboundHandlerAdapter):主要翻来对返回客户端的数据进加工
注意点:
- pipeline中的入站处理器没有向channel中写入数据,出站处理器是不会被触发的。
- 前面的入站处理器需要调用`super.channelRead(ctx, msg)`或者`ctc.fireChannelRead(msg)`,消息才能向后方的入站处理器传递——所谓,“击鼓传花,不能有人偷懒”;
- ChannelHandler的执行顺序:ChannelInboundHandlerAdapter是按添加顺序,ChannelInboundHandlerAdapter则与添加顺序相反。
![](https://img.kancloud.cn/5b/e0/5be0ffb27c28838ed9a4383c1e07beca_989x253.png)
#### `channel.writeAndFlush()`和`ctx.writeAndFlush()`区别
- `ctx.writeAndFlush()`,是从当前的handler,由后向前找出站处理器;
- `channel.writeAndFlush()`,是从pipeline尾部开始,由后向前找出站处理器。
### 关于深入学习
由于篇幅原因,本小册侧重于实际项目演练,关于深入学习Netty一些方法,大家供可以参考一下。
- 使用Netty开发基本网络应用程序
- 彻底理解阻塞、非阻塞的区别,并跟Netty、 NIO的编码联系起来
- 懂得多路复用在服务器开发时的优势,为什么在此基础上还要加多线程
- Netty中是如何实现异步的,异步处理的优势是什么
- Netty中是如何管理线程的,EventLoop 如何运作
- Netty中是如何管理内存的,ByteBuf特点和分配时机
- 看源码、调试的一些技巧,让自己也能去看、去跟源码
- 第一章 开篇寄语
- 1-1 技术选型要点
- 1-2 认识905.4王国的交流规范
- 1-3 联系作者
- 第二章 Socket编程的基础知识
- 2-1 Socket家族的基石
- 2-2 byte数组基础
- 2-3 缓冲区基础
- 2-4 NIO Socket通讯的工作原理
- 第三章 905.4规范解读
- 3-1 基于通道选择器的Socket长连接及消息读写框架
- 3-2 严格的信件收发员
- 3-3 负责消息处理的一家子
- 3-4 负责认证的大儿子(AuthWorker)
- 3-5 哑巴老二(PingWoker)
- 3-6 勤奋的定位汇报员老三(LocationReportWorker)
- 3-7 精明的老四(BusinessReportWorker)
- 3-8 数据检察官——CRC16-CCITT校验
- 3-11 数据的加密官
- 3-12 头尾标识转义
- 第四章 测试方法
- 4-1 测试数据样例
- 4-2 客户端链路保持功能实现
- 4-3 使用Socket短连接进行功能测试
- 4-4 NIO服务端性能分析
- 4-5 http测试方法(推荐)
- 第五章 从NIO到netty
- 5-1 编程进阶——Netty核心基础
- 5-2 Netty使用常见问题
- 5-3 使用Netty重写Server端
- 5-4 Netty之链路管理
- 5-5 netty堆外内存泄漏如何应对?
- 第六章 统计与监控
- 6-1 Grafana监控面板
- 第七章 售后服务
- 7-1 勘误与优化
- 7-2 获取源码