netty实战案例
1. 摘要
之前做过一个XX集团与代理机构实时联网收费系统,采用自定义报文格式,自己编写解码器,旨在拿来就用。
2. 案例需求
2.1 通信方式
使用TCP/IP协议,SOCKET短链接。服务端始终处于监听状态,客户端发起通信请求,服务端应答后自动结束本次通信,下一回合的通信需要客户端重新发起请求。
2.2 报文格式
格式:LEN(6位)+DATA
LEN:DATA的长度。若长度项不足位数,则左侧添0。
DATA:数据报文内容,采用UTF-8编码。
长度单位:字节。
说明:数据包长度不含本身所占的6字节,如000006e4bda0,表明数据包长度为6,但报文长度为12。
2.3 业务类型和交易代码
账户信息查询:1001。获取账户详情。
2.4 数据格式规定
- 数据项中长度小于接口中定义的长度,数据左对齐,右补空格。
- 带小数的数据保留两位小数,带小数点。
- 日期格式YYYYMMDD,不带分隔符。
2.5 返回代码含义
S000:正确返回
E000:错误标志
E001:无此用户
2.6 交易报文
2.6.1 账户信息查询(1001)
- 请求接口内容
字段名 | 字段长度 | 备注 |
---|---|---|
交易代码 | 4 | 1001 |
代理机构编码 | 2 | 01 |
业务编号 | 8 | 8位数字 |
- 正确返回
字段名 | 字段长度 | 备注 |
---|---|---|
返回代码 | 4 | S000 |
姓名 | 90 | 需要补齐 |
家庭住址 | 150 | 需要补齐 |
缴费金额 | 8 | 含2位小数 |
- 错误返回
字段名 | 字段长度 | 备注 |
---|---|---|
返回代码 | 4 | 错误代码 |
3. 需求分析
在网络编程中,数据总是以字节的形式在流动,我们在实际开发中,总是要知道一段消息从哪开始从哪结束。
为了对消息进行区分,常用消息定长、使用消息结束符、消息头中定义长度字段这三种方案,目前需求属于自定义协议格式,上述三种方案均不满足,所以需要我们自己开发解码器处理消息边界。
3.1 字节序列分析
按照000005Hello数据分析字节序列,如下所示:
3.2 事件分析
解码器(1):处理处理粘包问题,netty自带的解码器都不适合。此解码器区分消息的完整性。
解码器(2):将消息序列转换成业务实体类对象。
编码器(1):业务处理完成后,将返回的数据转换为字符串。
编码器(2):字符串编码,进行发送。
3.3 系统安全性壁垒
本系统提供IP白名单设置,通过IP的过滤提供系统的安全壁垒。
4. 建设方案
4.1 解码器设计
4.1.1 VariableLengthDecoder
功能:首先获取到报文头长度,报文头长度属于报文的一部分,需要转换字节数据。其次根据获得的报文头长度截取报文数据。
4.1.2 MsgToObjectDecoder
功能:报文数据转换成业务对象。
4.2 编码器设计
4.2.1 ObjectToStringEncoder
功能:业务处理完成后,将对象转换为填充位数后的String。
4.2.2 StringToByteEncoder
功能:报文格式封装完后,字符串进行编码发送。
4.3 业务处理器设计
功能:业务处理器主要是业务相关的部分,可以写各个接口的增删改查了。
4.4 安全性设计
使用白名单技术,只有配置了客户端IP才能进行访问。
IP过滤规则定义和IP过滤处理器实现。
4.5 池化技术
主要应用在业务处理器上,使用线程池来满足系统性能。