netty学习笔记

Posted by Clear Blog on June 15, 2017

拆包粘包问题解决方案

  1. 消息定长,例如每个报文200个字节固定大小,如果不够,空格补位。FixedLengthFrameDecoder
  2. 在包尾部增加特殊字符进行隔断 DelimiterBasedFrameDecoder
  3. 将消息分为消息头和消息体,在消息头中包含消息总长度,然后进行逻辑处理

编解码

说白了就是java的序列化技术, 序列化的目的就两个,

  1. 进行网络传输,
  2. 对象持久化. 虽然我们可以使用java进行对象序列化,netty去传输,但是java序列化的 硬伤太多,比如java序列化无法跨语言,序列化码流太大,序列化性能太差等。

主流的编解码框架:

  • JBoss的Marshalling包
  • google的Protobuf
  • 基于Protobuf的Kyro
  • MessagePack框架

Marshalling是对jdk默认的序列化框架进行了优化,又保持跟Serializable 接口的兼容,同时增加了一些可调的参数和附加特性。

websocket的特点:

  1. 单一的tcp连接,双方可通信
  2. 对代理,路由器,防火墙透明
  3. 无头部信息,cookie和身份验证
  4. 无安全开销
  5. 通过ping/pong帧保持链路激活
  6. 服务器可主动传递消息给客户端,不需要再让客户端去轮询

netty最佳实践

我们真正需要去考虑的问题是如何实现多台机器之间如何通信? 大体上可以分为三种:

  1. 使用长连接通道不断开的形式通信,也就是服务器端与客户端的通道一直处于开启状态。 如果服务器性能足够好,推荐使用这种方式

  2. 一次性批量提交数据,采用短连接方式,也就是我们会把数据临时存在本地缓存中或者临时表里。 当达到临界值时一次性批量提交,或者定时任务轮询提交。缺点是做不到实时传输,对实时性不高的应用推荐使用

  3. 做一种特殊的长连接,当在指定的某一段时间里面,客户端与服务端没有发生任何通信,则断开连接。 下一次客户端再向服务端发起请求的时候再建立连接。这里我们需要考虑两个问题:

    • 如何在超时后关闭通道,关闭通道后又如何再建立连接;
    • 如果服务端宕机,客户端如何再与服务端重连