最 靠谱 的软件外包伙伴

您的位置:首页 > 关于我们 > 新闻动态

互联网系统通信架构设计开发案例-基于Netty

基于Netty的通信框架可靠性设计

在客户端和服务端进行网络通信时,网络闪断、网络超时、通信对端宕机等故障时有发生,为了保证异常场景下系统的可用性,通信框架必须具有很高的可靠性。

1.链路有效性检测

从技术层面来看,要解决链路的可靠性问题,必须周期性的对链路进行有效性检测。目前最流行和通用的做法就是心跳检测。

心跳检测机制分为三个层面:

  • TCP层面的心跳检测,即TCP的Keep-Alive机制,他的作用域是整个TCP协议栈

  • 协议层的心跳检测,主要存在于长连接协议中,例如SMPP协议

  • 应用层的心跳检测,他主要由各业务产品通过约定方式定时给对方发送心跳消息实现

心跳检测的目的就是确认当前链路可用,对方或者并且能够正常接收和发送消息。作为高可靠的NIO框架,Netty也提供了心跳检测机制。

不同的协议,心跳检测机制也存在差异,归纳起来主要分为两类:

  • Ping-Pong型心跳:由通信一方定时发送Ping消息,对方接收到Ping消息之后,立即返回Pong应答消息给对方,属于请求-响应型心跳。

  • Ping-Ping型心跳:不区分心跳请求和应答,由通信双方按照约定定时向对方发送心跳Ping消息,它属于双向心跳。

心跳检测策略如下:

  • 联系N次心跳检测都没有收到对方的Pong应答消息或Ping请求消息,则认为链路已经发生逻辑失效,这杯称作心跳超时。

  • 读取和发送心跳消息的时候如果直接发生了IO异常,说明链路已经失效,这被称为心跳失败。

无论发生心跳超时还是心跳失败,都需要关闭链路,由客户端发起重连操作,保证链路能够恢复正常。

Netty的心跳检测实际上是利用了链路空闲检测机制实现的,他的空闲检测机制分为三种:

  • 读空闲,链路持续时间t没有读取到任何消息

  • 写空闲,链路持续时间t没有发送任何消息

  • 读写空闲,链路持续时间t没有接收或者发送任何消息

2.断连重连机制

当发生如下异常时,客户端需要释放资源,重新发起连接:

  • 服务端因为某种原因,主动关闭连接,客户端检测到链路被正常关闭

  • 服务端因为宕机等故障,强制关闭连接,客户端检测到链路被Reset掉

  • 心跳检测超时,客户端主动关闭连接

  • 客户端因为其他原因,强制关闭连接

  • 网络类故障,例如网络丢包、超时、单通等,导致链路中断

客户端检测到链路中断后,等到INTERVAL时机,由客户端发起重连操作,如果重连失败,间隔周期INTERVAL后再次发起重连,直到重连成功。

为了保证服务端能够有充足的时间释放句柄资源在首次断连时客户端需要等到INTERVAL时机之后再发起重连,而不是失败后就立即重连。

为了保证句柄资源能够及时释放,无论什么场景下的重连失败,客户端都必须保证自身资源被及时释放,包括但不限于SocketChannel、Socket等。重连失败后,需要打印异常堆栈信息,方便后续的问题定位。

3.消息缓存重发

当我们调用消息发送接口的时候,消息并没有真正被写入到Socket中,而是先放入NIO通信框架的消息发送队列中,由Reactor线程扫描待发送的消息队列,异步发送给通信对端。假设消息队列中积压了部分消息,此时链路中断,这回导致部分消息并没有真正发送给通信对端。

发生此故障时,我们希望NIO框架能够自动实现消息缓存和重新发送,遗憾的是作为基础的NIO通信框架,无论是Mina还是Netty,都没有提供该功能,需要通信框架自己封装实现,基于Netty的实现策略如下:

  • 调用Netty ChannelHandlerContext的write()方法时,返回ChannelFuture对象,我们在ChannelFuture中注册发送结果监听Listener。

  • 在Listener的operationComplete方法中判断操作结果,如果操作不成功,将之前发送的消息对象添加到重发队列中。

  • 链路重连成功后,根据策略,将缓存队列中的消息重新发送给通信对端。

4.资源优雅释放

Java的优雅停机通常通过注册JDK的ShutdownHook实现,当系统接收到退出指令后,首先标记系统处于退出状态,不再接收新的消息,然后将积压的消息处理完,最后调用资源回收接口将资源销毁,最后各线程退出执行。

通常优雅退出有个时间限制,例如30s,如果到达执行时间仍然没有完成退出前的操作,则由监控脚本直接kill -9 pid,强制退出。

Netty提供了完善的优雅停机接口shutdownGracefully,通过调用相关接口,可以实现线程池、消息队列、Socket句柄、多路复用器等的资源释放。

 

关于:百思特

深圳市百思特科技有限公司专注提供软件+硬件结合系统解决方案定制开发服务,其中包括:软件外包软件开发软件定制、硬件开发、硬件定制、智能硬件开发、物联网项目等开发外包服务,通过IT技术实现创造客户和社会的价值,成为最好的软件公司,通过客户需求导向、开放式创新、卓越运营管理等战略的实施,全面打造公司的核心竞争力。最佳软件外包公司、软件开发公司。


     [返回首页] [打印] [返回上页]   下一篇

电话

联系